-. $Cambridge: exim/doc/doc-src/spec.src,v 1.1 2004/10/07 15:04:35 ph10 Exp $
+. $Cambridge: exim/doc/doc-src/spec.src,v 1.8 2005/02/17 11:58:25 ph10 Exp $
.
-.set version "4.40"
-.set previousversion "4.30"
-.set versionmonth "July"
-.set versionyear "2004"
+.set version "4.50"
+.set previousversion "4.40"
+.set versionmonth "February"
+.set versionyear "2005"
.set ACL "ACL"
. The last of those is to make ACL index entries easier to type. It is put
.blank
.endm
-.macro startconf
+.macro startconf ""
+.set confsection "~~1"
.newline
.push
.if ~~sys.fancy
.else
.index \~~1\ option
.fi
+.if "~~confsection" == ""
+.set inssect ""
+.else
+.set inssect "$rm{Use:} $it{~~confsection}###"
+.fi
.tempindent 0
-\**~~1**\ $c $rm{Type:} $it{~~2} $e $rm{Default:} $it{~~3}
+\**~~1**\ $c ~~inssect$rm{Type:} $it{~~2} $e $rm{Default:} $it{~~3}
.blank
.endm
.index CRL $it{see certificate revocation list}
.index delivery||failure report $it{see bounce message}
.index dialup $it{see intermittently connected hosts}
+.index exiscan $it{see content scanning}
.index failover $it{see fallback}
.index fallover $it{see fallback}
.index filter||Sieve $it{see Sieve filter}
.index LF character $it{see linefeed}
.index maximum $it{see limit}
.index NUL $it{see binary zero}
+.index passwd file $it{see \(/etc/passwd)\}
.index process id $it{see pid}
.index RBL $it{see DNS list}
.index redirection $it{see address redirection}
.index return path||$it{see also envelope sender}
+.index scanning $it{see content scanning}
.index SSL $it{see TLS}
.index string||expansion $it{see expansion}
.index top bit $it{see 8-bit characters}
BSD/OS (aka BSDI), Darwin (Mac OS X), DGUX, FreeBSD, GNU/Hurd, GNU/Linux,
HI-OSF (Hitachi), HP-UX, IRIX, MIPS RISCOS, NetBSD, OpenBSD, 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.
+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.
There are also configuration files for compiling Exim in the Cygwin environment
that can be installed on systems running Windows. However, this document does
\(ACKNOWLEDGMENTS)\, in which I have started recording the names of
contributors.
+
.section Exim documentation
.index documentation
.em
[(A HREF="http://www.uit.co.uk/exim-book/")]
$it{The Exim SMTP Mail Server},
[(/A)]
-published by UIT Cambridge.
+published by UIT Cambridge.
.else
$it{The Exim SMTP Mail Server}, published by UIT Cambridge
(\?http://www.uit.co.uk/exim-book/?\).
.index change log
As the program 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. However,
-specifications of new features that are not yet in this manual are placed in
-the file \(doc/NewStuff)\ in the Exim distribution. All changes to the program
-(whether new features, bug fixes, or other kinds of change) are noted briefly
-in the file called \(doc/ChangeLog)\.
+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
+\(doc/NewStuff)\ in the Exim distribution.
+
+.em
+Some features may be classified as `experimental'. 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 \(doc/experimental.txt)\.
+.nem
+
+All changes to the program (whether new features, bug fixes, or other kinds of
+change) are noted briefly in the file called \(doc/ChangeLog)\.
.index \(doc/spec.txt)\
This specification itself is available as an ASCII file in \(doc/spec.txt)\ so
\(OptionLists.txt)\ $t $rm{list of all options in alphabetical order}
\(dbm.discuss.txt)\ $t $rm{discussion about DBM libraries}
\(exim.8)\ $t $rm{a man page of Exim's command line options}
+.newline
+.em
+\(experimental.txt)\ $t $rm{documentation of experimental features}
+.nem
+.newline
\(filter.txt)\ $t $rm{specification of the filter language}
\(pcrepattern.txt)\ $t $rm{specification of PCRE regular expressions}
\(pcretest.txt)\ $t $rm{specification of the PCRE testing program}
~~SECTavail below tells you how to get hold of these.
-.section FTP and web sites, and mailing list
+.section FTP and web sites
.index web site
.index FTP site
-The primary distribution site for Exim is an FTP site, whose contents are
-described in \*Where to find the Exim distribution*\ below. In addition,
-there is a web site at \?http://www.exim.org?\ by courtesy of Energis Squared,
-formerly Planet Online Ltd, who are situated in the UK. The site is mirrored in
-a number of other countries; links to the mirrors are listed on the home page.
-The web site contains the Exim distribution, and you can also find the
-documentation and the
+.em
+The primary distribution site for Exim is currently the University of
+Cambridge's FTP site, whose contents are described in \*Where to find the Exim
+distribution*\ below. In addition, there is a
+.if ~~html
+[(A HREF="http://www.exim.org/")]
+.fi
+web site
+.if ~~html
+[(/A)]
+.fi
+and an
+.if ~~html
+[(A HREF="ftp://ftp.exim.org/")]
+.fi
+FTP site
+.if ~~html
+[(/A)]
+.fi
+at \exim.org\. These are now also hosted at the University of Cambridge.
+The \exim.org\ site was previously hosted for a number of years by Energis
+Squared, formerly Planet Online Ltd, whose support I gratefully acknowledge.
+
+As well as Exim distribution tar files, the Exim web site contains a number of
+differently formatted versions of the documentation, including the
.index FAQ
.if ~~html
[(A HREF="FAQ.html")]
.if ~~html
[(/A)]
.fi
-online there, as well as other relevant material.
+in both text and HTML formats. The HTML version comes with a keyword-in-context
+index. A recent addition to the online information is the
+.index wiki
+.if ~~html
+[(A HREF="http://www.exim.org/eximwiki/")]
+Exim wiki.
+[(/A)]
+.else
+Exim wiki (\?http://www.exim.org/eximwiki/?\).
+.fi
+We hope that this will make it easier for Exim users to contribute examples,
+tips, and know-how for the benefit of others.
+.nem
+.section Mailing lists
.index mailing lists||for Exim users
-Energis Squared also provide resources for the following mailing lists:
+.em
+The following are the three main Exim mailing lists:
.display rm
.tabs 28
$it{exim-users@@exim.org} $t general discussion list
+$it{exim-dev@@exim.org} $t discussion of bugs, enhancements, etc.
$it{exim-announce@@exim.org} $t moderated, low volume announcements list
.endd
+.nem
You can subscribe to these lists, change your existing subscriptions, and view
or search the archives via the
.if ~~html
to post a message to the $it{exim-users} mailing list and have it discussed.
+.em
.section Where to find the Exim distribution
.rset SECTavail "~~chapter.~~section"
.index FTP site
.fi
\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim?\
.endd
-Within that directory there are subdirectories called \(exim3)\ (for previous
-Exim 3 distributions), \(exim4)\ (for the latest Exim 4 distributions), and
-\(Testing)\ for occasional testing versions. Those mirror sites that I know
-about are listed in the file
+This is mirrored by
.display rm
.if ! ~~sys.fancy
.indent 0
.fi
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/Mirrors?\
+\?ftp://ftp.exim.org/pub/exim?\
.endd
-In the \(exim4)\ subdirectory, the current release can always be found in
-files called
+The file references that follow are relative to the \(exim)\ directories at
+these sites.
+
+There are now quite a number of independent mirror sites around the world.
+Those that I know about are listed in the file called \(Mirrors)\.
+
+Within the \(exim)\ directory there are subdirectories called \(exim3)\ (for
+previous Exim 3 distributions), \(exim4)\ (for the latest Exim 4
+distributions), and \(Testing)\ for testing versions. In the \(exim4)\
+subdirectory, the current release can always be found in files called
.display rm
\(exim-$it{n.nn}.tar.gz)\
\(exim-$it{n.nn}.tar.bz2)\
.index distribution||signing details
.index distribution||public key
.index public key for signed distribution
-The distributions are signed with Philip Hazel's GPG key.
-The corresponding public key is available from a number of keyservers, and
-there is also a copy in the file:
-.display rm
-.if ! ~~sys.fancy
-.indent 0
-.fi
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/Public-Key?\
-.endd
-The signatures for the tar bundles are in:
+The distributions are currently signed with Philip Hazel's GPG key. The
+corresponding public key is available from a number of keyservers, and there is
+also a copy in the file \(Public-Key)\. The signatures for the tar bundles are
+in:
.display rm
\(exim-$it{n.nn}.tar.gz.sig)\
\(exim-$it{n.nn}.tar.bz2.sig)\
.endd
-
-When there is only a small amount of change from one release to the next, a
-patch file may be provided, with a final component name of the form
-.display rm
-\(exim-patch-$it{n.nn}-$it{m.mm}.gz)\
-.endd
-For each released version, the log of changes is made separately available in
-the directory
-.display rm
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/ChangeLogs?\
-.endd
-so that it is possible to find out what has changed without having to download
-the entire distribution.
+For each released version, the log of changes is made separately available in a
+separate file in the directory \(ChangeLogs)\ so that it is possible to
+find out what has changed without having to download the entire distribution.
.index documentation||available formats
The main distribution contains ASCII versions of this specification and other
distribution, and are also available in \(.bz2)\ as well as \(.gz)\ forms.
.index FAQ
-The FAQ is available for downloading in two different formats from
+The FAQ is available for downloading in two different formats in these files:
.display rm
-.if ! ~~sys.fancy
-.indent 0
-.fi
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/FAQ.txt.gz?\
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/FAQ.html.tar.gz?\
+\(exim4/FAQ.txt.gz)\
+\(exim4/FAQ.html.tar.gz)\
.endd
The first of these is a single ASCII file that can be searched with a text
editor. The second is a directory of HTML files, normally accessed by starting
.section Wish list
.index wish list
A wish list is maintained, containing ideas for new features that have been
-submitted. From time to time the file is exported to the ftp site:
-.display rm
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/WishList?\
-.endd
-Items are removed from the list if they get implemented.
+submitted. From time to time the file is exported to the ftp site into the file
+\(exim4/WishList)\. Items are removed from the list if they get implemented.
.section Contributed material
.index contributed material
-At the ftp site, there is a directory called
-.display rm
-.if ! ~~sys.fancy
-.indent 0
-.fi
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/Contrib/?\
-.endd
-which contains miscellaneous files contributed to the Exim community by Exim
-users. There is also a collection of contributed configuration examples in
-.display rm
-.if ! ~~sys.fancy
-.indent 0
-.fi
-\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/config.samples.tar.gz?\
-.endd
-These samples are referenced from the FAQ.
-
+At the ftp site, there is a directory called \(Contrib)\ that contains
+miscellaneous files contributed to the Exim community by Exim users. There is
+also a collection of contributed configuration examples in
+\(exim4/config.samples.tar.gz)\. These samples are referenced from the FAQ.
+.nem
.section Limitations
.index limitations of Exim
(that is, off Exim's queue) and subsequently passed on to the dial-in hosts by
other means.
.nextp
-Although Exim does have some 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.
+.em
+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.
+.nem
.endp
.index bounce message||definition of
When a message cannot be delivered, it is normally returned to the sender in a
-delivery failure message. The term \*bounce*\ is commonly used for this action,
-and the error reports are often called \*bounce messages*\. This is a
-convenient shorthand for `delivery failure error report'. Such messages have an
-empty sender address in the message's \*envelope*\ (see below) to ensure that
-they cannot themselves give rise to further bounce messages.
+delivery failure message or a `non-delivery report' (NDR). The term \*bounce*\
+is commonly used for this action, and the error reports are often called
+\*bounce messages*\. This is a convenient shorthand for `delivery failure error
+report'. Such messages have an empty sender address in the message's
+\*envelope*\ (see below) to ensure that they cannot themselves give rise to
+further bounce messages.
The term \*default*\ 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
A number of pieces of external code are included in the Exim distribution.
.numberpars $.
Regular expressions are supported in the main Exim program and in the Exim
-monitor using the freely-distributable PCRE library, copyright (c) 2003
-University of Cambridge. The source is distributed in the directory
-\(src/pcre)\. However, this is a cut-down version of PCRE. If you want to use
-the PCRE library in other programs, you should obtain and install the full
-version from \?ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre?\.
+monitor using the freely-distributable PCRE library, copyright (c) University
+of Cambridge. The source is distributed in the directory \(src/pcre)\. However,
+this is a cut-down version of PCRE. If you want to use the PCRE library in
+other programs, you should obtain and install the full version from
+\?ftp://ftp.csx.cam.ac.uk/pub/software/programming/pcre?\.
.space 1ld
.nextp
.index cdb||acknowledgement
Support for the cdb (Constant DataBase) lookup method is provided by code
-contributed by Nigel Metheringham of Planet Online Ltd. which contains the
-following statements:
+contributed by Nigel Metheringham of (at the time he contributed it) Planet
+Online Ltd. which contains the following statements:
.rule
.push
.if ~~sgcal
.index Samba project
.index Microsoft Secure Password Authentication
Client support for Microsoft's \*Secure Password Authentication*\ is provided
-by code contributed by Marc Prud'hommeaux. Server support was contributed by
+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.
at Carnegie Mellon University (\?http://www.cmu.edu/computing/?\).}
.newline
.pop
-.endp
+.endp
.if ~~sgcal
.cancelflag $npbracket
.flag $npbracket "(" ")"
.newline
.pop
.rule
+.space 1ld
+.nextp
+.em
+Many people have contributed code fragments, some large, some small, that were
+not covered by any specific licence requirements. It is assumed that the
+contributors are happy to see their code incoporated into Exim under the GPL.
+.nem
.endp
.numberpars $.
.index ~~ACL||introduction
Exim 4 (unlike previous versions of Exim) implements policy controls on
-incoming SMTP mail by means of \*Access Control Lists*\ (ACLs). Each list is a
+incoming mail by means of \*Access Control Lists*\ (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. 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 ~~CHAPACL). Denial of access results in an SMTP error code.
-.nextp
-An ACL is also available for locally generated, non-SMTP messages. In this
+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 ~~CHAPACL). Denial of access results in an SMTP
+error code.
+.nextp
+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.
.nextp
+.em
+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.
+.nem
+.nextp
When a message has been received, either from a remote host or from the local
host, but before the final acknowledgement has been sent, a locally supplied C
function called \*local@_scan()*\ can be run to inspect the message and decide
whether to accept it or not (see chapter ~~CHAPlocalscan). If the message is
accepted, the list of recipients can be modified by the function.
.nextp
+.em
+Using the \*local@_scan()*\ mechanism is another way of calling external
+scanner software. The \SA-Exim\ add-on package works this way. It does not
+require Exim to be compiled with the content-scanning extension.
+.nem
+.nextp
After a message has been accepted, a further checking mechanism is available in
the form of the $it{system filter} (see chapter ~~CHAPsystemfilter). This runs
at the start of every delivery process.
.section User filters
.index filter||introduction
.index Sieve filter
-In a conventional Exim configuration, users are able to run private filters by
-setting up appropriate \(.forward)\ files in their home directories. See
-chapter ~~CHAPredirect (about the \%redirect%\ router) for the configuration
-needed to support this, and the separate document entitled
+In a conventional Exim configuration, users are able to run private filters by
+setting up appropriate \(.forward)\ files in their home directories. See
+chapter ~~CHAPredirect (about the \%redirect%\ router) for the configuration
+needed to support this, and the separate document entitled
.if ~~html
[(A HREF="filter_toc.html")]
.fi
.fi
for user details. Two different kinds of filtering are available:
.numberpars $.
-Sieve filters are written in the standard filtering language that is defined by
+Sieve filters are written in the standard filtering language that is defined by
RFC 3028.
.nextp
-Exim filters are written in a syntax that is unique to Exim, but which is more
+Exim filters are written in a syntax that is unique to Exim, but which is more
powerful than Sieve, which it pre-dates.
.endp
User filters are run as part of the routing process, described below.
characters long. It is divided into three parts, separated by hyphens, for
example \"16VDhn-0001bo-D3"\. 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
+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 file names, and the names of files in those systems are
not case-sensitive.
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
+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:
.numberpars $.
The first six characters of the message id are the time at which the message
users, and the \untrusted@_set@_sender\ option for a way of allowing untrusted
users to change sender addresses.
-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
+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 \*local@_scan()*\ function (see chapter
~~CHAPlocalscan) is run for all incoming messages.
are also written to a separate $it{message log} 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
+The use of individual message logs can be disabled by setting
\no@_message@_logs\; this might give an improvement in performance on very
busy systems.
ones are actually used for delivering messages.
.index drivers||instance definition
-Each driver that is specified in the run time configuration is an \*instance*\
-of that particular driver type. Multiple instances are allowed; for example,
-you can set up several different \%smtp%\ transports, each with different
+Each driver that is specified in the run time configuration is an \*instance*\
+of that particular driver type. Multiple instances are allowed; for example,
+you can set up several different \%smtp%\ 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
+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.
.if ~~sys.fancy
.figure "Routing an address" rm
.indent 0
-.call aspic
+.call aspic -sgcal -nv
centre ~~sys.linelength;
magnify 0.8;
boundingbox 30;
The second 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
+to fail, or it may simply decline to handle the address, in which case the
address is passed to the next router.
The final router in many configurations is one that checks to see if the
.section Processing an address for verification
.index router||for verification
.index verifying||address, overview
-As well as being used to decide how to deliver to an address, Exim's routers
-are also used for \*address verification*\. 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 \-bv-\ and
+As well as being used to decide how to deliver to an address, Exim's routers
+are also used for \*address verification*\. 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 \-bv-\ and
\-bvs-\ command line options.
-When an address is being verified, the routers are run in `verify mode'. This
-does not affect the way the routers work, but it is a state that can be
+When an address is being verified, the routers are run in `verify mode'. 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 \no@_verify\ option
+checking, making it useless for verifying. Normally, the \no@_verify\ option
would be set for such a router, causing it to be skipped in verify mode.
.numberpars $.
\*accept*\: The router accepts the address, and either queues it for a
transport, or generates one or more `child' addresses. Processing the original
-address ceases,
+address ceases,
.index \unseen\ option
unless the \unseen\ option is set on the router. This option
can be used to set up multiple deliveries with different routing (for example,
.endp
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 `unrouteable address', but you
-can set your own message by making use of the \cannot@_route@_message\ option.
-This can be set for any router; the value from the last router that `saw'
+The default error message in this situation is `unrouteable address', but you
+can set your own message by making use of the \cannot@_route@_message\ option.
+This can be set for any router; the value from the last router that `saw'
the address is used.
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 \%redirect%\ router has a `fail'
+when the relevant conditions are met. The \%redirect%\ router has a `fail'
facility for this purpose.
removed from the local part before further processing, including the evaluation
of any other conditions.
.nextp
-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
-\verify\ option is set false, the router is skipped when Exim is verifying an
+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
+\verify\ option is set false, the router is skipped when Exim is verifying an
address.
-Setting the \verify\ option actually sets two options, \verify@_sender\ and
-\verify@_recipient\, which independently control the use of the router for
-sender and recipient verification. You can set these options directly if
+Setting the \verify\ option actually sets two options, \verify@_sender\ and
+\verify@_recipient\, 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.
.nextp
-If the \address@_test\ option is set false, the router is skipped when Exim is
-run with the \-bt-\ 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
+If the \address@_test\ option is set false, the router is skipped when Exim is
+run with the \-bt-\ 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 \-bt-\ to test subsequent delivery routing without having to
simulate the effect of the scanner.
.nextp
.nextp
If the \check@_local@_user\ 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
+If this check succeeds, the uid and gid of the local user are placed in
\$local@_user@_uid$\ and \$local@_user@_gid$\; these values can be used in the
remaining preconditions.
.nextp
If the \router@_home@_directory\ option is set, it is expanded at this point,
-because it overrides the value of \$home$\. If this expansion were left till
-later, the value of \$home$\ as set by \check@_local@_user\ would be used in
-subsequent tests. Having two different values of \$home$\ in the same router
+because it overrides the value of \$home$\. If this expansion were left till
+later, the value of \$home$\ as set by \check@_local@_user\ would be used in
+subsequent tests. Having two different values of \$home$\ in the same router
could lead to confusion.
.nextp
If the \senders\ option is set, the envelope sender address must be in the set
to Exim (`the Exim user'), 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 \remote@_max@_parallel\ option.
-.em
-The order in which deliveries are done is not defined, except that all local
+The order in which deliveries are done is not defined, except that all local
deliveries happen before any remote deliveries.
-.nem
.nextp
.index queue runner
When it encounters a local delivery during a queue run, Exim checks its retry
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,
+deferred,
.index hints database
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
.if !~~sys.fancy && ~~sgcal
.tabs 16
.else
-.tabs 22
+.tabs 22
.fi
\(ACKNOWLEDGMENTS)\ $t contains some acknowledgments
.newline
DBMLIB = -ldb
DBMLIB = -ltdb
.endd
-Settings like that will work if the DBM library is installed in the standard
+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
+file is, and to specify the path to the library more fully in \\DBMLIB\\, as in
this example:
.display asis
INCLUDE=-I/usr/local/include/db-4.1
detected early in Exim's execution (such as a malformed configuration file) can
be logged.
+.index content scanning||specifying at build time
+.em
+Exim's interfaces for calling virus and spam scanning sofware directly from
+access control lists are not compiled by default. If you want to include these
+facilities, you need to set
+.display asis
+WITH_CONTENT_SCAN=yes
+.endd
+in your \(Local/Makefile)\. For details of the facilities themselves, see
+chapter ~~CHAPexiscan.
+.nem
+
.index \(Local/eximon.conf)\
.index \(exim@_monitor/EDITME)\
If you are going to build the Exim monitor, a similar configuration process is
.section Support for iconv()
.index \*iconv()*\ support
-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 \@$h@_\
-mechanism, it decodes them, and translates them into a specified character set
+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 \@$h@_\
+mechanism, it decodes them, and translates them into a specified character set
(default ISO-8859-1). The translation is possible only if the operating system
supports the \*iconv()*\ function.
very many conversions. The GNU \libiconv\ library (available from
\?http:/@/www.gnu.org/software/libiconv/?\) can be installed on such systems to
remedy this deficiency, as well as on systems that do not supply \*iconv()*\ at
-all. After installing \libiconv\, you should add
+all. After installing \libiconv\, you should add
.display asis
-HAVE_ICONV=yes
-.endd
+HAVE_ICONV=yes
+.endd
to your \(Local/Makefile)\ and rebuild Exim.
.index OpenSSL||building Exim with
.index GnuTLS||building Exim with
Exim can be built to support encrypted SMTP connections, using the \\STARTTLS\\
-command as per RFC 2487. It can also support legacy clients that expect to
-start a TLS session immediately on connection to a non-standard port (see the
-\-tls-on-connect-\ command line option).
+command as per RFC 2487. It can also support legacy clients that expect to
+start a TLS session immediately on connection to a non-standard port (see the
+\tls@_on@_connect@_ports\ runtime option and the \-tls-on-connect-\ command
+line option).
-If you want to build Exim with TLS support, you must first install either the
+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.
library and include files. For example:
.display asis
SUPPORT_TLS=yes
-USE_GNUTLS=yes
+USE_GNUTLS=yes
TLS_LIBS=-L/usr/gnu/lib -lgnutls -ltasn1 -lgcrypt
TLS_INCLUDE=-I/usr/gnu/include
.endd
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
+specified in \\INCLUDE\\. Details of how to configure Exim to make use of TLS
are given in chapter ~~CHAPTLS.
where the IPv6 support is not fully integrated into the normal include and
library files.
-IPv6 is still changing rapidly. Two different types of DNS record for handling
-IPv6 addresses have been defined. AAAA records are already in use, and are
-currently seen as the `mainstream', but another record type called A6 is being
-argued about. Its status is currently `experimental'. Exim has support for A6
-records, but this is included only if you set \\SUPPORT@_A6=YES\\ in
-\(Local/Makefile)\.
-
+.em
+Two different types of DNS record for handling IPv6 addresses have been
+defined. AAAA records (analagous 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 `experimental'. It is not known
+if anyone is actually using A6 records. Exim has support for A6 records, but
+this is included only if you set \\SUPPORT@_A6=YES\\ in \(Local/Makefile)\. The
+support has not been tested for some time.
+.nem
.section The building process
.index build directory
.index symbolic link||to source files
Symbolic links to relevant source files are installed in the build directory.
-.em
-\**Warning**\: The \-j-\ (parallel) flag must not be used with \*make*\; the
+\**Warning**\: The \-j-\ (parallel) flag must not be used with \*make*\; the
building process fails if it is set.
-.nem
If this is the first time \*make*\ has been run, it calls a script that builds
a make file inside the build directory, using the configuration files from the
.index building Exim||overriding default settings
If you need to change any of the values that are set in \(OS/Makefile-Default)\
-or in \(OS/Makefile-<<ostype>>)\, or to add any new definitions, you do not
+or in \(OS/Makefile-<<ostype>>)\, 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 \(Local)\ file. For example,
.index Tru64-Unix build-time settings
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 \*cc*\ rather than \*gcc*\. Also, the compiler must be
+compiler is called \*cc*\ rather than \*gcc*\. Also, the compiler must be
called with the option \-std1-\, to make it recognize some of the features of
-Standard C that Exim uses. (Most other compilers recognize Standard C by
+Standard C that Exim uses. (Most other compilers recognize Standard C by
default.) To do this, you should create a file called \(Local/Makefile-OSF1)\
containing the lines
.display
CC=cc
CFLAGS=-std1
.endd
-If you are compiling for just one operating system, it may be easier to put
+If you are compiling for just one operating system, it may be easier to put
these lines directly into \(Local/Makefile)\.
Keeping all your local configuration settings separate from the distributed
The command \*make install*\ runs the \*exim@_install*\ script with no
arguments. The script copies binaries and utility scripts into the directory
whose name is specified by the \\BIN@_DIRECTORY\\ setting in
-\(Local/Makefile)\.
+\(Local/Makefile)\.
Exim's run time configuration file is named by the \\CONFIGURE@_FILE\\ setting
.index \\CONFIGURE@_FILE\\
.display asis
make DESTDIR=/some/directory/ install
.endd
-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
+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 \*is*\ modified.)
-For backwards compatibility, \\ROOT\\ is used if \\DESTDIR\\ is not set,
+For backwards compatibility, \\ROOT\\ is used if \\DESTDIR\\ is not set,
but this usage is deprecated.
.index installing Exim||what is not installed
make INSTALL_ARG=-no_symlink install
.endd
-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,
+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:
.display asis
make INSTALL_ARG='-no_symlink exim' install
.endd
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
+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,
.endd
to obtain the daemon's pid directly from the file that Exim saves it in.
-Note, however, that stopping the daemon does not `stop Exim'. Messages can
-still be received from local processes, and if automatic delivery is configured
+Note, however, that stopping the daemon does not `stop Exim'. Messages can
+still be received from local processes, and if automatic delivery is configured
(the normal case), deliveries will still occur.
.section Setting options by program name
.index \*mailq*\
If Exim is called under the name \*mailq*\, it behaves as if the option \-bp-\
-were present before any other options.
-The \-bp-\ option requests a listing of the contents of the mail queue on the
+were present before any other options.
+The \-bp-\ 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
false.
.endp
-\**Warning**\: 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
+\**Warning**\: 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
~~CHAPconf.
.option -help
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
+The same output is generated if the Exim binary is called with no options and
no arguments.
.option B <<type>>
.index \\SIGHUP\\
The \\SIGHUP\\ signal can be used to cause the daemon to re-exec itself. This
should be done whenever Exim's configuration file, or any file that is
-incorporated into it by means of the \.include\ facility, is changed, and also
+incorporated into it by means of the \.include\ 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.
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. Long expressions can be split over several lines by using backslash
-continuations.
-As in Exim's run time configuration, whitespace at the start of continuation
-lines is ignored.
+of data.
+.em
+If Exim was built with \\USE@_READLINE\\=yes in \(Local/Makefile)\, it tries
+to load the \libreadline\ library dynamically whenever the \-be-\ option is
+used without command line arguments. If successful, it uses the \*readline()*\
+function, which provides extensive line-editing facilities, for reading the
+test data. A line history is supported.
+.nem
-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, \$qualify@_domain$\) are available, but no message-specific values
-(such as \$domain$\) are set, because no message is being processed.
+Long expansion expressions can be split over several lines by using backslash
+continuations. As in Exim's run time configuration, whitespace 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, \$qualify@_domain$\) are available, but no
+message-specific values (such as \$domain$\) are set, because no message is
+being processed.
.option bF #<<filename>>
.index system filter||testing
.index forward file||testing
.index testing||forward file
.index Sieve filter||testing
-This option runs Exim in 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. If a
-system filter file is being tested, \-bF-\ should be used instead of \-bf-\. If
-the test file does not begin with
-one of the special lines
+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.
+.em
+If you want to test a system filter file, use \-bF-\ instead of \-bf-\. You can
+use both \-bF-\ and \-bf-\ on the same command, in order to
+test a system filter and a user filter in the same run. For example:
+.display asis
+exim -bF /system/filter -bf /user/filter </test/message
+.endd
+This is helpful when the system filter adds header lines or sets filter
+variables that are used by the user filter.
+.nem
+
+If the test filter file does not begin with one of the special lines
.display asis
# Exim filter
# Sieve filter
.endd
it is taken to be a normal \(.forward)\ file, and is tested for validity under
-that interpretation. See sections ~~SECTitenonfilred to ~~SECTspecitredli for a
+that interpretation. See sections ~~SECTitenonfilred to ~~SECTspecitredli for a
description of the possible contents of non-filter redirection lists.
The result of an Exim command that uses \-bf-\, provided no errors are
When testing a filter file, the envelope sender can be set by the \-f-\ option,
or by a `From ' 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. These are:
-.display rm
-.if ~~sys.fancy
-.tabset 12em 16em
-.else
-.tabset 15em 20em
-.fi
-. The odd alignment here gets it lined up in the man page.
-\-bfd-\ $t <<domain>> $t $rm{default is the qualify domain}
-\-bfl-\ $t <<local@_part>> $t $rm{default is the logged in user}
-\-bfp-\ $t <<local@_part@_prefix>> $t $rm{default is null}
-\-bfs-\ $t <<local@_part@_suffix>> $t $rm{default is null}
-.endd
-The local part should always be set to the incoming address with any prefix or
+be set by means of additional command line options (see the next four options).
+
+.em
+.option bfd #<<domain>>
+This sets the domain of the recipient address when a filter file is being
+tested by means of the \-bf-\ option. The default is the value of
+\$qualify@_domain$\.
+
+.option bfl #<<local part>>
+This sets the local part of the recipient address when a filter file is being
+tested by means of the \-bf-\ 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.
+.option bfp #<<prefix>>
+This sets the prefix of the local part of the recipient address when a filter
+file is being tested by means of the \-bf-\ option. The default is an empty
+prefix.
+
+.option bfp #<<suffix>>
+This sets the suffix of the local part of the recipient address when a filter
+file is being tested by means of the \-bf-\ option. The default is an empty
+suffix.
+.em
+
+
.option bh #<<IP address>>
.index testing||incoming SMTP
.index SMTP||testing incoming
exim -bh 10.9.8.7.1234
exim -bh fe80::a00:20ff:fe86:a061.5678
.endd
+.em
+When an IPv6 address is given, it is converted into canonical form. In the case
+of the second example above, the value of \$sender@_host@_address$\ after
+conversion to the canonical form is \"fe80:0000:0000:0a00:20ff:fe86:a061.5678"\.
+.nem
+
Comments as to what is going on are written to the standard error file. These
include lines beginning with `LOG' 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
+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 \-bh-\.
.index RFC 1413
\-bh-\ because there is no incoming SMTP connection.
\**Warning 2**\: Address verification callouts (see section ~~SECTcallver) are
-also skipped when testing using \-bh-\. If you want these callouts to occur,
+also skipped when testing using \-bh-\. If you want these callouts to occur,
use \-bhc-\ instead.
Messages supplied during the testing session are discarded, and nothing is
acceptable or not. See section ~~SECTcheckaccess.
.option bhc #<<IP address>>
-This option operates in the same way as \-bh-\, except that address
-verification callouts are performed if required. This includes consulting and
-updating the callout cache database.
+This option operates in the same way as \-bh-\, except that address
+verification callouts are performed if required. This includes consulting and
+updating the callout cache database.
.option bi
.index alias file||building
options, as appropriate. The \-bnq-\ option (see below) provides a way of
suppressing this for special cases.
-Policy checks on the contents of local messages can be enforced by means of the
+Policy checks on the contents of local messages can be enforced by means of the
non-SMTP ACL. See chapter ~~CHAPACL for details.
.index return code||for \-bm-\
The return code is zero if the message is successfully accepted. Otherwise, the
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 \uucp@_from@_pattern\
-option, which can be changed if necessary.
+option, which can be changed if necessary.
.index \-f-\ option||overriding `From' line
The specified sender is treated as if it were given as the argument to the
\-f-\ option, but if a \-f-\ option is also present, its argument is used in
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
-\qualify@_domain\, and recipient addresses using \qualify@_recipient\ (which
+envelopes, and addresses in header lines. Sender addresses are qualified using
+\qualify@_domain\, and recipient addresses using \qualify@_recipient\ (which
defaults to the value of \qualify@_domain\).
Sometimes, qualification is not wanted. For example, if \-bS-\ (batch SMTP) is
.endd
If \configure@_file\ is given as an argument, the name of the run time
configuration file is output.
-If a list of configuration files was supplied, the value that is output here
+If a list of configuration files was supplied, the value that is output here
is the name of the file that was actually used.
.index daemon||process id (pid)
.index local SMTP input
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 ~~CHAPACL) are applied.
+policy controls, as defined in ACLs (see chapter ~~CHAPACL) are applied.
Some user agents use this interface as a way of passing locally-generated
messages to the MTA.
.index inetd
The \-bs-\ option is also used to run Exim from \*inetd*\, 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
-\*inetd*\, 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
+whether the standard input is a TCP/IP socket. When Exim is called from
+\*inetd*\, 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.
.option bt
.index address||testing
This option runs Exim in address testing mode, in which each argument is taken
as an 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.
+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.
If no arguments are given, Exim runs in an interactive manner, prompting with a
-right angle bracket for addresses to be tested. Each address is handled as if
-it were the recipient address of a message (compare the \-bv-\ option). It is
-passed to the routers and the result is written to the standard output.
-However, any router that has \no@_address@_test\ set is bypassed. This can
-make \-bt-\ easier to use for genuine routing tests if your first router passes
-everything to a scanner program.
+right angle bracket for addresses to be tested.
+.em
+Unlike the \-be-\ test option, you cannot arrange for Exim to use the
+\*readline()*\ function, because it is running as \*root*\ and there are
+security issues.
+.nem
+
+Each address is handled as if it were the recipient address of a message
+(compare the \-bv-\ option). It is passed to the routers and the result is
+written to the standard output. However, any router that has
+\no@_address@_test\ set is bypassed. This can make \-bt-\ easier to use for
+genuine routing tests if your first router passes everything to a scanner
+program.
.index return code||for \-bt-\
The return code is 2 if any address failed outright; it is 1 if no address
\**Warning**\: \-bt-\ can only do relatively simple testing. If any of the
routers in the configuration makes any tests on the sender address of a
-message,
+message,
.index \-f-\ option||for address testing
you can use the \-f-\ option to set an appropriate sender when running
\-bt-\ tests. Without it, the sender is assumed to be the calling user at the
specific lookup types), the drivers that are included in the binary, and the
name of the run time configuration file that is in use.
+.em
+As part of its operation, \-bV-\ 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 \-bV-\
+alone to discover (for example) all the typos in the configuration; some
+realistic testing is needed. The \-bh-\ and \-N-\ options provide more dynamic
+testing facilities.
+.nem
+
+
.option bv
.index verifying||address, using \-bv-\
.index address||verification
usernames and passwords for database lookups.
If no arguments are given, Exim runs in an interactive manner, prompting with a
-right angle bracket for addresses to be verified. Verification differs from
-address testing (the \-bt-\ option) in that routers that have \no@_verify\ set
-are skipped, and if the address is accepted by a router that has \fail@_verify\
-set, verification fails. The address is verified as a recipient if \-bv-\ is
-used; to test verification for a sender address, \-bvs-\ should be used.
+right angle bracket for addresses to be verified.
+.em
+Unlike the \-be-\ test option, you cannot arrange for Exim to use the
+\*readline()*\ function, because it is running as \*exim*\ and there are
+security issues.
+.nem
+
+Verification differs from address testing (the \-bt-\ option) in that routers
+that have \no@_verify\ set are skipped, and if the address is accepted by a
+router that has \fail@_verify\ set, verification fails. The address is verified
+as a recipient if \-bv-\ is used; to test verification for a sender address,
+\-bvs-\ should be used.
If the \-v-\ 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
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.
-When this option is used by a caller other than root or the Exim user,
-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 \\ALT@_CONFIG@_ROOT@_ONLY\\ is defined in \(Local/Makefile)\, root
-privilege is retained for \-C-\ only if the caller of Exim is root.
-This option is not set by default.
+When this option is used by a caller other than root or the Exim user, 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 \\ALT@_CONFIG@_ROOT@_ONLY\\ is defined in
+\(Local/Makefile)\, root privilege is retained for \-C-\ only if the caller of
+Exim is root.
+.em
+That is, the Exim user is no longer privileged in this regard. This build-time
+option is not set by default in the Exim source distribution tarbundle.
+However, if you are using a `packaged' version of Exim (source or binary), the
+packagers might have enabled it.
+.nem
Setting \\ALT@_CONFIG@_ROOT@_ONLY\\ locks out the possibility of testing a
configuration using \-C-\ 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 \-C-\ causes privilege to be lost. However, root can test reception and
-delivery using two separate commands (one to put a message on the queue, using
+delivery using two separate commands (one to put a message on the queue, using
\-odq-\, and another to do the delivery, using \-M-\).
If \\ALT@_CONFIG@_PREFIX\\ is defined \(in Local/Makefile)\, it specifies a
must start. In addition, the file name must not contain the sequence \"/../"\.
However, if the value of the \-C-\ option is identical to the value of
\\CONFIGURE@_FILE\\ in \(Local/Makefile)\, Exim ignores \-C-\ and proceeds as
-usual. There is no default setting for \\ALT@_CONFIG@_PREFIX\\; when it is
+usual. There is no default setting for \\ALT@_CONFIG@_PREFIX\\; when it is
unset, any file name can be used with \-C-\.
\\ALT@_CONFIG@_PREFIX\\ can be used to confine alternative configuration files
.index macro||setting on command line
This option can be used to override macro definitions in the configuration file
(see section ~~SECTmacrodefs). However, like \-C-\, if it is used by an
-unprivileged caller, it causes Exim to give up its root privilege.
+unprivileged caller, it causes Exim to give up its root privilege.
If \\DISABLE@_D@_OPTION\\ is defined in \(Local/Makefile)\, the use of \-D-\ is
completely disabled, and its use causes an immediate error exit.
The entire option (including equals sign if present) must all be within one
-command line item. \-D-\ 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
+command line item. \-D-\ 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:
.display asis
exim -DABC ...
exim -DABC= ...
.endd
-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
+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:
.display asis
exim '-D ABC = something' ...
interface $t $rm{lists of local interfaces}
lists $t $rm{matching things in lists}
load $t $rm{system load checks}
-local@_scan $t $rm{can be used by \*local@_scan()*\ (see chapter ~~CHAPlocalscan)}
+local@_scan $t $rm{can be used by \*local@_scan()*\ (see chapter ~~CHAPlocalscan)}
lookup $t $rm{general lookup code and all lookups}
memory $t $rm{memory handling}
pid $t $rm{add pid to debug output lines}
all $t $rm{all of the above, and also \-v-\}
.endd
-.em
.index resolver, debugging output
.index DNS||resolver, debugging output
-The \"resolver"\ option produces output only if the DNS resolver was compiled
+The \"resolver"\ 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.
-.nem
The default (\-d-\ with no argument) omits \"expand"\, \"filter"\,
\"interface"\, \"load"\, \"memory"\, \"pid"\, \"resolver"\, and \"timestamp"\.
If the \debug@_print\ option is set in any driver, it produces output whenever
any debugging is selected, or if \-v-\ is used.
+.em
+.option dd <<debug options>>
+This option behaves exactly like \-d-\ 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.
+.nem
+
.option dropcr
-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
+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 ~~SECTlineendings.
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 \untrusted@_set@_sender\ can be set to allow untrusted
-users to use it. In the absence of \-f-\, or if the caller is not allowed to
-use it, the sender of a local message is set to the caller's login name at the
-default qualify domain.
+users to use it.
+.em
+Processes running as root or the Exim user are always trusted. Other
+trusted users are defined by the \trusted@_users\ or \trusted@_groups\ options.
+
+In the absence of \-f-\, 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.
-There is one exception to the restriction on the use of \-f-\: an empty sender
-can be specified by any user, 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:
+There is one exception to the restriction on the use of \-f-\: an empty sender
+can be specified by any user, trusted or not,
+.nem
+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:
.display asis
exim -f '<>' user@domain
exim -f "" user@domain
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 \queue@_domains\, \queue@_smtp@_domains\, and
-\hold@_domains\ are ignored.
+\hold@_domains\ are ignored.
.index hints database||overriding retry hints
Retry hints for any of the addresses are
overridden -- Exim tries to deliver even if the normal retry time has not yet
to the remote host has been authenticated.
.option MCP
-This option is not intended for use by external callers. It is used internally
-by Exim in conjunction with the \-MC-\ option. It signifies that the server to
+This option is not intended for use by external callers. It is used internally
+by Exim in conjunction with the \-MC-\ option. It signifies that the server to
which Exim is connected supports pipelining.
.option MCQ #<<process id>> <<pipe fd>>
.index delivery||abandoning further attempts
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.
+their status is not altered.
For non-bounce messages, a delivery error message is sent to the sender,
containing the text `cancelled by administrator'. Bounce messages are just
discarded.
Exim.
.option O #<<data>>
-This option is interpreted by Sendmail to mean `set option`. It is ignored by
+This option is interpreted by Sendmail to mean `set option`. It is ignored by
Exim.
.option oA #<<file name>>
.index delivery||in the background
This option applies to all modes in which Exim accepts incoming messages,
including the listening daemon. It requests `background' delivery of such
-messages, which means that the accepting process automatically starts delivery
-process for each message received, but does not wait for the delivery process
-to complete. This is the default action if none of the \-od-\ options are
-present.
+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.
+.em
+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.
+.nem
+This is the default action if none of the \-od-\ options are present.
If one of the queueing options in the configuration file
(\queue@_only\ or \queue@_only@_file\, for example) is in effect, \-odb-\
a locally-generated message. (For the daemon it is exactly the same as
\-odb-\.) A delivery process is automatically started to deliver the
message, and Exim waits for it to complete before proceeding.
-However, like \-odb-\, this option has no effect if \queue@_only@_override\ is
+.em
+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.
+.nem
+However, like \-odb-\, this option has no effect if \queue@_only@_override\ is
false and one of the queueing options in the configuration file is in effect.
+.em
+If there is a temporary delivery error during foreground delivery, the message
+is left on the queue for later delivery, and the original reception process
+exists. See chapter ~~CHAPnonqueueing for a way of setting up a restricted
+configuration that never queues messages.
+.nem
+
.option odi
This option is synonymous with \-odf-\. It is provided for compatibility with
Sendmail.
.option odqs
.index SMTP||delaying delivery
-This option is a hybrid between \-odb-\/\-odi-\ and \-odq-\.
+This option is a hybrid between \-odb-\/\-odi-\ and \-odq-\.
However, like \-odb-\ and \-odi-\, this option has no effect if
\queue@_only@_override\ is false and one of the queueing options in the
configuration file is in effect.
.index dot||in incoming, non-SMTP message
This option, which has the same effect as \-i-\, specifies that a dot on a line
by itself should not terminate an incoming, non-SMTP message.
-.em
-Otherwise, a single dot does terminate, though Exim does no special processing
+Otherwise, a single dot does terminate, though Exim does no special processing
for other lines that start with a dot.
-.nem
This option is set by default if Exim is called as \*rmail*\. See also \-ti-\.
.option oitrue
A number of options starting with \-oM-\ 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
-\-bh-\,
+\-bh-\,
\-be-\,
\-bf-\, \-bF-\, \-bt-\, or \-bv-\ testing options. In other circumstances, they
are ignored unless the caller is trusted.
.option oMai #<<string>>
.index authentication||id, specifying for local message
See \-oMa-\ above for general remarks about the \-oM-\ options. The \-oMai-\
-option sets the
+option sets the
value of \$authenticated@_id$\ (the id that was authenticated).
This overrides the default value (the caller's login id) for messages from
local sources. See chapter ~~CHAPSMTPAUTH for a discussion of authenticated
.index authentication||sender, specifying for local message
See \-oMa-\ above for general remarks about the \-oM-\ options. The \-oMas-\
option sets the authenticated sender value
-in \$authenticated@_sender$\.
+in \$authenticated@_sender$\.
It overrides the sender address that is created from the caller's login id for
messages from local sources. See chapter ~~CHAPSMTPAUTH for a discussion of
authenticated senders.
See \-oMa-\ above for general remarks about the \-oM-\ options. The \-oMi-\
option sets the IP interface address value. A port number may be included,
using the same syntax as for \-oMa-\.
-The interface address is placed in \$interface@_address$\ and the port number,
+The interface address is placed in \$interface@_address$\ and the port number,
if present, in \$interface@_port$\.
.option oMr #<<protocol name>>
.index protocol||incoming, specifying for local message
See \-oMa-\ above for general remarks about the \-oM-\ options. The \-oMr-\
-option sets the received protocol value
-in \$received@_protocol$\.
-However, this applies only when \-bs-\ is not used. For interactive SMTP input,
-the protocol is determined by whether \\EHLO\\ or \\HELO\\ is used, and is
-always either `local-esmtp' or `local-smtp'. For \-bS-\ (batch SMTP) however,
-the protocol can be set by \-oMr-\.
+option sets the received protocol value that is stored in
+\$received@_protocol$\. However, this applies only when \-bs-\ is not used. For
+interactive SMTP input (\-bs-\), the protocol is always
+.em
+`local-' followed by one of the standard SMTP protocol names (see the
+description of \$received@_protocol$\ in section ~~SECTexpvar).
+.nem
+For \-bS-\ (batch SMTP) however, the protocol can be set by \-oMr-\.
.option oMs #<<host name>>
.index sender||host name, specifying for local message
See \-oMa-\ above for general remarks about the \-oM-\ options. The \-oMs-\
-option sets the sender host name
-in \$sender@_host@_name$\. When this option is present, Exim does not attempt
+option sets the sender host name
+in \$sender@_host@_name$\. 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.
.option oMt #<<ident string>>
.index sender||ident string, specifying for local message
See \-oMa-\ above for general remarks about the \-oM-\ options. The \-oMt-\
option sets the sender ident value
-in \$sender@_ident$\.
+in \$sender@_ident$\.
The default setting for local callers is the login id of the calling process.
.option om
.option oP #<<path>>
.index pid (process id)||of daemon
.index daemon||process id (pid)
-This option is useful only in conjunction with \-bd-\ or \-q-\ with a time
+This option is useful only in conjunction with \-bd-\ or \-q-\ with a time
value. The option specifies the file to which the process id of the daemon is
written. When \-oX-\ is used with \-bd-\, or when \-q-\ with a time is used
without \-bd-\, this is the only way of causing Exim to write a pid file,
chapter ~~CHAPperl). It overrides the setting of the \perl@_at@_start\ option,
forcing the starting of the interpreter to occur as soon as Exim is started.
-.em
.option p<<rval>>:<<sval>>
For compatibility with Sendmail, this option
is equivalent to
-.display
+.display
-oMr <<rval>> -oMs <<sval>>
.endd
It sets the incoming protocol and host name (for trusted callers). The
Note the Exim already has two private options, \-pd-\ and \-ps-\, that refer to
embedded Perl. It is therefore impossible to set a protocol value of \"p"\ or
\"s"\ using this option (but that does not seem a real limitation).
-.nem
.option q
.index queue runner||starting manually
An option starting with \-qq-\ requests a two-stage queue run. In the first
stage, the queue is scanned as if the \queue@_smtp@_domains\ option matched
every domain. Addresses are routed, local deliveries happen, but no remote
-transports are run.
+transports are run.
.index hints database||remembering routing
The hints database that remembers which messages are
waiting for specific hosts is updated, as if delivery to those hosts had been
\-odq-\ and want a queue runner just to process the new messages.
.option q[q][i]f...
-.index queue||forcing delivery
+.index queue||forcing delivery
.index delivery||forcing in queue run
If one \*f*\ flag is present, a delivery attempt is forced for each non-frozen
message, whereas without \f\ only those non-frozen addresses that have passed
Such a daemon listens for incoming SMTP calls, and also starts a queue runner
process every 30 minutes.
-When a daemon is started by \-q-\ with a time value, but without \-bd-\, no pid
+When a daemon is started by \-q-\ with a time value, but without \-bd-\, no pid
file is written unless one is explicitly requested by the \-oP-\ option.
.option qR <<rsflags>>#<<string>>
conditions must be met for a message to be selected. If either of the options
has \*f*\ or \*ff*\ in its flags, the associated action is taken.
-.em
.option Tqt#<<times>>
This 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 `queue times' so that various warning/retry features can be
-tested.
-.nem
+of explicit `queue times' so that various warning/retry features can be
+tested.
.option t
.index recipient||extracting from header lines
the requirement has been removed in RFC 2822, but that is still very new.
.index \Resent@-\ header lines||with \-t-\
-If there are any \Resent@-\ header lines in the message, Exim extracts
+If there are any \Resent@-\ header lines in the message, Exim extracts
recipients from all ::Resent-To::, ::Resent-Cc::, and ::Resent-Bcc:: header
-lines instead of from ::To::, ::Cc::, and ::Bcc::. This is for compatibility
-with Sendmail and other MTAs. (Prior to release 4.20, Exim gave an error if
+lines instead of from ::To::, ::Cc::, and ::Bcc::. This is for compatibility
+with Sendmail and other MTAs. (Prior to release 4.20, Exim gave an error if
\-t-\ was used in conjunction with \Resent@-\ header lines.)
RFC 2822 talks about different sets of \Resent@-\ header lines (for when a
\X-Resent@-\ when a new set is added. This removes any possible ambiguity.
.option ti
-This option is exactly equivalent to \-t-\ \-i-\. It is provided for
+This option is exactly equivalent to \-t-\ \-i-\. It is provided for
compatibility with Sendmail.
.option tls-on-connect
.index TLS||use without STARTTLS
.index TLS||automatic start
-This option is available when Exim is compiled with TLS support. It makes it
-possible to support legacy clients that do not support the \\STARTTLS\\
-command, but instead expect to start up a TLS session as soon as a connection
-to the server is established. These clients use a special port (usually called
-the `ssmtp' port) instead of the normal SMTP port 25. The \-tls-on-connect-\
-option can be used to run Exim in this way from \*inetd*\, and it can also be
-used to run a special daemon that operates in this manner (use \-oX-\ to
-specify the port). However, although it is possible to run one daemon that
-listens on several ports, it is not possible to have some of them operate one
-way and some the other. With only a few clients that need the legacy support, a
-convenient approach is to use a daemon for normal SMTP (with or without
-\\STARTTLS\\) and \*inetd*\ with \-tls-on-connect-\ for the legacy clients.
+This option is available when Exim is compiled with TLS support.
+.em
+It forces all incoming SMTP connections to behave as if the incoming port is
+listed in the \tls@_on@_connect@_ports\ option. See section ~~SECTsupobssmt and
+chapter ~~CHAPTLS for further details.
+.nem
.option U
.index Sendmail compatibility||\-U-\ option ignored
.index run time configuration
.index configuration file||general description
.index \\CONFIGURE@_FILE\\
+.index configuration file||errors in
+.index error||in configuration file
+.index return code||for bad configuration
Exim uses a single run time 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
+because Exim is designed to operate in a distributed manner, without central
control.
+.em
+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. \**Note**\: 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.
+.nem
+
+
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
.index \\EXIM@_USER\\
.index \\EXIM@_GROUP\\
+.index \\CONFIGURE@_OWNER\\
+.index \\CONFIGURE@_GROUP\\
.index configuration file||ownership
.index ownership||configuration file
-The run time configuration file must be owned by root or by the user that
-is specified at compile time by the \\EXIM@_USER\\ option,
+The run time configuration file must be owned by root or by the user that is
+specified at compile time by the \\EXIM@_USER\\ option, 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 one specified at compile time by the \\EXIM@_GROUP\\ option
.em
-or by the user that is specified at compile time by the \\CONFIGURE@_OWNER\\
-option (if set).
+or by the \\CONFIGURE@_GROUP\\ option.
.nem
-The configuration file must not be world-writeable or group-writeable, unless
-its group is the one specified at compile time by the \\EXIM@_GROUP\\ option.
-\**Warning**\: In a conventional configuration, where the Exim binary is setuid
-to root, anybody who is able to edit the run time configuration file has an
-easy way to run commands as root. If you make your mail administrators members
-of the Exim group, but do not trust them with root, make sure that the run time
+\**Warning**\: In a conventional configuration, where the Exim binary is setuid
+to root, anybody who is able to edit the run time configuration file has an
+easy way to run commands as root. If you make your mail administrators members
+of the Exim group, but do not trust them with root, make sure that the run time
configuration is not group writeable.
-
A default configuration file, which will work correctly in simple situations,
-is provided in the file \(src/configure.default)\.
-If \\CONFIGURE@_FILE\\ defines just one file name, 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 ~~CHAPdefconfil is a `walk-through' discussion of the
-default configuration.
-
-.index configuration file||errors in
-.index error||in configuration file
-.index return code||for bad configuration
-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.
+is provided in the file \(src/configure.default)\. If \\CONFIGURE@_FILE\\
+defines just one file name, 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
+~~CHAPdefconfil is a `walk-through' discussion of the default configuration.
.section Using a different configuration file
A one-off alternate configuration can be specified by the \-C-\ command line
option, which may specify a single file or a list of files. However, when \-C-\
is used, Exim gives up its root privilege, unless called by root or the Exim
-user (or unless the argument for \-C-\ is identical to the built-in value from
+user (or unless the argument for \-C-\ is identical to the built-in value from
\\CONFIGURE@_FILE\\). \-C-\ 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 \-C-\.
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 \-C-\ causes privilege to be lost. However, root can test reception and
-delivery using two separate commands (one to put a message on the queue, using
+delivery using two separate commands (one to put a message on the queue, using
\-odq-\, and another to do the delivery, using \-M-\).
If \\ALT@_CONFIG@_PREFIX\\ is defined \(in Local/Makefile)\, it specifies a
name can be used with \-C-\.
One-off changes to a configuration can be specified by the \-D-\ command line
-option, which defines and overrides values for macros used inside the
+option, which defines and overrides values for macros used inside the
configuration file. However, like \-C-\, the use of this option by a
non-privileged user causes Exim to discard its root privilege.
If \\DISABLE@_D@_OPTION\\ is defined in \(Local/Makefile)\, the use of \-D-\ is
If \\CONFIGURE@_FILE@_USE@_NODE\\ is defined in \(Local/Makefile)\, Exim first
looks for a file whose name is the configuration file name followed by a dot
and the machine's node name, as obtained from the \*uname()*\ function. If this
-file does not exist, the standard name is tried. This processing occurs for
+file does not exist, the standard name is tried. This processing occurs for
each file name in the list given by \\CONFIGURE@_FILE\\ or \-C-\.
In some esoteric situations different versions of Exim may be run under
.display asis
LOCAL_SCAN_HAS_OPTIONS=yes
.endd
-in \(Local/Makefile)\ before building Exim. Full details of the
+in \(Local/Makefile)\ before building Exim. Full details of the
\*local@_scan()*\ facility are given in chapter ~~CHAPlocalscan.
.endp
+.index configuration file||leading whitespace in
+.index configuration file||trailing whitespace in
+.index whitespace||in configuration file
+.em
+Leading and trailing whitespace in configuration lines is always ignored.
+.nem
Blank lines in the file, and lines starting with a @# character (ignoring
leading white space) are treated as comments and are ignored. \**Note**\: a
@# character other than at the beginning of a line is not treated specially,
and does not introduce a comment.
-Any non-comment line can be continued by ending it with a backslash. Trailing
-white space after the backslash is ignored, and leading white space at the
-start of continuation lines is also ignored.
+Any non-comment line can be continued by ending it with a backslash.
+.em
+Note that the general rule for whitespace means that trailing white space after
+the backslash is ignored, and leading white space at the start of continuation
+lines is also ignored.
+.nem
Comment lines beginning with @# (but not empty lines) may appear in the middle
of a sequence of continuation lines.
.display
@.include@_if@_exists <<file name>>
.endd
-on a line by itself. Double quotes round the file name are optional. If you use
-the first form, a configuration error occurs if the file does not exist; the
+on a line by itself. Double quotes round the file name 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.
Includes may be nested to any depth, but remember that Exim reads its
hosts_lookup = a.b.c \
.include /some/file
.endd
-Include processing happens
-after
+Include processing happens
+after
macro processing (see below). Its effect is to process the lines of the file as
if they occurred inline where the inclusion appears.
.index configuration file||conditional skips
.index .ifdef
You can use the directives \".ifdef"\, \".ifndef"\, \".elifdef"\,
-\".elifndef"\, \".else"\, and \".endif"\ 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).
+\".elifndef"\, \".else"\, and \".endif"\ 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).
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
is multiplied by 1024x1024.
When the values of integer option settings are output, values which are an
-exact multiple of 1024 or 1024x1024 are
+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.
.endd
For example, `3h50m' 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
+Exim does not restrict the values; it is perfectly acceptable, for example, to
specify `90m' instead of `1h30m'.
.index format||list item in configuration
.index string list, definition
.rset SECTlistconstruct "~~chapter.~~section"
-The data for some configuration options is a colon-separated list of items.
-Many of these options are shown with type `string list' in the descriptions
-later in this document. Others are listed as `domain list', `host list',
-`address list', or `local part list'. Syntactically, they are all the same;
-however, those other than `string list' are subject to particular kinds of
-interpretation, as described in chapter ~~CHAPdomhosaddlists.
+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 `string list' in
+the descriptions later in this document. Others are listed as `domain list',
+`host list', `address list', or `local part list'. Syntactically, they are all
+the same; however, those other than `string list' are subject to particular
+kinds of interpretation, as described in chapter ~~CHAPdomhosaddlists.
In all these cases, the entire list is treated as a single string as far as the
input syntax is concerned. The \trusted@_users\ setting in section
local_interfaces = 127.0.0.1 : ::::1
.endd
contains two IP addresses, the IPv4 address 127.0.0.1 and the IPv6 address
-@:@:1. IPv6 addresses are going to become more and more common as the new
-protocol gets more widely deployed.
+@:@:1.
.index list||separator, changing
.index IPv6||addresses in lists
-Doubling their colons 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:
+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:
.display asis
local_interfaces = <; 127.0.0.1 ; ::1
.endd
confined to circumstances where they really are needed.
+.em
+.section Empty items in lists
+.rset SECTempitelis "~~chapter.~~section"
+.index list||empty item in
+An empty item at the end of a list is always ignored. In other words, trailing
+separator characters are ignored. Thus, the list in
+.display asis
+senders = user@domain :
+.endd
+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:
+.display asis
+senders = user1@domain : : user2@domain
+.endd
+\**Note**\: there must be whitespace 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:
+.display asis
+senders = :
+.endd
+In this case, the first item is empty, and the second is discarded because it
+is at the end of the list.
+.nem
+
+
.section Format of driver configurations
.rset SECTfordricon "~~chapter.~~section"
.index drivers||configuration format
check_local_user
transport = local_delivery
.endd
-For each driver instance, you specify which Exim code module it uses -- by the
+For each driver instance, you specify which Exim code module it uses -- by the
setting of the \driver\ 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 \%smtp%\ driver; if you want to deliver to a local file
The first line defines a domain list called \*local@_domains*\; this is used
later in the configuration to identify domains that are to be delivered
-on the local host.
+on the local host.
.index @@ in a domain list
There is just one item in this list, the string `@@'. This is a special form of
entry which means `the name of the local host'. Thus, if the local host is
acl_smtp_rcpt = acl_check_rcpt
.endd
This option specifies an \*Access Control List*\ (ACL) which is to be used
-during an incoming SMTP session for every recipient of a message (every
+during an incoming SMTP session for every recipient of a message (every
\\RCPT\\ command). The name of the list is \*acl@_check@_rcpt*\, and we will
come to its definition below, in the ACL section of the configuration. ACLs
control which recipients are accepted for an incoming message -- if a
.display asis
# allow_domain_literals
.endd
-.em
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
+people believe there are circumstances (for example, messages addressed to
\*postmaster*\) where domain literals are still useful.
-.nem
The next configuration line is a kind of trigger guard:
.display asis
The list of users specified by \never@_users\ is not, however, the complete
list; the build-time configuration in \(Local/Makefile)\ has an option called
\\FIXED@_NEVER@_USERS\\ specifying a list that cannot be overridden. The
-contents of \never@_users\ are added to this list. By default
+contents of \never@_users\ are added to this list. By default
\\FIXED@_NEVER@_USERS\\ also specifies root.
When a remote host connects to Exim in order to send mail, the only information
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 `nearby' networks.
-Note that it is not always possible to find a host name from an IP address,
+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.
deny domains = !+local_domains
local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./
-.endd
-These statements are concerned with local parts that contain any of the
+.endd
+These statements are concerned with local parts that contain any of the
characters `@@', `%', `!', `/', `|', or dots in unusual places. Although these
characters are entirely legal in local parts (in the case of `@@' and leading
dots, only if correctly quoted), they do not commonly occur in Internet mail
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
+see if a
+bounce
message could be delivered to it. In the case of remote addresses, basic
verification checks only the domain, but \*callouts*\ can be used for more
verification if required. Section ~~SECTaddressverification discusses the
The name of the router driver is \%dnslookup%\,
and is specified by the \driver\ 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 \driver\ option must be one
+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 \driver\ option must be one
of the driver modules that is in the Exim binary.
The \%dnslookup%\ router routes addresses by looking up their domains in the
The \ignore@_target@_hosts\ 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
+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
the value of the \data\ option is empty, causing the address to be passed to
the next router.
-\(/etc/aliases)\ is a conventional name for the system aliases file that is
-often used. That is why it is referenced by from the default configuration
+\(/etc/aliases)\ 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
\(Local/Makefile)\ before building Exim.
local user. If it is not, the router is skipped. When a local user is found,
the file called \(.forward)\ in the user's home directory is consulted. If it
does not exist, or is empty, the router declines. Otherwise, the contents of
-\(.forward)\ are interpreted as redirection data (see chapter ~~CHAPredirect
+\(.forward)\ are interpreted as redirection data (see chapter ~~CHAPredirect
for more details).
.index Sieve filter||enabling in default router
The \no@_verify\ and \no@_expn\ options mean that this router is skipped when
verifying addresses, or when running as a consequence of an SMTP \\EXPN\\
-command.
+command.
There are two reasons for doing this:
.numberpars
-Whether or not a local user has a \(.forward)\ file is not really relevant when
+Whether or not a local user has a \(.forward)\ file is not really relevant when
checking an address for validity; it makes sense not to waste resources doing
unnecessary work.
.nextp
-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.
+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' \(.forward)\ files at
this time.
.fi
(O'Reilly, ISBN 0-596-00289-0).
-The documentation for the syntax and semantics of the regular expressions that
+The documentation for the syntax and semantics of the regular expressions that
are supported by PCRE is included in plain text in the file
\(doc/pcrepattern.txt)\ in the Exim distribution, and also in the HTML
tarbundle of Exim documentation, and as an appendix to the
options set), except that the \\PCRE@_CASELESS\\ option is set when the
matching is required to be case-insensitive.
-.em
-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
+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 `ends with' wildcard. In this example of a configuration setting, the
second item in the colon-separated list is a regular expression.
.display asis
normal effect of `anchoring' it to the start of the string that is being
matched.
-There are, however, two cases where a circumflex is not required for the
+There are, however, two cases where a circumflex is not required for the
recognition of a regular expression: these are the \match\ condition in a
string expansion, and the \matches\ 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.
-In all cases, if you want a regular expression to match at the end of a string,
+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:
.display asis
domains = ^\\d{3}\\.example
.endd
-matches the domain \*123.example*\, but it also matches \*123.example.com*\.
+matches the domain \*123.example*\, but it also matches \*123.example.com*\.
You need to use:
.display asis
domains = ^\\d{3}\\.example\$
.endd
if you want \*example*\ to be the top-level domain. (The backslash before the
@$ is another artefact of string expansion.)
-.nem
.section Testing regular expressions
messages. Two different kinds of syntax are used:
.numberpars
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.
+cause parts of the string to be replaced by data that is obtained from the
+lookup.
.nextp
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
.endp
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.
+processed as lists. Therefore, they may also contain lookups of the first kind.
Be careful to distinguish between the following two examples:
.display asis
domains = ${lookup{$sender_host_address}lsearch{/some/file}}
192.168.3.4: domain1 : domain2 : ...
192.168.1.9: domain3 : domain4 : ...
.endd
-Thus, the result of the expansion is a list of domains (and possibly other
+Thus, the result of the expansion is a list of domains (and possibly other
types of item that are allowed in domain lists).
-In the second case, the lookup is a single item in a domain list. It causes
+In the second case, 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:
.display asis
-domain1:
+domain1:
domain2:
.endd
-Any data that follows the keys is not relevant when checking that the domain
+Any data that follows the keys is not relevant when checking that the domain
matches the list item.
-It is possible to use both kinds of lookup at once. Consider a file containing
+It is possible to use both kinds of lookup at once. Consider a file containing
lines like this:
.display asis
192.168.5.6: lsearch;/another/file
.endd
-If the value of \$sender@_host@_address$\ is 192.168.5.6, expansion of the
-first \domains\ setting above generates the second setting, which therefore
+If the value of \$sender@_host@_address$\ is 192.168.5.6, expansion of the
+first \domains\ setting above generates the second setting, which therefore
causes a second lookup to occur.
The rest of this chapter describes the different lookup types that are
available. Any of them can be used in either of the circumstances described
-above. The syntax requirements for the two cases are described in chapters
+above. The syntax requirements for the two cases are described in chapters
~~CHAPexpand and ~~CHAPdomhosaddlists, respectively.
.section Lookup types
Two different styles of data lookup are implemented:
.numberpars $.
The \*single-key*\ style requires the specification of a file in which to look,
-and a single key to search for. The lookup type determines how the file is
-searched.
+and a single key to search for.
+.em
+The key must be a non-empty string for the lookup to succeed.
+.nem
+The lookup type determines how the file is searched.
.nextp
.index query-style lookup||definition of
The \*query*\ style accepts a generalized database query.
zero is included in the key that is passed to the DBM library. See section
~~SECTdb for a discussion of DBM libraries.
.index Berkeley DB library||file format
-For all versions of Berkeley DB, Exim uses the \\DB@_HASH\\ style of database
-when building DBM files using the \exim@_dbmbuild\ utility. However, when using
+For all versions of Berkeley DB, Exim uses the \\DB@_HASH\\ style of database
+when building DBM files using the \exim@_dbmbuild\ 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
+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.)
.nextp
.nextp
.index lookup||iplsearch
.index iplsearch lookup type
-.em
\%iplsearch%\: 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
The key for an \%iplsearch%\ 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
-`best' match. Apart from the way the keys are matched, the processing for
+`best' match. Apart from the way the keys are matched, the processing for
\%iplsearch%\ is the same as for \%lsearch%\.
\**Warning 1**\: Unlike most other single-key lookup types, a file of data for
\%iplsearch%\ can \*not*\ be turned into a DBM or cdb file, because those
lookup types support only literal keys.
-\**Warning 2**\: In a host list, you must always use \%net-iplsearch%\ so that
+\**Warning 2**\: In a host list, you must always use \%net-iplsearch%\ so that
the implicit key is the host's IP address rather than its name (see section
~~SECThoslispatsikey).
-.nem
.nextp
.index linear search
wildcarding of any kind.
.index lookup||lsearch, colons in keys
-In most \%lsearch%\ files, keys are not required to contain colons
-.em
-or @# characters, or
-.nem
-whitespace. 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
-~~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 \%lsearch%\ line.
+.index whitespace||in lsearch key
+In most \%lsearch%\ files, keys are not required to contain colons or @#
+characters, or whitespace. 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 ~~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 \%lsearch%\ line.
.nextp
.index NIS lookup type
.index lookup||NIS
\%wildlsearch%\ or \%nwildlsearch%\: These search a file linearly, like
\%lsearch%\, but instead of being interpreted as a literal string, each key may
be wildcarded. The difference between these two lookup types is that for
-\%wildlsearch%\, each key in the file is string-expanded before being used,
+\%wildlsearch%\, each key in the file is string-expanded before being used,
whereas for \%nwildlsearch%\, no expansion takes place.
Like \%lsearch%\, the testing is done case-insensitively. The following forms
of wildcard are recognized:
.numberpars "$*$"
-The string may begin with an asterisk to mean `begins with'. For example:
+The string may begin with an asterisk to mean `ends with'. For example:
.display asis
*.a.b.c data for anything.a.b.c
*fish data for anythingfish
.display asis
^\N\d+\.a\.b\N data for <digits>.a.b
.endd
-Note the use of \"@\N"\ to disable expansion of the contents of the regular
-expression. If you are using \%nwildlsearch%\, where the keys are not
+Note the use of \"@\N"\ to disable expansion of the contents of the regular
+expression. If you are using \%nwildlsearch%\, where the keys are not
string-expanded, the equivalent entry is:
.display asis
^\d+\.a\.b data for <digits>.a.b
escape all the backslashes inside the quotes.
.nextp
Although I cannot see it being of much use, the general matching function
-that is used to implement
-\%(n)wildlsearch%\
+that is used to implement
+\%(n)wildlsearch%\
means that the string may begin with a lookup name terminated by a semicolon,
and followed by lookup data. For example:
.display asis
.section Query-style lookup types
.index lookup||query-style types
.index query-style lookup||list of types
-The supported query-style lookup types are listed below. Further details about
+The supported query-style lookup types are listed below. Further details about
many of them are given in later sections.
.numberpars $.
.index DNS||as a lookup type
.index lookup||DNS
-\%dnsdb%\: This does a DNS search for a record whose domain name is the supplied
-query. The resulting data is the contents of the record. See section
-~~SECTdnsdb.
+\%dnsdb%\: This does a DNS search for
+.em
+one or more records whose domain names are given in the supplied query. The
+resulting data is the contents of the records.
+.nem
+See section ~~SECTdnsdb.
.nextp
.index Interbase lookup type
.index lookup||Interbase
.nextp
.index lookup||passwd
.index passwd lookup type
+.index \(/etc/passwd)\
\%passwd%\ is a query-style lookup with queries that are just user names. The
lookup calls \*getpwnam()*\ to interrogate the system password data, and on
success, the result string is the same as you would get from an \%lsearch%\
.display asis
data = ${lookup{$local_part@$domain}lsearch*@{/etc/mixed-aliases}}
.endd
-Suppose the address that is being processed is \*jane@@eyre.example*\. Exim
+Suppose the address that is being processed is \*jane@@eyre.example*\. Exim
looks up these keys, in this order:
.display asis
jane@eyre.example
*@eyre.example
*
.endd
-The data is taken from whichever key it finds first. \**Note**\: in an
-\%lsearch%\ 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
+The data is taken from whichever key it finds first. \**Note**\: in an
+\%lsearch%\ 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.
by \*dates.fict.example*\, if that does not appear as a separate key in the
file.
-\**Note**\: Partial matching is not available for query-style lookups. It is
+\**Note**\: Partial matching is not available for query-style lookups. It is
also not available for any lookup items in address lists (see section
~~SECTaddresslist).
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
+partial matching keys
beginning with a special prefix (default `$*$.') 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.
*.fict.example
.endd
As soon as one key in the sequence is successfully looked up, the lookup
-finishes.
+finishes.
.index lookup||partial matching, changing prefix
.index prefix||for partial matching
-The use of `$*$.' as the partial matching prefix is a default that can be
+The use of `$*$.' 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 `partial'. For example:
domains = partial(.)lsearch;/some/file
.endd
In this example, if the domain is \*a.b.c*\, the sequence of lookups is
-\"a.b.c"\, \".a.b.c"\, and \".b.c"\ (the default minimum of 2 non-wild
+\"a.b.c"\, \".a.b.c"\, and \".b.c"\ (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:
.display asis
example, the final lookup for `partial0(.)' is for \"."\ alone.
.nextp
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
+remainder is looked up. With the default prefix, therefore, the final lookup is
for `$*$' on its own.
.nextp
Otherwise, the whole prefix is looked up.
.section Lookup caching
-.index lookup||caching
+.index lookup||caching
.index caching||lookup data
-An Exim process
-caches the most recent lookup result on a per-file basis for single-key
-lookup types, and keeps the relevant files open. 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
-\lookup@_open@_max\ option.
-
-For query-style lookups, a single data cache per lookup type is kept. The files
-are closed and the caches flushed at strategic points during delivery -- for
-example, after all routing is complete.
+.em
+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 caching facility.
+
+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 \lookup@_open@_max\ option.
+
+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.
+.nem
.section Quoting lookup data
.index dnsdb lookup
.index lookup||dnsdb
.index DNS||as a lookup type
-The \%dnsdb%\ lookup type uses the DNS as its database. A query consists of a
-record type and a domain name, separated by an equals sign. For example, an
-expansion string could contain:
+The \%dnsdb%\ 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:
.display asis
${lookup dnsdb{mx=a.b.example}{$value}fail}
.endd
+The supported DNS record types are A, CNAME, MX, NS, PTR, SRV, and TXT, and,
+when Exim is compiled with IPv6 support, AAAA (and A6 if that is also
+configured). If no type is given, TXT is assumed. When the type is PTR,
.em
-The supported record types are A, CNAME, MX, NS, PTR, SRV, and TXT,
-.nem
-and, when Exim is compiled with IPv6 support, AAAA (and A6 if that is also
-configured). If no type is given, TXT is assumed. When the type is PTR, the
-address should be given as normal; it is converted to the necessary inverted
-format internally. For example:
+the data can be an IP address, written as normal; inversion and the addition of
+\in-addr.arpa\ or \ip6.arpa\ happens automatically. For example:
.display asis
${lookup dnsdb{ptr=192.168.4.5}{$value}fail}
.endd
+If the data for a PTR record is not a syntactically valid IP address, it is not
+altered and nothing is added.
+
+For any record type, if multiple records are found (or, for A6 lookups, if a
+single record leads to multiple addresses), 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:
+.display asis
+${lookup dnsdb{>: a=host1.example}}
+.endd
+It is permitted to specify a space as the separator character. Further
+whitespace is ignored.
-.index MX record||in \%dnsdb%\ lookup
-For MX records, both the preference value and the host name are returned,
-separated by a space.
-.em
.index SRV record||in \%dnsdb%\ lookup
-For SRV records, the priority, weight, port, and host name are returned,
-separated by spaces. For any record type,
-.nem
-if multiple records are found (or, for A6 lookups, if a single record leads to
-multiple addresses), the data is returned as a concatenation, separated by
-newlines. The order, of course, depends on the DNS resolver.
+For SRV records, the priority, weight, port, and host name are returned for
+each record, separated by spaces.
+.index MX record||in \%dnsdb%\ lookup
+For MX records, both the preference value and the host name are returned for
+each record, separated by a space. However, if you want only host names, you
+can use the pseudo-type MXH:
+.display asis
+${lookup dnsdb{mxh=a.b.example}}
+.endd
+In this case, the preference values are omitted.
+
+.index name server||for enclosing domain
+Another pseudo-type is ZNS (for `zone NS'). 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:
+.display asis
+${lookup dnsdb{zns=xxx.quercite.com}}
+${lookup dnsdb{zns=xxx.edu}}
+.endd
+Assuming that in each case there are no NS records for the full domain name,
+the first returns the name servers for \quercite.com\, and the second returns
+the name servers for \edu\.
+
+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 \com\ or \co.uk\ are not going to be on such
+a list.
+
+.nem
+.em
+.section Multiple dnsdb lookups
+In the previous section, \%dnsdb%\ lookups for a single domain are described.
+However, you can specify a list of domains or IP addresses in a single
+\%dnsdb%\ 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:
+.display asis
+${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}}
+.endd
+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.
+
+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.
+
+The \%dnsdb%\ 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
+an optional keyword followed by a comma that may appear before the record
+type. The possible keywords are `defer@_strict', `defer@_never', and
+`defer@_lax'. With `strict' behaviour, any temporary DNS error causes the
+whole lookup to defer. With `never' behaviour, a temporary DNS error is
+ignored, and the behaviour is as if the DNS lookup failed to find anything.
+With `lax' 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 `lax', so the following lookups are equivalent:
+.display asis
+${lookup dnsdb{defer_lax,a=one.host.com:two.host.com}}
+${lookup dnsdb{a=one.host.com:two.host.com}}
+.endd
+Thus, in the default case, as long as at least one of the DNS lookups
+yields some data, the lookup succeeds.
+.nem
.section More about LDAP
.index LDAP||quoting
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
+within an LDAP query, two different kinds of quoting are required. For this
reason, there are two different LDAP-specific quoting operators.
The \quote@_ldap\ operator is designed for use on strings that are part of
before any trailing spaces. (These rules are in RFC 2253.) The resulting string
is then quoted according to the rules for URLs. For example:
.display asis
-${quote_ldap_dn: a(bc)*, a<yz>; }
+${quote_ldap_dn: a(bc)*, a<yz>; }
.endd
yields
.display asis
.display asis
\ a(bc)*\, a\<yz\>\;\
.endd
-There are some further comments about quoting in the section on LDAP
+There are some further comments about quoting in the section on LDAP
authentication below.
.section LDAP connections
Using a pathname with \"ldap"\ or \"ldaps"\ forces the use of the Unix domain
interface.
.nextp
-Using \"ldapi"\ with a host name causes an error.
+Using \"ldapi"\ with a host name causes an error.
.endp
Using \"ldapi"\ with no host or path in the query, and no setting of
be preceded by any number of `<<name>>=<<value>>' 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:
+them. The following names are recognized:
.display
-CONNECT $rm{set a connection timeout}
-.newline
DEREFERENCE $rm{set the dereferencing parameter}
+.newline
+.em
+NETTIME $rm{set a timeout for a network operation}
+.nem
+.newline
USER $rm{set the DN, for authenticating the LDAP bind}
PASS $rm{set the password, likewise}
SIZE $rm{set the limit for the number of entries returned}
TIME $rm{set the maximum waiting time for a query}
.endd
-The value of the \\DEREFERENCE\\ parameter must be one of the words `never',
+The value of the \\DEREFERENCE\\ parameter must be one of the words `never',
`searching', `finding', or `always'.
+.em
+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
+\*ldap@_result()*\ 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 `no timeout' for
+Netscape SDK; for OpenLDAP no action is taken.
+
+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.
+.nem
+
Here is an example of an LDAP query in an Exim lookup that uses some of these
values. This is a single line, folded for ease of reading:
.display asis
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.
-The time limit for connection is given in seconds; zero means use the default.
-This facility is available in Netscape SDK 4.1; it may not be available in
-other LDAP implementations. Exim uses the given value if
-\\LDAP@_X@_OPT@_CONNECT@_TIMEOUT\\ is defined in the LDAP headers.
-
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
It makes it possible to use the same \quote@_ldap@_dn\ expansion for \\USER=\\
DNs as with DNs inside actual queries.
.nextp
-It permits spaces inside \\USER=\\ DNs.
+It permits spaces inside \\USER=\\ DNs.
.endp
For example, a setting such as
.display asis
.endd
should work even if \$1$\ contains spaces.
-Expanded data for the \\PASS=\\ value should be quoted using the \quote\
-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
+Expanded data for the \\PASS=\\ value should be quoted using the \quote\
+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:
.display asis
PASS=${quote:$3}
.endd
The \%ldap%\ lookup type generates an error if more than one entry matches the
-search filter, whereas \%ldapm%\ 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 \%ldap%\ and \%ldapm%\, but in the former case you
-know that whatever values are returned all came from a single entry in the
+search filter, whereas \%ldapm%\ 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 \%ldap%\ and \%ldapm%\, but in the former case
+you know that whatever values are returned all came from a single entry in the
directory.
In the common case where you specify a single attribute in your LDAP query, the
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.
-
+.em
+\**Warning**\: 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.
+.nem
.section Special PostgreSQL features
.section Expansion of lists
.index expansion||of lists
-Each list is expanded as a single string before it is used. If the 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.
+.em
+Each list is expanded as a single string before it is used. 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 ~~SECTlistconstruct and
+~~SECTempitelis for details of the list syntax; the second of these discusses
+the way you specify empty list items.
+.nem
+
+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.
If an item in a list is a regular expression, backslashes, dollars and possibly
other special characters in the expression must be protected against
\"@\N"\, whereas the second uses the expansion to obtain a list of unwanted
senders based on the receiving domain.
-After expansion, the list is split up into separate items for matching.
-Normally, colon is used as the separator character, but this can be varied if
-necessary, as described in section ~~SECTlistconstruct.
.section Negated items in lists
list is negative. In other words, a list that ends with a negative item behaves
as if it had an extra item \":*"\ on the end.
-Another way of thinking about positive and negative items in lists is to read
-the connector as `or' after a positive item and as `and' after a negative
-item.
+Another way of thinking about positive and negative items in lists is to read
+the connector as `or' after a positive item and as `and' after a negative
+item.
.section File names in lists
non-constant pattern. This is not the case. The keys in an \%lsearch%\ file are
always fixed strings, just as for any other single-key lookup type.
-If you want to use a file to contain wild-card patterns that form part of a
+If you want to use a file to contain wild-card patterns that form part of a
list, just give the file name on its own, without a search type, as described
in the previous section.
.display asis
domainlist dom2 = !a.b : *.b
.endd
-where \*x.y*\ does not match. It's best to avoid negation altogether in
+where \*x.y*\ does not match. It's best to avoid negation altogether in
referenced lists if you can.
Named lists may have a performance advantage. When Exim is routing an
domains = +local_domains
.endd
on several of your routers
-or in several ACL statements,
+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
.endd
-.em
.section Named list caching
.index list||caching of named
.index caching||named lists
.endd
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.
-.nem
.section Domain lists
The following types of item may appear in domain lists:
.numberpars $.
.index primary host name
-.index host||name, matched in domain list
+.index host||name, matched in domain list
.index \primary@_hostname\
.index domain list||matching primary host name
.index @@ in a domain list
.index domain literal
If a pattern consists of the string \"@@[]"\ it matches any local IP interface
address, enclosed in square brackets, as in an email address that contains a
-domain literal.
-.em
+domain literal.
In today's Internet, the use of domain literals is controversial.
-.nem
.nextp
.index @@mx@_any
.index @@mx@_primary
but a secondary MX target is. `Primary' means an MX record with the lowest
preference value -- there may of course be more than one of them.
-.em
-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 \*not*\ be expanded by adding the
-resolver's default domain. See the \qualify@_single\ and \search@_parents\
+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 \*not*\ be expanded by adding the
+resolver's default domain. See the \qualify@_single\ and \search@_parents\
options of the \%dnslookup%\ router for a discussion of domain widening.
Sometimes you may want to ignore certain IP addresses when using one of these
patterns. You can specify this by following the pattern with \"/ignore=<<ip
list>>"\, where <<ip list>> is a list of IP addresses. These addresses are
-ignored when processing the pattern (compare the \ignore@_target@_hosts\ option
+ignored when processing the pattern (compare the \ignore@_target@_hosts\ option
on a router). For example:
.display asis
domains = @mx_any/ignore=127.0.0.1
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.
-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
+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.
Because the list of IP addresses is a sublist within a domain list, you have to
domains = <? @mx_any/ignore=<;127.0.0.1;::1 ? \
an.other.domain ? ...
.endd
-.nem
.nextp
.index asterisk||in domain list
This typically causes a forward DNS lookup of the name. The result is compared
with the IP address of the subject host.
-.em
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
+lookup, a temporary error occurs. For example, if the list is being used in an
ACL condition, the ACL gives a `defer' 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 ~~SECTbehipnot below.
-.nem
.nextp
.index @@ in a host list
host under the given mask.
This allows, an entire network of hosts to be included (or excluded) by a
single item.
-.index CIDR notation
+.index CIDR notation
The mask uses CIDR notation; it specifies the number of address bits that must
match, starting from the most significant end of the address.
.display asis
192.168.23.236/31
.endd
-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 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.
Here is another example which shows an IPv4 and an IPv6 network:
.rset SECThoslispatnam "~~chapter.~~section"
.index host||lookup failures
.index unknown host name
-.index host list||matching host name
+.index host list||matching host name
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 the section ~~SECThoslispatip above.)
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.
-.em
+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
There are some options that control what happens if a host name cannot be
found. These are described in section ~~SECTbehipnot below.
-.nem
.index host||alias for
.display asis
sender_unqualified_hosts = \N^(a|b)\.c\.d$\N : ....
.endd
-.em
-\**Warning**\: If you want to match a complete host name, you must include the
-\"@$"\ 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
+\**Warning**\: If you want to match a complete host name, you must include the
+\"@$"\ 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.
-.nem
.endp
-.em
.section Behaviour when an IP address or name cannot be found
.rset SECTbehipnot "~~chapter.~~section"
.index host||lookup failures
-While processing a host list, Exim may need to look up an IP address from a
-name (see section ~~SECThoslispatip), or it may need to look up a host name
-from an IP address (see section ~~SECThoslispatnam). In either case, the
+While processing a host list, Exim may need to look up an IP address from a
+name (see section ~~SECThoslispatip), or it may need to look up a host name
+from an IP address (see section ~~SECThoslispatnam). In either case, the
behaviour when it fails to find the information it is seeking is the same.
.index \"+include@_unknown"\
rejects connections from any host whose name matches \"*.enemy.ex"\, and also
any hosts whose name it cannot find.
.nextp
-If any item that follows \"+ignore@_unknown"\ requires information that cannot
-be found, Exim ignores that item and proceeds to the rest of the list. For
+If any item that follows \"+ignore@_unknown"\ requires information that cannot
+be found, Exim ignores that item and proceeds to the rest of the list. For
example:
.display asis
accept hosts = +ignore_unknown : friend.example : \
192.168.4.5
.endd
-accepts from any host whose name is \*friend.example*\ and from 192.168.4.5,
-whether or not its host name can be found. Without \"+ignore@_unknown"\, if no
+accepts from any host whose name is \*friend.example*\ and from 192.168.4.5,
+whether or not its host name can be found. Without \"+ignore@_unknown"\, if no
name can be found for 192.168.4.5, it is rejected.
.endp
Both \"+include@_unknown"\ and \"+ignore@_unknown"\ may appear in the same
-list. The effect of each one lasts until the next, or until the end of the
+list. The effect of each one lasts until the next, or until the end of the
list.
\**Note**\: This section applies to permanent lookup failures. It does \*not*\
apply to temporary DNS errors. They always cause a defer action.
-.nem
.section Host list patterns for single-key lookups by host name
hosts_lookup = pgsql;\
select ip from hostlist where ip='$sender_host_address'
.endd
-The value of \$sender@_host@_address$\ for an IPv6 address uses colon
-separators. You can use the \sg\ expansion item to change this if you need to.
-If you want to use masked IP addresses in database queries, you can use the
-\mask\ expansion operator.
+The value of \$sender@_host@_address$\ for an IPv6 address contains colons. You
+can use the \sg\ expansion item to change this if you need to. If you want to
+use masked IP addresses in database queries, you can use the \mask\ expansion
+operator.
-If the query contains a reference to \$sender@_host@_name$\, Exim automatically
+If the query contains a reference to \$sender@_host@_name$\, Exim automatically
looks up the host name if has not already done so. (See section
~~SECThoslispatnam for comments on finding host names.)
-Historical note: prior to release 4.30, Exim would always attempt to find a
+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
-\"net-"\. This is no longer the case. For backwards compatibility, \"net-"\ is
+\"net-"\. This is no longer the case. For backwards compatibility, \"net-"\ is
still recognized for query-style lookups, but its presence or absence has no
-effect. (Of course, for single-key lookups, \"net-"\ $it{is} important.)
+effect. (Of course, for single-key lookups, \"net-"\ $it{is} important.
+See section ~~SECThoslispatsikey.)
.section Mixing wildcarded host names and addresses in host lists
.endd
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.
+detected by a regular expression that matches an empty string,
+.em
+and by a query-style lookup that succeeds when \$sender@_address$\ is empty.
-The following kinds of pattern are supported in address lists:
+The following kinds of address list pattern can match any address, including
+the empty address that is characteristic of bounce message senders:
+.nem
.numberpars $.
-.index regular expressions||in address list
-.index address list||regular expression in
+.em
+As explained above, if a pattern item is empty, it matches the empty address
+(and no others).
+.nem
+.nextp
+.index regular expressions||in address list
+.index address list||regular expression in
If (after expansion) a pattern starts with `@^', 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
The \"@\N"\ sequences are removed by the expansion, so the item does start
with `@^' by the time it is being interpreted as an address pattern.
.nextp
+.index address list||lookup for complete address
+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:
+.display asis
+deny senders = cdb;/etc/blocked.senders : \
+ mysql;select address from blocked where \
+ address='${quote_mysql:$sender_address}'
+.endd
+.em
+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.
+
+.nem
+Partial matching for single-key lookups (section ~~SECTpartiallookup) cannot be
+used, and is ignored if specified, with an entry being written to the panic
+log.
+.index @*@@ with single-key lookup
+However, you can configure lookup defaults, as described in section
+~~SECTdefaultvaluelookups, but this is useful only for the `$*$@@' type of
+default. For example, with this lookup:
+.display asis
+accept senders = lsearch*@;/some/file
+.endd
+the file could contains lines like this:
+.display asis
+user1@domain1.example
+*@domain2.example
+.endd
+and for the sender address \*nimrod@@jaeger.example*\, the sequence of keys
+that are tried is:
+.display asis
+nimrod@jaeger.example
+*@jaeger.example
+*
+.endd
+\**Warning 1**\: Do not include a line keyed by `$*$' in the file, because that
+would mean that every address matches, thus rendering the test useless.
+
+\**Warning 2**\: Do not confuse these two kinds of item:
+.display asis
+deny recipients = dbm*@;/some/file
+deny recipients = *@dbm;/some/file
+.endd
+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.
+.endp
+
+
+.em
+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.
+.nem
+
+.numberpars $.
.index @@@@ with single-key lookup
.index address list||@@@@ lookup type
.index address list||split local part and domain
-If a pattern starts with `@@@@' followed by a single-key lookup item
+If a pattern starts with `@@@@' followed by a single-key lookup item
(for example, \"@@@@lsearch;/some/file"\), 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
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.
.nextp
-The @@@@<<lookup>> style of item can also be used with a query-style
-lookup, but in this case, the chaining facility is not available. The lookup
+The @@@@<<lookup>> 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.
.nextp
-.index address list||lookup for complete address
-Complete addresses can be looked up by using a pattern that
-starts with a lookup type terminated by a semicolon, follwed by the data for
-the lookup.
-For example:
-.display asis
-deny senders = cdb;/etc/blocked.senders : \
- mysql;select address from blocked where \
- address='${quote_mysql:$sender_address}'
-.endd
-For a single-key lookup type, Exim uses the complete address as the key.
-Partial matching (section ~~SECTpartiallookup) cannot be used, and is ignored
-if specified, with an entry being written to the panic log.
-
-.index @*@@ with single-key lookup
-You can configure lookup defaults, as described in section
-~~SECTdefaultvaluelookups, but this is useful only for the `$*$@@' type of
-default. For example, with this lookup:
-.display asis
-accept senders = lsearch*@;/some/file
-.endd
-the file could contains lines like this:
-.display asis
-user1@domain1.example
-*@domain2.example
-.endd
-and for the sender address \*nimrod@@jaeger.example*\, the sequence of keys
-that are tried is:
-.display asis
-nimrod@jaeger.example
-*@jaeger.example
-*
-.endd
-\**Warning 1**\: Do not include a line keyed by `$*$' in the file, because that
-would mean that every address matches, thus rendering the test useless.
-
-\**Warning 2**\: Do not confuse these two kinds of item:
-.display asis
-deny recipients = dbm*@;/some/file
-deny recipients = *@dbm;/some/file
-.endd
-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 the next paragraph.
-.nextp
-If a pattern contains an @@ character, but is not a regular expression
-and does not begin with a lookup type
-as described above, 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:
+If a pattern contains an @@ character, but is not a regular expression and does
+not begin with a lookup type as described above, 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:
.display asis
deny senders = *@*.spamming.site:\
*@+hostile_domains:\
specified using a regular expression, because otherwise the exclamation mark is
treated as a sign of negation.
.nextp
-If a pattern is not one of the above syntax forms, that is, if a pattern which
-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 \"*@@"\
-preceded the pattern.
+If a pattern is not one of the above syntax forms, that is, if a
+.em
+non-empty
+.nem
+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
+\"*@@"\ preceded the pattern.
.endp
\**Warning**\: there is an important difference between the address list items
When a string is being expanded it is copied verbatim from left to right except
when a dollar or backslash character is encountered. A dollar specifies the
start of a portion of the string which is interpreted and replaced as described
-below in section ~~SECTexpansionitems onwards. Backslash is used as an escape
+below in section ~~SECTexpansionitems onwards. Backslash is used as an escape
character, as described in the following section.
using \-be-\ for reading files to which they do not have access.
+.em
+.section Forced expansion failure
+.rset SECTforexpfai "~~chapter.~~section"
+.index expansion||forced failure
+A number of expansions that are described in the following section have
+alternative `true' and `false' substrings, enclosed in curly brackets. Which
+one is used depends on some condition that is evaluated as part of the
+expansion. If, instead of a `false' substring, the word `fail' is used (not in
+curly brackets), the entire string expansion fails in a way that can be
+detected by the code that requested the expansion. This is called `forced
+expansion failure', 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.
+.nem
+
+
.section Expansion items
.rset SECTexpansionitems "~~chapter.~~section"
The following items are recognized in expanded strings. White space may be used
.item "@$@{extract@{<<key>>@}@{<<string1>>@}@{<<string2>>@}@{<<string3>>@}@}"
.index expansion||extracting substrings by key
-The key and <<string1>> are first expanded separately.
-Leading and trailing whitespace is removed from the key (but not from any of
+The key and <<string1>> are first expanded separately.
+Leading and trailing whitespace is removed from the key (but not from any of
the strings).
The key must not consist entirely of digits. The expanded <<string1>> must be
of the form:
.display
@$@{extract@{Z@}@{A=... B=...@}@{@$value@} fail @}
.endd
-@{<<string2>>@} must be present for `fail' to be recognized. When this syntax
-is used, if the extraction fails, the entire string expansion fails in a way
-that can be detected by the code in Exim which requested the expansion. This is
-called `forced expansion failure', 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 which is expanded.
+This forces an expansion failure (see section ~~SECTforexpfai); @{<<string2>>@}
+must be present for `fail' to be recognized.
.item "@$@{extract@{<<number>>@}@{<<separators>>@}@{<<string1>>@}@{<<string2>>@}@{<<string3>>@}@}"
.index expansion||extracting substrings by number
The <<number>> argument must consist entirely of decimal digits,
-apart from leading and trailing whitespace, which is ignored.
+apart from leading and trailing whitespace, which is ignored.
This is what distinguishes this form of \extract\ from the previous kind. It
behaves in the same way, except that, instead of extracting a named field, it
extracts from <<string1>> the field whose number is given as the first
.item "@$@{hash@{<<string1>>@}@{<<string2>>@}@{<<string3>>@}@}"
.index hash function||textual
.index expansion||textual hash
-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
+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.
-The first two strings, after expansion, must be numbers. Call them <<m>> and
-<<n>>. If you are using fixed values for these numbers, that is, if <<string1>>
+The first two strings, after expansion, must be numbers. Call them <<m>> and
+<<n>>. If you are using fixed values for these numbers, that is, if <<string1>>
and <<string2>> do not change when they are expanded, you can use the
simpler operator notation that avoids some of the braces:
.display
.endd
The second number is optional (in both notations).
-If <<n>> is greater than or equal to the length of the string, the expansion
+If <<n>> 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 <<n>> by
applying a hashing function to the string. The new string consists of
characters taken from the first <<m>> characters of the string
If <<m>> is not present the value 26 is used, so that only lower case
letters appear. For example:
.display
-@$@{hash@{3@}@{monty@}@} $rm{yields} \"jmg"\
-@$@{hash@{5@}@{monty@}@} $rm{yields} \"monty"\
-@$@{hash@{4@}@{62@}@{monty python@}@} $rm{yields} \"fbWx"\
+@$@{hash@{3@}@{monty@}@} $rm{yields} \"jmg"\
+@$@{hash@{5@}@{monty@}@} $rm{yields} \"monty"\
+@$@{hash@{4@}@{62@}@{monty python@}@} $rm{yields} \"fbWx"\
.endd
.endd
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.
+lines) may be present.
-The difference between \rheader\, \bheader\, and \header\ is in the way the
-data in the header line is interpreted.
+The difference between \rheader\, \bheader\, and \header\ is in the way the
+data in the header line is interpreted.
.numberpars $.
+.index whitespace||in header lines
\rheader\ gives the original `raw' content of the header line, with no
processing at all, and without the removal of leading and trailing whitespace.
.nextp
\bheader\ removes leading and trailing whitespace, and then decodes base64 or
quoted-printable MIME `words' within the header text, but does no character
set translation. If decoding of what looks superficially like a MIME `word'
-fails, the raw string is returned.
+fails, the raw string is returned.
.index binary zero||in header line
If decoding 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
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
+message, and any that are added by
an ACL \warn\ 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.
white space terminates the header name, it 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 \def\ condition in section ~~SECTexpcond
-for a means of testing for the existence of a header.)
+for a means of testing for the existence of a header.)
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. A newline
.index expansion||hmac hashing
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.
+RFC 2104.
This differs from \"@$@{md5:secret@_text...@}"\ or
-\"@$@{sha1:secret@_text...@}"\ in that the hmac step adds a signature to the
-cryptographic hash, allowing for authentication that is not possible with MD5
+\"@$@{sha1:secret@_text...@}"\ 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 \"md5"\ or \"sha1"\ at present. For
example:
{${primary_hostname},${message_id},$h_message-id:}}
.endd
Then given a message, you can check where it was scanned by looking at the
-::X-Spam-Scanned:: header line. If you know the secret, you can check that this
-header line is authentic by recomputing the authentication code from the host
+::X-Spam-Scanned:: 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 ::Message-id:: header line. This can be done using
Exim's \-be-\ option, or by other means, for example by using the
\*hmac@_md5@_hex()*\ function in Perl.
-
.item "@${if <<condition>> @{<<string1>>@}@{<<string2>>@}@}"
.index expansion||conditional
If <<condition>> is true, <<string1>> is expanded and replaces the whole item;
-otherwise <<string2>> is used. For example,
+otherwise <<string2>> is used. The available conditions are described in
+section ~~SECTexpcond below. For example:
.display asis
${if eq {$local_part}{postmaster} {yes}{no} }
.endd
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 `fail' 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. The
-available conditions are described in section ~~SECTexpcond below.
+case, the expansion is forced to fail if the condition is not true (see section
+~~SECTforexpfai).
+
+.em
+If both strings are omitted, the result is the string \"true"\ 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
+.display asis
+condition = ${if >{$acl_m4}{3}{true}{false}}
+.endd
+you can use
+.display asis
+condition = ${if >{$acl_m4}{3}}
+.endd
+.nem
.item "@$@{length@{<<string1>>@}@{<<string2>>@}@}"
.index expansion||string truncation
-The \length\ item is used to extract the initial portion of a string. Both
+The \length\ item is used to extract the initial portion of a string. Both
strings are expanded, and the first one must yield a number, <<n>>, say. If you
are using a fixed value for the number, that is, if <<string1>> does not change
when expanded, you can use the simpler operator notation that avoids some of
@$@{length@_<<n>>:<<string>>@}
.endd
The result of this item is either the first <<n>> characters or the whole
-of <<string2>>, whichever is the shorter. Do not confuse \length\ with
+of <<string2>>, whichever is the shorter. Do not confuse \length\ with
\strlen\, which gives the length of a string.
During its expansion, the variable \$value$\ 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, <<string2>> is expanded and replaces
-the entire item. If @{<<string2>>@} is omitted, the replacement is null on
-failure. Alternatively, <<string2>> can itself be a nested lookup, thus
-providing a mechanism for looking up a default value when the original lookup
-fails.
+the entire item. If @{<<string2>>@} is omitted, the replacement is the empty
+string on failure. If <<string2>> is provided, it can itself be a nested
+lookup, thus providing a mechanism for looking up a default value when the
+original lookup fails.
If a nested lookup is used as part of <<string1>>, \$value$\ contains the data
for the outer lookup while the parameters of the second lookup are expanded,
lookup fail.
Instead of @{<<string2>>@} the word `fail' can appear, and in this case, if the
-lookup fails, the entire expansion is forced to fail. If both @{<<string1>>@}
-and @{<<string2>>@} are omitted, the result is the looked up value in the case
-of a successful lookup, and nothing in the case of failure.
+lookup fails, the entire expansion is forced to fail (see section
+~~SECTforexpfai). If both @{<<string1>>@} and @{<<string2>>@} are omitted, the
+result is the looked up value in the case of a successful lookup, and nothing
+in the case of failure.
For single-key lookups, the string `partial' is permitted to precede the
search type in order to do partial matching, and $*$ or $*$@@ may follow a
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
+additional arguments need be given; the maximum number permitted, including the
name of the subroutine, is nine.
The return value of the subroutine is inserted into the expanded string, unless
the return value is \undef\. In that case, the expansion fails in the same way
-as an explicit `fail' on a lookup item.
-The return value is a scalar. Whatever you return is evaluated in a scalar
+as an explicit `fail' 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.
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 \expand\ operator. If the file cannot be read, the
+String expansion is not applied to the contents of the file. If you want this,
+you must wrap the item in an \expand\ operator. If the file cannot be read, the
string expansion fails.
The \%redirect%\ router has an option called \forbid@_filter@_readfile\ which
locks out the use of this expansion item in filter files.
.item "@$rheader@_<<header name>>:#$rm{or}#@$rh@_<<header name>>:"
-This item inserts `raw' header lines. It is described with the \header\
+This item inserts `raw' header lines. It is described with the \header\
expansion item above.
endif
.endd
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
+the return code is 127 -- the same code that shells use for non-existent
commands.
-\**Warning**\: In a router or transport, you cannot assume the order in which
-option values are expanded, except for those pre-conditions whose order of
-testing is documented. Therefore, you cannot reliably expect to set \$runrc$\
+\**Warning**\: In a router or transport, you cannot assume the order in which
+option values are expanded, except for those pre-conditions whose order of
+testing is documented. Therefore, you cannot reliably expect to set \$runrc$\
by the expansion of one option, and use it in another.
The \%redirect%\ router has an option called \forbid@_filter@_run\ which locks
${sg{1=A 4=D 3=C}{\N(\d+)=\N}{K\$1=}}
.endd
yields `K1=A K4=D K3=C'.
-Note the use of \"@\N"\ to protect the contents of the regular expression from
+Note the use of \"@\N"\ to protect the contents of the regular expression from
string expansion.
@$@{substr@_<<n>>@_<<m>>:<<string>>@}
.endd
The second number is optional (in both notations).
+.em
+If it is absent in the simpler format, the preceding underscore must also be
+omitted.
+.nem
The \substr\ item can be used to extract more general substrings than \length\.
The first number, <<n>>, is a starting offset, and <<m>> is the length
.endd
yields `1'.
-If the second number is omitted from \substr\, the remainder of the string is
-taken if the offset was positive. If it was negative, all characters in the
+When the second number is omitted from \substr\, the remainder of the string is
+taken if the offset is positive. If it is negative, all characters in the
string preceding the offset point are taken. For example, an offset of -1 and
-no length yields all but the last character of the string.
+no length, as in these semantically identical examples:
+.display asis
+${substr_-1:abcde}
+${substr{-1}{abcde}}
+.endd
+yields all but the last character of the string, that is, `abcd'.
zeros. \**Note**\: Just to be absolutely clear: this is \*not*\ base64
encoding.
-.em
.item "@$@{base62d:<<base-62 digits>>@}"
.index base62
.index expansion||conversion to base 62
The string must consist entirely of base-62 digits. The number is converted to
decimal and output as a string.
-.nem
.item "@$@{domain:<<string>>@}"
controlled by the \print@_topbitchars\ option.
-.em
.item "@$@{eval:<<string>>@}"
.item "@$@{eval10:<<string>>@}"
.index expansion||expression evaluation
the four basic operators (plus, minus, times, divide) and parentheses. All
operations are carried out using integer arithmetic. Plus and minus have a
lower priority than times and divide; operators with the same priority are
-evaluated from left to right.
+evaluated from left to right.
For \eval\, numbers may be decimal, octal (starting with `0') or hexadecimal
(starting with `0x'). For \eval10\, all numbers are taken as decimal, even if
they start with a leading zero. This can be useful when processing numbers
extracted from dates or times, which often do have leading zeros.
-.nem
A number may be followed by `K' or `M' to multiply it by 1024 or 1024$*$1024,
respectively. Negative numbers are supported. The result of the computation is
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
+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
+single-byte encoding (but thereby limited to 256 characters). This makes
translation from UTF-8 to ISO-8859-1 straightforward.
.item "@$@{hash@_<<n>>@_<<m>>:<<string>>@}"
.index hash function||textual
.index expansion||textual hash
-The \hash\ 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
+The \hash\ 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
.display
@$@{hash@{<<n>>@}@{<<m>>@}@{<<string>>@}@}
.item "@$@{hex2b64:<<hexstring>>@}"
.index base64 encoding||conversion from hex
.index expansion||hex to base64
-This operator converts a hex string into one that is base64 encoded. This can
+This operator converts a hex string into one that is base64 encoded. This can
be useful for processing the output of the MD5 and SHA-1 hashing functions.
.display
@$@{length@{<<number>>@}@{<<string>>@}@}
.endd
-See the description of the general \length\ item above for details. Note that
+See the description of the general \length\ item above for details. Note that
\length\ is not the same as \strlen\. The abbreviation \l\ can be used when
\length\ is used as an operator.
.item "@$@{quote:<<string>>@}"
.index quoting||in string expansions
.index expansion||quoting
-The \quote\ operator puts its argument into double quotes if it
+The \quote\ 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.
variable or a message header.
.item "@$@{quote@_local@_part:<<string>>@}"
-This operator is like \quote\, except that it quotes the string only if
-required to do so by the rules of RFC 2822 for quoting local parts. For
+This operator is like \quote\, 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 \quote\).
If you are creating a new email address from the contents of \$local@_part$\
(or any other unknown data), you should always use this operator.
.display asis
${quote_ldap:two * two}
.endd
-returns
+returns
.display asis
two%20%5C2A%20two
.endd
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
-\headers@_charset\ option, which defaults to ISO-8859-1.
-If the string contains only characters in the range 33--126, and no instances
-of the characters
+\headers@_charset\ option, which defaults to ISO-8859-1. If the string contains
+only characters in the range 33--126, and no instances of the characters
.display asis
-? = ( ) < > @ , ; : \ " . [ ] _
+? = ( ) < > @ , ; : \ " . [ ] _
.endd
-it is not modified. Otherwise, the result is the RFC 2047 encoding, as a single
-`coded word'.
+it is not modified. Otherwise, the result is the RFC 2047 encoding of the
+string,
+.em
+using as many `coded words' as necessary to encode all the characters.
+.nem
.item "@$@{sha1:<<string>>@}"
The string, after expansion, must be a file path. A call to the \*stat()*\
function is made for this path. If \*stat()*\ fails, an error occurs and the
expansion fails. If it succeeds, the data from the stat replaces the item, as a
-series of <<name>>=<<value>> pairs, where the values are all numerical,
+series of <<name>>=<<value>> pairs, where the values are all numerical,
except for the value of `smode'. The names are: `mode' (giving the mode as a
4-digit octal number), `smode' (giving the mode in symbolic format as a
10-character string, as for the \*ls*\ command), `inode', `device', `links',
incorrect on 32-bit systems for files larger than 2GB.
+.em
+.item "@$@{str2b64:<<string>>@}"
+.index expansion||base64 encoding
+.index base64 encoding||in string expansion
+This operator converts a string into one that is base64 encoded.
+.nem
+
+
.item "@$@{strlen:<<string>>@}"
.index expansion||string length
.index string||length in expansion
-The item is replace by the length of the expanded string, expressed as a
+The item is replace by the length of the expanded string, expressed as a
decimal number. \**Note**\: Do not confuse \strlen\ with \length\.
See the description of the general \substr\ item above for details. The
abbreviation \s\ can be used when \substr\ is used as an operator.
-.em
.item "@$@{time@_interval:<<string>>@}"
.index \time@_interval\
.index time interval||formatting
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,
\"1w3d4h2m6s"\.
-.nem
.item "@$@{uc:<<string>>@}"
.index case forcing in strings
.display asis
${if crypteq {test}{\{md5\}CY9rzUYh03PK3k6DJie09g==}{yes}{no}}
.endd
-The following encryption types
+The following encryption types
(whose names are matched case-independently)
are supported:
.numberpars $.
comparison fails.
.nextp
.index SHA-1 hash
-\@{sha1@}\ 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
+\@{sha1@}\ 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.
.nextp
.index \*crypt()*\
-\@{crypt@}\ calls the \*crypt()*\ function, which uses only the first eight
-characters of the password.
+\@{crypt@}\ calls the \*crypt()*\ function,
+.em
+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.
+.nem
.nextp
.index \*crypt16()*\
\@{crypt16@}\ calls the \*crypt16()*\ function (also known as \*bigcrypt()*\),
-which uses up to 16 characters of the password.
+which
+.em
+was orginally created to use up to 16 characters of the password. Again, in
+modern operating systems, more characters may be used.
+.nem
.endp
Exim has its own version of \*crypt16()*\ (which is just a double call to
\*crypt()*\). For operating systems that have their own version, setting
\\HAVE@_CRYPT16\\ in \(Local/Makefile)\ 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 \(Makefile)\ for those operating systems that are known to
+operating system version instead of its own. This option is set by default in
+the OS-dependent \(Makefile)\ for those operating systems that are known to
support \*crypt16()*\.
If you do not put any curly bracket encryption type in a \crypteq\ comparison,
.index string||comparison
.index expansion||string comparison
The two substrings are first expanded. The condition is true if the two
-resulting strings are identical: for \eq\ the comparison includes the case of
+resulting strings are identical: for \eq\ the comparison includes the case of
letters, whereas for \eqi\ the comparison is case-independent.
.item "exists @{<<file name>>@}"
This condition, which has no data, is true during a message's first delivery
attempt. It is false during any subsequent delivery attempts.
-.em
.item "ge @{<<string1>>@}@{<<string2>>@}"
.item "gei @{<<string1>>@}@{<<string2>>@}"
.index string||comparison
string is lexically greater than the second string: for \gt\ the comparison
includes the case of letters, whereas for \gti\ the comparison is
case-independent.
-.nem
.item "isip @{<<string>>@}" 8
.item "isip4 @{<<string>>@}"
.item "isip6 @{<<string>>@}"
.index IP address||testing string format
.index string||testing for IP address
-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 \isip\, whereas
-\isip4\ and \isip6\ test just for IPv4 or IPv6 addresses, respectively. For
+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 \isip\, whereas
+\isip4\ and \isip6\ test just for IPv4 or IPv6 addresses, respectively. For
example, you could use
-.display asis
+.display asis
${if isip4{$sender_host_address}...
.endd
to test which version of IP an incoming SMTP connection is using.
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
+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 ~~CHAPSMTPAUTH for details of SMTP authentication, and chapter
~~CHAPplaintext for an example of how this can be used.
-.em
.item "le @{<<string1>>@}@{<<string2>>@}"
.item "lei @{<<string1>>@}@{<<string2>>@}"
.index string||comparison
string is lexically less than the second string: for \lt\ the comparison
includes the case of letters, whereas for \lti\ the comparison is
case-independent.
-.nem
.item "match @{<<string1>>@}@{<<string2>>@}"
If the whole expansion string is in double quotes, further escaping of
backslashes is also required.
-The condition is true if the regular expression match succeeds.
-.em
-The regular expression is not required to begin with a circumflex
+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 \"@$"\
+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 \"@$"\
metacharacter at an appropriate point.
-.nem
.index numerical variables (\$1$\, \$2$\, etc)||in \if\ expansion
At the start of an \if\ expansion the values of the numeric variable
combination of conditions using \or\, the subsequent values of the numeric
variables are those of the condition that succeeded.
-.em
.item "match@_domain @{<<string1>>@}@{<<string2>>@}"
.item "match@_address @{<<string1>>@}@{<<string2>>@}"
.item "match@_local@_part @{<<string1>>@}@{<<string2>>@}"
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. At least, I haven't come
up with anything yet.
-.nem
.item "pam {<<string1>>:<<string2>>:...@}"
.index PAM authentication
in some releases of GNU/Linux \-ldl-\ is also needed.
The argument string is first expanded, and the result must be a colon-separated
-list of strings.
+list of strings.
Leading and trailing whitespace is ignored.
The PAM module is initialized with the service name `exim' and the user name
taken from the first item in the colon-separated data string (<<string1>>). The
Radius authentication (RFC 2865) is supported in a similar way to PAM. You must
set \\RADIUS@_CONFIG@_FILE\\ in \(Local/Makefile)\ to specify the location of
the Radius client configuration file in order to build Exim with Radius
-support.
+support.
+.em
+With just that one setting, Exim expects to be linked with the \radiusclient\
+library. You can also link Exim with the \libradius\ library that comes with
+FreeBSD. To do this, set
+.display asis
+RADIUS_LIB_TYPE=RADLIB
+.endd
+in \(Local/Makefile)\, in addition to setting \\RADIUS@_CONFIGURE@_FILE\\.
+.nem
You may also have to supply a suitable setting in \\EXTRALIBS\\ so that the
Radius library can be found when Exim is linked.
+
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
.rset SECTexpvar "~~chapter.~~section"
.index expansion||variables, list of
-The variables that are available for use in expansion strings are:
+.em
+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.
+.nem
.push
.indent 2em
-.tempindent 0
.index numerical variables (\$1$\, \$2$\, etc)
+.tempindent 0
\$0$\, \$1$\, etc: When a \match\ expansion condition succeeds, these
variables contain the captured substrings identified by the regular expression
during subsequent processing of the success string of the containing \if\
matching condition.
.tempindent 0
-\$acl@_c0$\ -- \$acl@_c9$\: Values can be placed in these variables by the
+\$acl@_c0$\ -- \$acl@_c9$\: Values can be placed in these variables by the
\set\ modifier in an ACL. The values persist throughout the lifetime of an SMTP
connection. They can be used to pass information between ACLs and different
-invocations of the same ACL.
+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
+message, and can be accessed by filters, routers, and transports during
subsequent delivery.
.tempindent 0
.tempindent 0
-\$acl@_verify@_message$\: During the expansion of the \message\ and
+\$acl@_verify@_message$\: During the expansion of the \message\ and
\log@_message\ modifiers in an ACL statement after an address verification has
failed, this variable contains the original failure message that will be
overridden by the expanded string.
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 ~~CHAProutergeneric for more details.
-\**Note**\: the contents of \$address@_data$\ are visible in user filter files.
+chapter ~~CHAProutergeneric for more details. \**Note**\: the contents of
+\$address@_data$\ are visible in user filter files.
-If \$address@_data$\ is set when the routers are called to verify an address
-from an ACL, the final value remains available in subsequent conditions in the
-ACL statement. If routing the address caused it to be redirected to a single
-address, the child address is also routed as part of the verification, and in
-this case the final value of \$address@_data$\ is from the child's routing.
+.em
+If \$address@_data$\ 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 \$address@_data$\ is
+from the child's routing.
+
+If \$address@_data$\ 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
+\$sender@_address@_data$\, to distinguish it from data from a recipient
+address.
+
+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.
+.nem
.tempindent 0
\$address@_file$\: When, as a result of aliasing, forwarding, or filtering, a
then when the \%address@_file%\ transport is running, \$address@_file$\
contains `/home/r2d2/savemail'.
.index Sieve filter||value of \$address@_file$\
-For Sieve filters, the value may be `inbox' or a relative folder name. It is
-then up to the transport configuration to generate an appropriate absolute path
+For Sieve filters, the value may be `inbox' or a relative folder name. It is
+then up to the transport configuration to generate an appropriate absolute path
to the relevant file.
.index \\AUTH\\||on \\MAIL\\ command
.tempindent 0
\$authenticated@_sender$\:
-.em
When acting as a server, Exim takes note of the \\AUTH=\\ parameter on an
incoming SMTP \\MAIL\\ command
-.nem
if it believes the sender is sufficiently trusted, as described in section
~~SECTauthparamail. Unless the data is the string `@<@>', it is set as the
authenticated sender of the message, and the value is available during delivery
.index authentication||failure
.tempindent 0
-\$authentication@_failed$\:
+\$authentication@_failed$\:
This variable is set to `1' in an Exim server if a client issues an \\AUTH\\
command that does not succeed. Otherwise it is set to `0'. This makes it
possible to distinguish between `did not try to authenticate'
.index body of message||binary zero count
.index binary zero||in message body
.tempindent 0
-.em
\$body@_zerocount$\:
When a message is being received or delivered, this variable contains the
number of binary zero bytes in the message's body.
-.nem
.tempindent 0
\$bounce@_recipient$\:
.index gid (group id)||caller
.tempindent 0
-\$caller@_gid$\: The
-.em
-real
-.nem
+\$caller@_gid$\: 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 \$originator@_gid$\). If Exim re-execs itself, this variable in the new
.index uid (user id)||caller
.tempindent 0
-\$caller@_uid$\: The
-.em
+\$caller@_uid$\: The
real
-.nem
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 \$originator@_uid$\). If Exim re-execs itself, this variable in the new
of times it has been compiled. This serves to distinguish different
compilations of the same version of the program.
+.em
+.tempindent 0
+\$demime@_errorlevel$\: This variable is available when Exim is compiled with
+the content-scanning extension and the obsolete \demime\ condition. For
+details, see section ~~SECTdemimecond.
+
+.tempindent 0
+\$demime@_reason$\: This variable is available when Exim is compiled with the
+content-scanning extension and the obsolete \demime\ condition. For details,
+see section ~~SECTdemimecond.
+.nem
+
.index black list (DNS)
.tempindent 0
\$dnslist@_domain$\: When a client host is found to be on a DNS (black) list,
.tempindent 0
\$dnslist@_value$\: When a client host is found to be on a DNS (black) list,
the IP address from the resource record is placed in this variable.
-If there are multiple records, all the addresses are included, comma-space
+If there are multiple records, all the addresses are included, comma-space
separated.
.tempindent 0
.numberpars $.
When an ACL is running for a \\RCPT\\ command, \$domain$\ contains the domain
of the recipient address.
-\**Note:**\ the domain of the sender address is in \$sender@_address@_domain$\
-at \\MAIL\\ time and at \\RCPT\\ time. \$domain$\ is not set for the \\MAIL\\
+\**Note:**\ the domain of the sender address is in \$sender@_address@_domain$\
+at \\MAIL\\ time and at \\RCPT\\ time. \$domain$\ is not set for the \\MAIL\\
ACL.
.nextp
When a rewrite item is being processed (see chapter ~~CHAPrewrite), \$domain$\
of the router as \$domain@_data$\. 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.
+used.
-\$domain@_data$\ is also set when the \domains\ condition in an ACL matches a
-domain by means of a lookup. The data read by the lookup is available during
+\$domain@_data$\ is also set when the \domains\ 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.
-.em
.tempindent 0
\$exim@_gid$\: This variable contains the numerical value of the Exim group id.
.tempindent 0
\$exim@_uid$\: This variable contains the numerical value of the Exim user id.
+
+.em
+.tempindent 0
+\$found@_extension$\: This variable is available when Exim is compiled with the
+content-scanning extension and the obsolete \demime\ condition. For details,
+see section ~~SECTdemimecond.
.nem
.tempindent 0
\$host@_address$\:
This variable is set to the remote host's IP address whenever \$host$\ is set
for a remote connection.
+.em
+It is also set to the IP address that is being checked when the
+\ignore@_target@_hosts\ option is being processed.
+.nem
.tempindent 0
\$host@_data$\:
message = $host_data
.endd
+.em
.index host||name lookup, failure of
.tempindent 0
-\$host@_lookup@_failed$\:
-This variable contains `1' if the message came from a remote host and there was
-an attempt to look up the host's name from its IP address, but the attempt
-failed. Otherwise the value of the variable is `0'.
-.em
-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 \$host@_lookup@_failed$\ is set to
-`1'. 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.
+\$host@_lookup@_deferred$\:
+This variable normally contains `0', as does \$host@_lookup@_failed$\. 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 `1'.
+.numberpars $.
+If the lookup receives a definite negative response (for example, a DNS lookup
+succeeded, but no records were found), \$host@_lookup@_failed$\ is set to `1'.
+.nextp
+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), \$host@_lookup@_deferred$\ is set to `1'.
+.endp
+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
+\$host@_lookup@_failed$\ is set to `1'. 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 \$host@_lookup@_deferred$\ is set to
+`1'. See also \$sender@_host@_name$\.
+
+.tempindent 0
+\$host@_lookup@_failed$\: See \$host@_lookup@_deferred$\.
.nem
.tempindent 0
\$interface@_address$\:
When a message is received over a TCP/IP connection, this variable contains the
address of the local IP interface. See also the \-oMi-\ command line option.
-This variable can be used in ACLs and also, for example, to make the file name
+This variable can be used in ACLs and also, for example, to make the file name
for a TLS certificate depend on which interface is being used.
.tempindent 0
\$interface@_port$\:
When a message is received over a TCP/IP connection, this variable contains the
local port number. See also the \-oMi-\ command line option.
-This variable can be used in ACLs and also, for example, to make the file name
+This variable can be used in ACLs and also, for example, to make the file name
for a TLS certificate depend on which port is being used.
.tempindent 0
\$ldap@_dn$\:
-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
+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.
-
.tempindent 0
\$load@_average$\:
-This variable contains the system load average, multiplied by 1000 to that it
-is an integer. For example, if the load average is 0.21, the value of the
+This variable contains the system load average, multiplied by 1000 to 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.
.tempindent 0
.display asis
data = ${quote_local_part:$local_part}@new.domain.example
.endd
-.em
-\**Note**\: The value of \$local@_part$\ is normally lower cased. If you want
-to process local parts in a case-dependent manner in a router, you can set the
+\**Note**\: The value of \$local@_part$\ is normally lower cased. If you want
+to process local parts in a case-dependent manner in a router, you can set the
\caseful@_local@_part\ option (see chapter ~~CHAProutergeneric).
-.nem
.tempindent 0
\$local@_part@_data$\:
values in these variables are \"(uid@_t)(-1)"\ and \"(gid@_t)(-1)"\,
respectively.
-
.tempindent 0
\$localhost@_number$\: This contains the expanded value of the
\localhost@_number\ option. The expansion happens after the main options have
been read.
+.em
+.tempindent 0
+\$log@_inodes$\: 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 \check@_log@_inodes\ option.
+
+.tempindent 0
+\$log@_space$\: 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 \check@_log@_space\ option.
+.nem
+
.tempindent 0
-\$mailstore@_basename$\: This variable is set only when doing deliveries in
-`mailstore' format in the \%appendfile%\ transport. During the expansion of the
-\mailstore@_prefix\, \mailstore@_suffix\, \message__prefix\, and
+\$mailstore@_basename$\: This variable is set only when doing deliveries in
+`mailstore' format in the \%appendfile%\ transport. During the expansion of the
+\mailstore@_prefix\, \mailstore@_suffix\, \message__prefix\, and
\message@_suffix\ options, it contains the basename of the files that are being
written, that is, the name without the `.tmp', `.env', or `.msg' suffix. At all
other times, this variable is empty.
+.em
+.tempindent 0
+\$malware@_name$\: 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 \malware\ condition is true (see section ~~SECTscanvirus).
+.nem
+
.index message||age of
.tempindent 0
\$message@_age$\: This variable is set at the start of a delivery attempt to
.index body of message||size
.index message||body, size
.tempindent 0
-\$message@_body@_size$\: When a message is being processed, this variable
+\$message@_body@_size$\: 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 \$message@_size$\ and \$body@_linecount$\.
+included in the count. See also \$message@_size$\, \$body@_linecount$\, and
+\$body@_zerocount$\.
.tempindent 0
\$message@_headers$\:
lines are separated by newline characters.
.tempindent 0
-\$message@_id$\:
+\$message@_id$\:
When a message is being received or delivered, this variable contains the
unique message id that is used by Exim to identify the message.
-An id is not created for a message until after its header has been
+An id is not created for a message until after its header has been
successfully received.
-.em
-\**Note**\: This is \*not*\ the contents of the ::Message-ID:: header line; it
-is the local id that Exim assigns to the message, for example:
+\**Note**\: This is \*not*\ the contents of the ::Message-ID:: header line; it
+is the local id that Exim assigns to the message, for example:
\"1BXTIK-0001yO-VA"\.
-.nem
.index size||of message
.index message||size
.tempindent 0
-\$message@_size$\:
+\$message@_size$\:
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 ::Envelope-to::) that are added to individual
expansion of the \maildir@_tag\ option in the \%appendfile%\ transport while
doing a delivery in maildir format, the value of \$message@_size$\ is the
precise size of the file that has been written. See also
-\$message@_body@_size$\ and \$body@_linecount$\.
+\$message@_body@_size$\, \$body@_linecount$\, and \$body@_zerocount$\.
.index \\RCPT\\||value of \$message@_size$\
While running an ACL at the time of an SMTP \\RCPT\\ command, \$message@_size$\
-contains the size supplied on the \\MAIL\\ command, or
+contains the size supplied on the \\MAIL\\ command, or
-1
if no size was given. The value may not, of course, be truthful.
+.em
+.tempindent 0
+\$mime@_$\\*xxx*\: A number of variables whose names start with \$mime$\ are
+available when Exim is compiled with the content-scanning extension. For
+details, see section ~~SECTscanmimepart.
+.nem
+
.tempindent 0
\$n0$\ -- \$n9$\: These variables are counters that can be incremented by means
of the \add\ command in filter files.
.tempindent 0
\$original@_local@_part$\: When a top-level address is being processed for
delivery, this contains the same value as \$local@_part$\, unless a prefix or
-suffix was removed from the local part, in which case \$original@_local@_part$\
-contains the full local part. When a `child' 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. If the router that did the
-redirection processed the local part case-insensitively, the value in
-\$original@_local@_part$\ is in lower case. This variable differs from
-\$parent@_local@_part$\ 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, \$original@_local@_part$\ is not set.
+suffix was removed from the local part, because \$original@_local@_part$\
+always contains the full local part. When a `child' 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.
+
+If the router that did the redirection processed the local part
+case-insensitively, the value in \$original@_local@_part$\ is in lower case.
+This variable differs from \$parent@_local@_part$\ 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, \$original@_local@_part$\ is not set.
If new an address is created by means of a \deliver\ command in a system
filter, it is set up with an artificial `parent' address. This has the local
\*uname()*\ function. If \*uname()*\ returns a single-component name, Exim
calls \*gethostbyname()*\ (or \*getipnodebyname()*\ where available) in an
attempt to acquire a fully qualified host name.
-.em
See also \$smtp@_active@_hostname$\.
-.nem
.tempindent 0
\$qualify@_domain$\: The value set for this option in the configuration file.
or if not set, the value of \$qualify@_domain$\.
.tempindent 0
-\$rcpt@_count$\: When a message is being received by SMTP, this variable
+\$rcpt@_count$\: 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.
.tempindent 0
-\$rcpt@_defer@_count$\: When a message is being received by SMTP, this variable
+\$rcpt@_defer@_count$\: 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\*xx*\) response.
\$received@_for$\: If there is only a single recipient address in an incoming
message, this variable contains that address when the ::Received:: header line
is being built.
-.em
The value is copied after recipient rewriting has happened, but before the
\*local@_scan()*\ function is run.
-.nem
.tempindent 0
\$received@_protocol$\: When a message is being processed, this variable
-contains the name of the protocol by which it was received. See also the
-\-oMr-\ option.
-
+contains the name of the protocol by which it was received.
.em
+Most of the names used by Exim are defined by RFCs 821, 2821, and 3848. They
+start with `smtp' (the client used \\HELO\\) or `esmtp' (the client used
+\\EHLO\\). This can be followed by `s' for secure (encrypted) and/or `a' for
+authenticated. Thus, for example, if the protocol is set to `esmtpsa', the
+message was received over an encrypted SMTP connection and the client was
+successfully authenticated.
+
+Exim uses the protocol name `smtps' for the case when encryption is
+automatically set up on connection without the use of \\STARTTLS\\ (see
+\tls@_on@_connect@_ports\), and the client uses \\HELO\\ to initiate the
+encrypted SMTP session. The name `smtps' 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.
+
+The \-oMr-\ 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.
+.nem
+
.tempindent 0
\$recipient@_data$\: This variable is set after an indexing lookup success in
an ACL \recipients\ condition. It contains the data from the lookup, and the
require recipients = cdb*@@;/some/file
deny \*some further test involving*\ @$recipient@_data
.endd
-\**Warning**\: This variable is set only when a lookup is used as an indexing
+\**Warning**\: 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.
+
+.em
+.tempindent 0
+\$recipient@_verify@_failure$\: In an ACL, when a recipient verification fails,
+this variable contains information about the failure. It is set to one of the
+following words:
+.numberpars " "
+`qualify': The address was unqualified (no domain), and the message
+was neither local nor came from an exempted host.
+.nextp
+`route': Routing failed.
+.nextp
+`mail': Routing succeeded, and a callout was attempted; rejection occurred at
+or before the \\MAIL\\ command (that is, on initial connection, \\HELO\\, or
+\\MAIL\\).
+.nextp
+`recipient': The \\RCPT\\ command in a callout was rejected.
+.nextp
+`postmaster': The postmaster check in a callout was rejected.
+.endp
+The main use of this variable is expected to be to distinguish between
+rejections of \\MAIL\\ and rejections of \\RCPT\\.
.nem
.tempindent 0
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 \$recipients$\ only
+in these two cases:
.numberpars
In a system filter file.
.nextp
-In the \\DATA\\ or non-SMTP ACL, that is, in the final ACL for accepting a
-message.
+.em
+In the ACLs associated with the \\DATA\\ command, that is, the ACLs defined by
+\acl@_smtp@_predata\ and \acl@_smtp@_data\.
+.nem
.endp
.tempindent 0
.tempindent 0
\$return@_path$\: 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,
+is not enclosed in @<@> characters.
+At the start of routing an address,
\$return@_path$\ has the same value as \$sender@_address$\, 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, \$return@_path$\
subsequently contains the new bounce address, whereas \$sender@_address$\
always contains the original sender address that was received with the message.
-In other words, \$sender@_address$\ contains the incoming envelope sender, and
+In other words, \$sender@_address$\ contains the incoming envelope sender, and
\$return@_path$\ contains the outgoing envelope sender.
.tempindent 0
.tempindent 0
\$runrc$\: This variable contains the return code from a command that is run by
the \@$@{run...@}\ expansion item.
-\**Warning**\: In a router or transport, you cannot assume the order in which
-option values are expanded, except for those pre-conditions whose order of
-testing is documented. Therefore, you cannot reliably expect to set \$runrc$\
+\**Warning**\: In a router or transport, you cannot assume the order in which
+option values are expanded, except for those pre-conditions whose order of
+testing is documented. Therefore, you cannot reliably expect to set \$runrc$\
by the expansion of one option, and use it in another.
.tempindent 0
\$self@_hostname$\: When an address is routed to a supposedly remote host that
-turns out to be the local host, what happens is controlled by the
+turns out to be the local host, what happens is controlled by the
.index \self\ option||value of host name
\self\ generic router option. One of its values causes the address to be passed
to another router. When this happens, \$self@_hostname$\ is set to the name of
messages, the value of this variable is the empty string.
See also \$return@_path$\.
+.em
+.tempindent 0
+\$sender@_address@_data$\: If \$address@_data$\ is set when the routers are
+called from an ACL to verify a sender address, the final value is preserved in
+\$sender@_address@_data$\, 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.
+.nem
+
.tempindent 0
\$sender@_address@_domain$\: The domain portion of \$sender@_address$\.
.tempindent 0
\$sender@_address@_local@_part$\: The local part portion of \$sender@_address$\.
-.em
.tempindent 0
-\$sender@_data$\: This variable is set after a lookup success in an ACL
+\$sender@_data$\: This variable is set after a lookup success in an ACL
\senders\ condition or in a router \senders\ option. It contains the data from
the lookup, and the value remains set until the next \senders\ test. Thus, you
can do things like this:
require senders = cdb*@@;/some/file
deny \*some further test involving*\ @$sender@_data
.endd
-\**Warning**\: This variable is set only when a lookup is used as an indexing
+\**Warning**\: 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.
-.nem
.tempindent 0
\$sender@_fullhost$\: When a message is received from a remote host, this
.tempindent 0
\$sender@_host@_name$\: When a message is received from a remote host, this
-variable contains the host's name as obtained by looking up its IP address.
+variable contains the host's name as obtained by looking up its IP address.
For messages received by other means, this variable is empty.
If the host name has not previously been looked up, a reference to
-\$sender@_host@_name$\ triggers a lookup (for messages from remote hosts).
-.em
+\$sender@_host@_name$\ 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, or if
-the forward lookup does not yield the original IP address,
+via a forward lookup. If either the reverse or the forward lookup fails
+.em
+to find any data,
+.nem
+or if the forward lookup does not yield the original IP address,
\$sender@_host@_name$\ remains empty, and \$host@_lookup@_failed$\ is set to
`1'.
+.em
+However, if either of the lookups cannot be completed (for example, there is a
+DNS timeout), \$host@_lookup@_deferred$\ is set to `1', and
+\$host@_lookup@_failed$\ remains set to `0'.
+
+Once \$host@_lookup@_failed$\ is set to `1', Exim does not try to look up the
+host name again if there is a subsequent reference to \$sender@_host@_name$\
+in the same Exim process, but it does try again if \$sender@_host@_deferred$\
+is set to `1'.
.nem
Exim does not automatically look up every calling host's name. If you want
.numberpars
A string containing \$sender@_host@_name$\ is expanded.
.nextp
-The calling host matches the list in \host@_lookup\. In the default
+The calling host matches the list in \host@_lookup\. 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 \host@_lookup\ is unset.)
.nextp
that require this are described in sections ~~SECThoslispatnam and
~~SECThoslispatnamsk.
.nextp
-The calling host matches \helo@_try@_verify@_hosts\ or \helo@_verify@_hosts\.
-In this case, the host name is required to compare with the name quoted in any
+The calling host matches \helo@_try@_verify@_hosts\ or \helo@_verify@_hosts\.
+In this case, the host name is required to compare with the name quoted in any
\\EHLO\\ or \\HELO\\ commands that the client issues.
.nextp
-The remote host issues a \\EHLO\\ or \\HELO\\ command that quotes one of the
-domains in \helo@_lookup@_domains\. The default value of this option is
+The remote host issues a \\EHLO\\ or \\HELO\\ command that quotes one of the
+domains in \helo@_lookup@_domains\. The default value of this option is
.display asis
helo_lookup_domains = @ : @[]
.endd
-which causes a lookup if a remote host (incorrectly) gives the server's name or
+which causes a lookup if a remote host (incorrectly) gives the server's name or
IP address in an \\EHLO\\ or \\HELO\\ command.
.endp
three items are present in the parentheses, a newline and tab are inserted into
the string, to improve the formatting of the ::Received:: header.
+.em
+.tempindent 0
+\$sender@_verify@_failure$\: In an ACL, when a sender verification fails, this
+variable contains information about the failure. The details are the same as
+for \$recipient@_verify@_failure$\.
+
+.tempindent 0
+\$smtp@_active@_hostname$\: During an SMTP session, this variable contains the
+value of the active host name, as specified by the \smtp@_active@_hostname\
+option. The value of \$smtp@_active@_hostname$\ is saved with any message that
+is received, so its value can be consulted during routing and delivery.
+.nem
+
.index \\AUTH\\||argument
.index \\EXPN\\||argument
.index \\ETRN\\||argument
filter files. For example, a system filter could set a value indicating how
likely it is that a message is junk mail.
+.em
+.tempindent 0
+\$spam@_$\\*xxx*\: A number of variables whose names start with \$spam$\ are
+available when Exim is compiled with the content-scanning extension. For
+details, see section ~~SECTscanspamass.
+.nem
+
.tempindent 0
\$spool@_directory$\: The name of Exim's spool directory.
+.em
+.tempindent 0
+\$spool@_inodes$\: 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 \check@_spool@_inodes\ option.
+
+.tempindent 0
+\$spool@_space$\: 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:
+.display asis
+condition = ${if > {$spool_space}{50000}}
+.endd
+See also the \check@_spool@_space\ option.
+.nem
+
.tempindent 0
\$thisaddress$\: This variable is set only during the processing of the
\foranyaddress\ command in a filter file. Its use is explained in the
.tempindent 0
\$tls@_cipher$\: 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
+negotiated, for example DES-CBC3-SHA.
+In other circumstances, in particular, for message received over unencrypted
connections, the variable is empty.
See chapter ~~CHAPTLS for details of TLS support.
.tempindent 0
\$tls@_peerdn$\: When a message is received from a remote host over an
-encrypted SMTP connection,
+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
\$tls@_peerdn$\ during subsequent processing.
.tempindent 0
\$tod@_full$\: 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
+UTC, with positive values used for timezones that are ahead (east) of UTC, and
negative values for those that are behind (west).
.tempindent 0
.endd
in your \(Local/Makefile)\ and then build Exim in the normal way.
+.section Setting up so Perl can be used
Access to Perl subroutines is via a global configuration option called
.index \perl@_startup\
\perl@_startup\ and an expansion string operator \@$@{perl ...@}\. If there is
There is also a command line option \-pd-\ (for delay) which suppresses the
initial startup, even if \perl@_at@_start\ is set.
+.section Calling Perl subroutines
When the configuration file includes a \perl@_startup\ option you can make use
of the string expansion item to call the Perl subroutines that are defined
by the \perl@_startup\ code. The operator is used in any of the following
.endd
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 \*undef*\, the expansion fails in the same way as an explicit
-`fail' on an \@$@{if ...@}\ or \@$@{lookup...@}\ item.
-If the subroutine aborts by obeying Perl's \die\ function, the expansion fails
-with the error message that was passed to \die\.
+return value is \*undef*\, the expansion is forced to fail in the same way as
+an explicit `fail' on an \@$@{if ...@}\ or \@$@{lookup...@}\ item. If the
+subroutine aborts by obeying Perl's \die\ function, the expansion fails with
+the error message that was passed to \die\.
+.section Calling Exim functions from Perl
Within any Perl code called from Exim, the function \*Exim@:@:expand@_string*\
is available to call back into Exim's string expansion function. For example,
the Perl code
main log, adding a leading timestamp. In this case, you should not supply a
terminating newline.
+.em
+.section Use of standard output and error by Perl
+.index Perl||standard output and error
+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 \(/dev/null)\ in the daemon. The chaos is
+avoided, but the output is lost.
+
+.index Perl||\warn\, use of
+The Perl \warn\ statement writes to the standard error stream by default. Calls
+to \warn\ 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 \warn\ 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 \warn\ output completely, you need this:
+.display asis
+$SIG{__WARN__} = sub { };
+.endd
+Whenever a \warn\ 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 \warn\ message is passed
+as the first subroutine argument.
+.nem
.
standard SMTP port, you should not need to take any special action. The
rest of this chapter does not apply to you.
-In a more complicated situation you may want to listen only on certain
+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.
192.168.23.65 ; \
::1 ; \
3ffe:ffff:836f::fe86:a061
-.endd
+.endd
There are two different formats for specifying a port along with an IP address
in \local@_interfaces\:
.numberpars
-The port is added onto the address with a dot separator. For example, to listen
+The port is added onto the address with a dot separator. For example, to listen
on port 1234 on two different IP addresses:
.display asis
local_interfaces = <; 192.168.23.65.1234 ; \
3ffe:ffff:836f::fe86:a061.1234
-.endd
+.endd
.nextp
The IP address is enclosed in square brackets, and the port is added
with a colon separator, for example:
.display asis
local_interfaces = <; [192.168.23.65]:1234 ; \
[3ffe:ffff:836f::fe86:a061]:1234
-.endd
+.endd
.endp
When a port is not specified, the value of \daemon@_smtp@_ports\ is used. The
default setting contains just one port:
IP addresses in \local@_interfaces\, only numbers (not names) can be used.
-.section Special IP listening addresses
+.section Special IP listening addresses
The addresses 0.0.0.0 and @:@:0 are treated specially. They are interpreted
as `all IPv4 interfaces' and `all IPv6 interfaces', respectively. In each
case, Exim tells the TCP/IP stack to `listen on all IPv\*x*\ interfaces'
value of \daemon@_smtp@_ports\ is no longer relevant in this example.)
+.em
+.section Support for the obsolete SSMTP (or SMTPS) protocol
+.rset SECTsupobssmt "~~chapter.~~section"
+.index ssmtp protocol
+.index smtps protocol
+.index SMTP||ssmtp protocol
+.index SMTP||smtps protocol
+Exim supports the obsolete SSMTP protocol (also known as SMTPS) that was used
+before the \\STARTTLS\\ command was standardized for SMTP. Some legacy clients
+still use this protocol. If the \tls@_on@_connect@_ports\ option is set to a
+list of port numbers, connections to those ports must use SSMTP. The most
+common use of this option is expected to be
+.display asis
+tls_on_connect_ports = 465
+.endd
+because 465 is the usual port number used by the legacy clients. There is also
+a command line option \-tls-on-connect-\, which forces all ports to behave in
+this way when a daemon is started.
+
+\**Warning**\: Setting \tls@_on@_connect@_ports\ does not of itself cause the
+daemon to listen on those ports. You must still specify them in
+\daemon@_smtp@_ports\, \local@_interfaces\, or the \-oX-\ option. (This is
+because \tls@_on@_connect@_ports\ applies to \inetd\ connections as well as to
+connections via the daemon.)
+.nem
+
+
.section IPv6 address scopes
IPv6 addresses have `scopes', and a host with multiple hardware interfaces
can, in principle, have the same link-local IPv6 address on different
percent sign followed by something (often the interface name) has been
adopted in some cases, leading to addresses like this:
.display asis
-3ffe:2101:12:1:a00:20ff:fe86:a061%eth0
+fe80::202:b3ff:fe03:45c1%eth0
.endd
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 \*getaddrinfo()*\
.section Examples of starting a listening daemon
The default case in an IPv6 environment is
.display asis
-daemon_smtp_port = smtp
+daemon_smtp_ports = smtp
local_interfaces = <; ::0 ; 0.0.0.0
.endd
This specifies listening on the smtp port on all IPv6 and IPv4 interfaces.
.display asis
local_interfaces = 192.168.34.67 : 192.168.34.67
.endd
-\**Note**\: such a setting excludes listening on the loopback interfaces.
+\**Warning**\: such a setting excludes listening on the loopback interfaces.
.section Recognising the local host
address, but all available interface addresses are treated as local when
Exim is routing.
-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
+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 \hosts@_treat@_as@_local\ option.
This contains host names rather than IP addresses. When a host is referenced
-
.
.
.
types and default values. For ease of finding a particular option, they appear
in alphabetical order in section ~~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.
+aid to finding the name of the option you are looking for. Some options are
+listed in more than one group.
.set savedisplayflowcheck ~~displayflowcheck
.set displayflowcheck 0
\keep@_malformed\ $t$rm{for broken files -- should not happen}
\localhost@_number\ $t$rm{for unique message ids in clusters}
\message@_body@_visible\ $t$rm{how much to show in \$message@_body$\}
+.newline
+.em
+\mua@_wrapper\ $t$rm{run in `MUA wrapper' mode}
+.nem
+.newline
\print@_topbitchars\ $t$rm{top-bit characters are printing}
\timezone\ $t$rm{force time zone}
.endd
.section Logging
.display flow rm
.tabs 31
+.em
+\hosts@_connection@_nolog\ $t$rm{exemption from connect logging}
+.nem
+.newline
\log@_file@_path\ $t$rm{override compiled-in value}
\log@_selector\ $t$rm{set/unset optional logging}
\log@_timezone\ $t$rm{add timezone to log lines}
\message@_logs\ $t$rm{create per-message logs}
-\preserve@_message@_logs\ $t$rm{in another directory after message completion}
+\preserve@_message@_logs\ $t$rm{after message completion}
\process@_log@_path\ $t$rm{for SIGUSR1 and \*exiwhat*\}
\syslog@_duplication\ $t$rm{controls duplicate log lines on syslog }
\syslog@_facility\ $t$rm{set syslog `facility' field}
\syslog@_processname\ $t$rm{set syslog `ident' field}
\syslog@_timestamp\ $t$rm{timestamp syslog lines}
.newline
-.em
\write@_rejectlog\ $t$rm{control use of message log}
.newline
-.nem
.endd
.section Frozen messages
\extra@_local@_interfaces\ $t$rm{not necessarily listened on}
\local@_interfaces\ $t$rm{on which to listen, with optional ports}
\pid@_file@_path\ $t$rm{override compiled-in value}
-\queue@_run@_max\ $t$rm{maximum number of simultaneous queue runners}
+\queue@_run@_max\ $t$rm{maximum simultaneous queue runners}
.endd
.section Resource control
\check@_spool@_space\ $t$rm{before accepting a message}
\deliver@_queue@_load@_max\ $t$rm{no queue deliveries if load high}
\queue@_only@_load\ $t$rm{queue incoming if load high}
-\queue@_run@_max\ $t$rm{maximum number of simultaneous queue runners}
+\queue@_run@_max\ $t$rm{maximum simultaneous queue runners}
\remote@_max@_parallel\ $t$rm{parallel SMTP delivery per message}
\smtp@_accept@_max\ $t$rm{simultaneous incoming connections}
\smtp@_accept@_max@_nommail\ $t$rm{non-mail commands}
\acl@_smtp@_helo\ $t$rm{set ACL for \\EHLO\\ or \\HELO\\}
\acl@_smtp@_mail\ $t$rm{set ACL for \\MAIL\\}
\acl@_smtp@_mailauth\ $t$rm{set ACL for \\AUTH\\ on \\MAIL\\ command}
+.newline
+.em
+\acl@_smtp@_mime\ $t$rm{set ACL for MIME parts}
+\acl@_smtp@_predata\ $t$rm{set ACL for start of data}
+\acl@_smtp@_quit\ $t$rm{set ACL for \\QUIT\\}
+.nem
+.newline
\acl@_smtp@_rcpt\ $t$rm{set ACL for \\RCPT\\}
\acl@_smtp@_starttls\ $t$rm{set ACL for \\STARTTLS\\}
\acl@_smtp@_vrfy\ $t$rm{set ACL for \\VRFY\\}
+.newline
+.em
+\av@_scanner\ $t$rm{specify virus scanner}
+.nem
+.newline
\header@_maxsize\ $t$rm{total size of message header}
\header@_line@_maxsize\ $t$rm{individual header line limit}
\helo@_accept@_junk@_hosts\ $t$rm{allow syntactic junk from these hosts}
\local@_scan@_timeout\ $t$rm{timeout for \*local@_scan()*\}
\message@_size@_limit\ $t$rm{for all messages}
\percent@_hack@_domains\ $t$rm{recognize %-hack for these domains}
+.newline
+.em
+\spamd@_address\ $t$rm{set interface to SpamAssassin}
+.nem
+.newline
.endd
.section Callout cache
.tabs 31
\tls@_advertise@_hosts\ $t$rm{advertise TLS to these hosts}
\tls@_certificate\ $t$rm{location of server certificate}
-.newline
-.em
\tls@_crl\ $t$rm{certificate revocation list}
+\tls@_dhparam\ $t$rm{DH parameters for server}
.newline
+.em
+\tls@_on@_connect@_ports\ $t$rm{specify SSMTP (SMTPS) ports}
.nem
-\tls@_dhparam\ $t$rm{DH parameters for server}
+.newline
\tls@_privatekey\ $t$rm{location of server private key}
\tls@_remember@_esmtp\ $t$rm{don't reset after starting TLS}
-.newline
-.em
\tls@_require@_ciphers\ $t$rm{specify acceptable cipers}
-.newline
-.nem
\tls@_try@_verify@_hosts\ $t$rm{try to verify client certificate}
\tls@_verify@_certificates\ $t$rm{expected client certificates}
\tls@_verify@_hosts\ $t$rm{insist on client certificate verify}
.endd
-.section Local user handling
+.section Local user handling
.display flow rm
.tabs 31
\finduser@_retries\ $t$rm{useful in NIS environments}
\smtp@_accept@_queue@_per@_connection\ $t$rm{queue if more messages per connection}
\smtp@_accept@_reserve\ $t$rm{only reserve hosts if more connections}
.newline
-.em
\smtp@_active@_hostname\ $t$rm{host name to use in messages}
.newline
-.nem
\smtp@_banner\ $t$rm{text for welcome banner}
\smtp@_check@_spool@_space\ $t$rm{from \\SIZE\\ on \\MAIL\\ command}
\smtp@_connect@_backlog\ $t$rm{passed to TCP/IP stack}
\queue@_run@_in@_order\ $t$rm{order of arrival}
\queue@_run@_max\ $t$rm{of simultaneous queue runners}
\queue@_smtp@_domains\ $t$rm{no immediate SMTP delivery for these}
-\remote@_max@_parallel\ $t$rm{parallel SMTP delivery (per message, not overall)}
+\remote@_max@_parallel\ $t$rm{parallel SMTP delivery per message}
\remote@_sort@_domains\ $t$rm{order of remote deliveries}
\retry@_data@_expire\ $t$rm{timeout for retry data}
\retry@_interval@_max\ $t$rm{safety net for retry rules}
Those options that undergo string expansion before use are marked with $**$.
.fi
-.startconf
+.startconf main
.index \\8BITMIME\\
.index 8-bit characters
.index ~~ACL||for non-SMTP messages
.index non-SMTP messages, ACL for
.conf acl@_not@_smtp string$**$ unset
-This option defines the ACL that is run when a non-SMTP message is on the point
+This option defines the ACL that is run when a non-SMTP message is on the point
of being accepted. See chapter ~~CHAPACL for further details.
-.index ~~ACL||on SMTP connection
-.conf acl@_smtp@_connect string$**$ unset
-This option defines the ACL that is run when an SMTP connection is received.
-See chapter ~~CHAPACL for further details.
-
.index ~~ACL||setting up for SMTP commands
.index \\AUTH\\||ACL for
.conf acl@_smtp@_auth string$**$ unset
This option defines the ACL that is run when an SMTP \\AUTH\\ command is
received. See chapter ~~CHAPACL for further details.
+.index ~~ACL||on SMTP connection
+.conf acl@_smtp@_connect string$**$ unset
+This option defines the ACL that is run when an SMTP connection is received.
+See chapter ~~CHAPACL for further details.
+
.index \\DATA\\, ACL for
.conf acl@_smtp@_data string$**$ unset
This option defines the ACL that is run after an SMTP \\DATA\\ command has been
.index \\AUTH\\||on \\MAIL\\ command
.conf acl@_smtp@_mailauth string$**$ unset
-This option defines the ACL that is run when there is an \\AUTH\\ parameter on
+This option defines the ACL that is run when there is an \\AUTH\\ parameter on
a \\MAIL\\ command. See chapter ~~CHAPACL for details of ACLs, and chapter
~~CHAPSMTPAUTH for details of authentication.
+.em
+.index MIME content scanning||ACL for
+.conf acl@_smtp@_mime string$**$ unset
+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 ~~SECTscanmimepart for details.
+
+.conf acl@_smtp@_predata string$**$ unset
+This option defines the ACL that is run when an SMTP \\DATA\\ command is
+received, before the message itself is received. See chapter ~~CHAPACL for
+further details.
+
+.index \\QUIT\\||ACL for
+.conf acl@_smtp@_quit string$**$ unset
+This option defines the ACL that is run when an SMTP \\QUIT\\ command is
+received. See chapter ~~CHAPACL for further details.
+.nem
+
.index \\RCPT\\||ACL for
.conf acl@_smtp@_rcpt string$**$ unset
This option defines the ACL that is run when an SMTP \\RCPT\\ command is
format is not normally required these days, and few people know about it. It
has, however, been exploited by mail abusers.
-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
-\allow@_domain@_literals\ true, and also to add \"@@[]"\ to the list of local
-domains (defined in the named domain list \local@_domains\ in the default
-configuration). This `magic string' matches the domain literal form of all the
+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
+\allow@_domain@_literals\ true, and also to add \"@@[]"\ to the list of local
+domains (defined in the named domain list \local@_domains\ in the default
+configuration). This `magic string' matches the domain literal form of all the
local host's IP addresses.
.conf allow@_mx@_to@_ip boolean false
.conf allow@_utf8@_domains boolean false
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
+that at least two other MTAs permit this. This option allows Exim users to
experiment if they wish.
If it is set true, Exim's domain parsing function allows valid
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
+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
-\server@_advertise@_condition\ generic authenticator option on the individual
+\server@_advertise@_condition\ generic authenticator option on the individual
authenticators. See chapter ~~CHAPSMTPAUTH for further details.
Certain mail clients (for example, Netscape) require the user to provide a name
.display asis
auth_advertise_hosts = ${if eq{$tls_cipher}{}{}{*}}
.endd
-If \$tls@_cipher$\ is empty, the session is not encrypted, and the result of
-the expansion is empty, thus matching no hosts. Otherwise, the result of the
+If \$tls@_cipher$\ 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.
.conf auto@_thaw time 0s
though there are big problems'. See also \timeout@_frozen@_after\ and
\ignore@_bounce@_errors@_after\.
+.em
+.conf av@_scanner string "see below"
+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:
+.display asis
+sophie:/var/run/sophie
+.endd
+If the value of \av@_scanner\ starts with dollar character, it is expanded
+before use. See section ~~SECTscanvirus for further details.
+.nem
+
.conf bi@_command string unset
.index \-bi-\ option
This option supplies the name of a command that is run when Exim is called with
.index bounce message||including body
.conf bounce@_return@_body boolean true
-This option controls whether the body of an incoming message is included in a
-bounce message when \bounce@_return@_message\ is true. If it is not set, only
+This option controls whether the body of an incoming message is included in a
+bounce message when \bounce@_return@_message\ is true. If it is not set, only
the message header is included.
.index bounce message||including original
section ~~SECTcallvercache for details of the caching.
.conf callout@_random@_local@_part string$**$ "see below"
-This option defines the `random' local part that can be used as part of callout
+This option defines the `random' local part that can be used as part of callout
verification. The default value is
.display asis
$primary_host_name-$tod_epoch-testing
.index disk space, checking
.index spool directory||checking space
The four \check@_...\ options allow for checking of disk resources before a
-message is accepted. \check@_spool@_space\ and \check@_spool@_inodes\ check the
-spool partition if either value is greater than zero, for example:
+message is accepted.
+.em
+When any of these options are set, 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 the variables \$log@_inodes$\, \$log@_space$\,
+\$spool@_inodes$\, and \$spool@_space$\ in an ACL with appropriate additional
+conditions.
+.nem
+
+\check@_spool@_space\ and \check@_spool@_inodes\ check the spool partition if
+either value is greater than zero, for example:
.display asis
check_spool_space = 10M
check_spool_inodes = 100
.endd
-The spool partition is the one which contains the directory defined by
+The spool partition is the one that contains the directory defined by
\\SPOOL@_DIRECTORY\\ in \(Local/Makefile)\. It is used for holding messages in
transit.
.index TCP/IP||setting listening ports
.conf daemon@_smtp@_ports string "$tt{smtp}"
This option specifies one or more default SMTP ports on which the Exim daemon
-listens. See chapter ~~CHAPinterfaces for details of how it is used. For
+listens. See chapter ~~CHAPinterfaces for details of how it is used. For
backward compatibility, \daemon@_smtp@_port\ (singular) is a synonym.
.conf delay@_warning "time list" 24h
.index warning of delay
.index delay warning, specifying
When a message is delayed, Exim sends a warning message to the sender at
-intervals specified by this option. If it is set to a zero, no warnings are
-sent. The data is a colon-separated list of times after which to send warning
-messages. Up to 10 times may be given. If a message has been on the queue for
-longer than the last time, the last interval between the times is used to
-compute subsequent warning times. For example, with
+intervals specified by this option. The data is a colon-separated list of times
+after which to send warning messages.
+.em
+If the value of the option is an empty string or a zero time, no warnings are
+sent.
+.nem
+Up to 10 times may be given. If a message has been on the queue for longer than
+the last time, the last interval between the times is used to compute
+subsequent warning times. For example, with
.display asis
delay_warning = 4h:8h:24h
.endd
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
+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:
.display asis
delay_warning = 6h
for a long time. If a domain which exhibits this problem matches anything in
\dns__again__means__nonexist\, it is treated as if it did not exist. This
option should be used with care.
-.em
You can make it apply to reverse lookups by a setting such as this:
.display asis
dns_again_means_nonexist = *.in-addr.arpa
.endd
+.em
+This option applies to all DNS lookups that Exim does. The \%dnslookup%\ 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 the global option.
.nem
.index DNS||pre-check of name syntax
.endd
which permits only letters, digits, and hyphens in components, but they may not
start or end with a hyphen.
-If you set \allow@_utf8@_domains\, you must modify this pattern, or set the
+If you set \allow@_utf8@_domains\, you must modify this pattern, or set the
option to an empty string.
.conf dns@_ipv4@_lookup "domain list$**$" unset
See \dns@_retrans\ above.
.conf drop@_cr boolean false
-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
+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 ~~SECTlineendings.
.conf envelope@_to@_remove boolean true
The address list is expanded before use. The expansion variables
\$local@_part$\ and \$domain$\ are set from the original recipient of the error
message, and if there was any wildcard matching in the pattern, the expansion
-.index numerical variables (\$1$\, \$2$\, etc)||in \errors@_copy\
+.index numerical variables (\$1$\, \$2$\, etc)||in \errors@_copy\
variables \$0$\, \$1$\, etc. are set in the normal way.
.conf errors@_reply@_to string unset
.display
From: Mail Delivery System @<Mailer-Daemon@@<<qualify-domain>>@>
.endd
-where <<qualify-domain>> is the value of the \qualify@_domain\ option.
+where <<qualify-domain>> is the value of the \qualify@_domain\ option.
Experience shows that people reply to bounce messages. If the
\errors@_reply@_to\ option is set, a ::Reply-To:: header is added to bounce and
warning messages. For example:
the directory configured at compile time by the \\BIN@_DIRECTORY\\ setting. It
is necessary to change \exim@_path\ if, exceptionally, Exim is run from some
other place.
-\**Warning**\: 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 \-bP-\ option to extract option
+\**Warning**\: 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 \-bP-\ option to extract option
settings such as the value of \spool@_directory\.)
.conf exim@_user string "compile-time configured"
used. See chapter ~~CHAPsecurity for a discussion of security issues.
.conf extra@_local@_interfaces "string list" unset
-.index
-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
+.index
+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
~~SECTreclocipadd for details.
.conf extract@_addresses@_remove@_arguments boolean true
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
-\extract@_addresses@_remove@_arguments\ is true (the default), Exim subtracts
+\extract__addresses__remove__arguments\ is true (the default), Exim subtracts
argument headers. If it is set false, Exim adds rather than removes argument
addresses.
many extra times to find a user or a group, waiting for one second between
retries.
+.index \(/etc/passwd)\, multiple reading of
+.em
+You should not set this option greater than zero if your user information is in
+a traditional \(/etc/passwd)\ file, because it will cause Exim needlessly to
+search the file multiple times for non-existent users, and also cause delay.
+.nem
+
.conf freeze@_tell "string list, comma separated" unset
.index freezing messages||sending a message when freezing
On encountering certain errors, or when configured to do so in a system filter,
Exim freezes a message. This means that no further delivery attempts take place
until an administrator (or the \auto@_thaw\ feature) thaws the message. If
\freeze@_tell\ is set, Exim generates a warning message whenever it freezes
-something, unless the message it is freezing is a
+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.
+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
+message log. If you configure freezing in a filter or ACL, you must arrange for
any logging that you require.
.conf gecos@_name string$**$ unset
When these options are set, \gecos@_pattern\ 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, \gecos@_name\ is expanded and used as the user's name.
-.index numerical variables (\$1$\, \$2$\, etc)||in \gecos@_name\
+.index numerical variables (\$1$\, \$2$\, etc)||in \gecos@_name\
Numeric variables such as \$1$\, \$2$\, 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:
.index limit||size of message header section
This option controls the overall maximum size of a message's header
section. The default is the value of \\HEADER@_MAXSIZE\\ in
-\(Local/Makefile)\; the default for that is 1M. Messages with larger header
+\(Local/Makefile)\; the default for that is 1M. Messages with larger header
sections are rejected.
.conf header@_line@_maxsize integer 0
-.index header lines||maximum size of
+.index header lines||maximum size of
.index limit||size of one header line
This option limits the length of any individual header line in a message, after
all the continuations have been joined together. Messages with individual
some SMTP clients that send syntactic junk. They can be accommodated by setting
this option. Note that this is a syntax check only. See \helo@_verify@_hosts\
if you want to do semantic checking.
-See also \helo@_allow@_chars\ for a way of extending the permitted character
+See also \helo@_allow@_chars\ for a way of extending the permitted character
set.
.conf helo@_allow@_chars string unset
when looked up using \*gethostbyname()*\ (or \*getipnodebyname()*\ when
available) yields the calling host address.
.endp
-However, the \\EHLO\\ or \\HELO\\ command is not rejected if any of the checks
+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 \"verify = helo"\ condition. If you want
verification failure to cause rejection of \\EHLO\\ or \\HELO\\, use
\\HELO\\ or \\EHLO\\ in the same way as for \helo@_try@_verify@_hosts\. 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
+received before \\EHLO\\ or \\HELO\\, it is rejected with a
+503
error.
.conf hold@_domains "domain list$**$" unset
.conf host@_lookup@_order "string list" $tt{bydns:byaddr}
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
+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 \*gethostbyaddr()*\ or equivalent)
if that fails. You can change the order of these lookups, or omit one entirely,
if you want.
\**Warning**\: the `byaddr' method does not always yield aliases when there are
-multiple PTR records in the DNS and the IP address is not listed in
+multiple PTR records in the DNS and the IP address is not listed in
\(/etc/hosts)\. Different operating systems give different results in this
case. That is why the default tries a DNS lookup first.
.conf host@_reject@_connection "host list$**$" unset
.index host||rejecting connections from
If this option is set, incoming SMTP calls from the hosts listed are rejected
-as soon as the connection is made.
+as soon as the connection is made.
This option is obsolete, and retained only for backward compatibility, because
nowadays the ACL specified by \acl@_smtp@_connect\ can also reject incoming
connections immediately.
incoming messages at a later stage, such as after \\RCPT\\ commands. See
chapter ~~CHAPACL.
+.em
+.conf hosts@_connection@_nolog "host list$**$" unset
+.index host||not logging connections from
+This option defines a list of hosts for which connection logging does not
+happen, even though the \smtp@_connection\ 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:
+.display asis
+hosts_connection_nolog = :
+.endd
+If the \smtp@_connection\ log selector is not set, this option has no effect.
+.nem
+
.conf hosts@_treat@_as@_local "domain list$**$" unset
.index local host||domains treated as
.index host||treated as local
section ~~SECTdomainlist), and when checking the \hosts\ option in the \%smtp%\
transport for the local host (see the \allow@_localhost\ option in that
transport).
-See also \local@_interfaces\, \extra@_local@_interfaces\, and chapter
-~~CHAPinterfaces, which contains a discussion about local network interfaces
+See also \local@_interfaces\, \extra@_local@_interfaces\, and chapter
+~~CHAPinterfaces, which contains a discussion about local network interfaces
and recognising the local host.
.conf ignore@_bounce@_errors@_after time 10w
.index bounce message||discarding
.index discarding bounce message
-This option affects the processing of bounce messages that cannot be delivered,
-that is, those that suffer a permanent delivery failure. (Bounce messages that
+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.)
After a permanent delivery failure, bounce messages are frozen,
.index ::From:: header line||disabling checking of
When a message is submitted locally (that is, not over a TCP/IP connection) by
an untrusted user, Exim removes any existing ::Sender:: header line, and checks
-that the ::From:: header line matches the login of the calling user. You can
-use \local@_from@_prefix\ and \local@_from@_suffix\ to permit affixes on the
-local part. If the ::From:: header line does not match, Exim adds a ::Sender::
-header with an address constructed from the calling user's login and the
-default qualify domain.
+that the ::From:: header line matches
+.em
+the login of the calling user and the domain specified by \qualify@_domain\.
+
+\**Note**\: An unqualified address (no domain) in the ::From:: header in a
+locally submitted message is automatically qualified by Exim, unless the
+\-bnq-\ command line option is used.
+.nem
+
+You can use \local@_from@_prefix\ and \local@_from@_suffix\ to permit affixes
+on the local part. If the ::From:: header line does not match, Exim adds a
+::Sender:: header with an address constructed from the calling user's login and
+the default qualify domain.
If \local@_from@_check\ is set false, the ::From:: header check is disabled,
and no ::Sender:: header is ever added. If, in addition, you want to retain
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
\untrusted@_set@_sender\ permits the user to supply an envelope sender.
-Section ~~SECTthesenhea has more details about ::Sender:: processing.
+
+.em
+For messages received over TCP/IP, an ACL can specify `submission mode' to
+request similar header line checking. See section ~~SECTthesenhea, which has
+more details about ::Sender:: processing.
+.nem
.conf local@_from@_prefix string unset
See \local@_from@_prefix\ above.
.conf local@_interfaces "string list" "see below"
-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
-~~CHAPinterfaces contains a full description of this option and the related
-options \extra@_local@_interfaces\ and \hosts@_treat@_as@_local\. The default
-value for \local@_interfaces\ is
+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
+~~CHAPinterfaces contains a full description of this option and the related
+options
+.em
+\daemon@_smtp@_ports\, \extra@_local@_interfaces\, \hosts@_treat@_as@_local\,
+and \tls@_on@_connect@_ports\.
+.nem
+The default value for \local@_interfaces\ is
.display asis
local_interfaces = 0.0.0.0
.endd
.index limit||message size
.index size||of message, limit
This option limits the maximum size of message that Exim will process. The
-value is expanded for each incoming
+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. \**Note**\: This limit cannot be
made to depend on a message's sender or any other properties of an individual
standard utilities for handling such moved messages, and they do not show up in
lists generated by \-bp-\ or by the Exim monitor.
+.em
+.conf mua@_wrapper boolean false
+Setting this option true causes Exim to run in a very restrictive mode in which
+it passes messages synchronously to a smart host. Chapter ~~CHAPnonqueueing
+contains a full description of this facility.
+.nem
+
.conf mysql@_servers "string list" unset
.index MySQL||server list
This option provides a list of MySQL servers and associated connection data, to
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.
-
-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 `root'. The \never@_users\ runtime option
+
+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 `root'. The \never@_users\ runtime option
can be used to add more users to the fixed list.
If a message is to be delivered as one of the users on the fixed list or the
.endd
If no path is set, the pid is written to the file \(exim-daemon.pid)\ in Exim's
spool directory.
-The value set by the option can be overridden by the \-oP-\ command line
-option. A pid file is not written if a `non-standard' daemon is run by means of
+The value set by the option can be overridden by the \-oP-\ command line
+option. A pid file is not written if a `non-standard' daemon is run by means of
the \-oX-\ option, unless a path is explicitly supplied by \-oP-\.
.conf pipelining@_advertise@_hosts "host list$**$" $*$
\\PIPELINING\\ extension to specific hosts. When \\PIPELINING\\ is not
advertised and \smtp@_enforce@_sync\ is true, an Exim server enforces strict
synchronization for each SMTP command and response.
-.em
When \\PIPELINING\\ is advertised, Exim assumes that clients will use it; `out
-of order' commands that are `expected' do not count as protocol errors (see
+of order' commands that are `expected' do not count as protocol errors (see
\smtp@_max@_synprot@_errors\).
-.nem
.conf preserve@_message@_logs boolean false
.index message logs, preserving
.index name||of local host
.index host||name of local
.index local host||name of
-.em
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 \helo@_data\
option in the \%smtp%\ transport),
-.nem
and as the default for \qualify@_domain\. If it is not set, Exim calls
\*uname()*\ to find it. If this fails, Exim panics and dies. If the name
returned by \*uname()*\ contains only one component, Exim passes it to
\*gethostbyname()*\ (or \*getipnodebyname()*\ when available) in order to
obtain the fully qualified version.
-.em
The value of \$primary@_hostname$\ is also used by default in some SMTP
response messages from an Exim server. This can be changed dynamically by
setting \smtp@_active@_hostname\.
-.nem
.conf print@_topbitchars boolean false
.index printing characters
.conf process@_log@_path string unset
.index process log path
-.index log||process log
+.index log||process log
.index \*exiwhat*\
This option sets the name of the file to which an Exim process writes its
`process log' when sent a USR1 signal. This is used by the \*exiwhat*\ utility
.conf qualify@_domain string "see below"
.index domain||for qualifying addresses
.index address||qualification
-This option specifies the domain name that is added to any sender addresses
-that do not have a domain qualification. It also applies to recipient addresses
-if \qualify@_recipient\ is not set. Such addresses are accepted by default only
-for locally-generated messages. Messages from external sources must always
-contain fully qualified addresses, unless the sending host matches
-\sender@_unqualified@_hosts\ or \recipient@_unqualified@_hosts\ (as
-appropriate), in which case incoming addresses are qualified with
-\qualify@_domain\ or \qualify@_recipient\ as necessary. Internally, Exim always
-works with fully qualified addresses.
-If \qualify@_domain\ is not set, it defaults to the \primary@_hostname\ value.
+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 \qualify@_recipient\ is not set.
+.em
+Unqualified addresses are accepted by default only for locally-generated
+messages.
+
+Qualification is also applied to addresses in header lines such as ::From:: and
+::To:: for locally-generated messages, unless the \-bnq-\ command line option
+is used.
+.nem
+
+Messages from external sources must always contain fully qualified addresses,
+unless the sending host matches \sender@_unqualified@_hosts\ or
+\recipient@_unqualified@_hosts\ (as appropriate), in which case incoming
+addresses are qualified with \qualify@_domain\ or \qualify@_recipient\ as
+necessary. Internally, Exim always works with fully qualified envelope
+addresses. If \qualify@_domain\ is not set, it defaults to the
+\primary@_hostname\ value.
.conf qualify@_recipient string "see below"
-This specifies the domain name that is added to any recipient addresses that do
-not have a domain qualification. Such addresses are accepted by default only
-for locally-generated messages. Messages from external sources must always
-contain fully qualified recipient addresses, unless the sending host matches
-\recipient@_unqualified@_hosts\,
-in which case incoming recipient addresses are qualified with
-\qualify@_recipient\.
-If \qualify@_recipient\ is not set, it defaults to the \qualify@_domain\ value.
+.em
+This option allows you to specify a different domain for qualifying recipient
+addresses to the one that is used for senders. See \qualify@_domain\ above.
+.nem
.conf queue@_domains "domain list$**$" unset
.index domain||specifying non-immediate delivery
.index queue runner||processing messages in order
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 in a single
-directory (the default), this happens anyway, but if \split@_spool@_directory\
-is set it does not -- for delivery in random order, the sub-directories are
-processed one at a time (in random order), to avoid setting up one huge list.
-Thus, setting \queue@_run@_in@_order\ with \split@_spool@_directory\ may
-degrade performance when the queue is large. In most situations,
-\queue@_run@_in@_order\ should not be set.
+must be set up before the deliveries start. When the queue is all held in a
+single directory (the default),
+.em
+a single list is created for both the ordered and the non-ordered cases.
+However, if \split@_spool@_directory\ is set, a single list is not created when
+\queue@_run@_in@_order\ 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 \queue@_run@_in@_order\ with
+\split@_spool@_directory\ may degrade performance when the queue is large,
+because of the extra work in setting up the single, large list. In most
+situations, \queue@_run@_in@_order\ should not be set.
+.nem
.conf queue@_run@_max integer 5
.index queue runner||maximum number of
Received: by scrooge.carol.example with local (Exim 4.00)
id 16IOWW-000083-00; Tue, 25 Dec 2001 14:43:41 +0000
.endd
-.em
-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
+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.
-.nem
.conf received@_headers@_max integer 30
.index loop||prevention
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 \recipient@_unqualified@_hosts\,
-.em
or if the message was submitted locally (not using TCP/IP), and the \-bnq-\
option was not set.
-.nem
.conf recipients@_max integer 0
.index limit||number of recipients
-.index recipient||maximum number
+.index recipient||maximum number
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
then take place at once is \queue@_run@_max\ multiplied by
\remote@_max@_parallel\.
-If it is purely remote deliveries you want to control, use \queue@_smtp\
-instead of \queue@_only\. This has the added benefit of doing the SMTP routing
-before queuing, so that several messages for the same host will eventually get
-delivered down the same connection.
+If it is purely remote deliveries you want to control, use
+\queue@_smtp@_domains\ instead of \queue@_only\. This has the added benefit of
+doing the SMTP routing before queuing, so that several messages for the same
+host will eventually get delivered down the same connection.
.conf remote@_sort@_domains "domain list$**$" unset
.index sorting remote deliveries
reject unqualified addresses in headers that contain sender addresses, but it
qualifies them only if the message came from a host that matches
\sender@_unqualified@_hosts\,
-.em
or if the message was submitted locally (not using TCP/IP), and the \-bnq-\
option was not set.
-.nem
.conf smtp@_accept@_keepalive boolean true
.index keepalive||on incoming connection
Exim counts the number of `non-mail' commands in an SMTP session, and drops the
connection if there are too many. This option defines `too many'. The check
catches some denial-of-service attacks, repeated failing \\AUTH\\s, or a mad
-client looping sending \\EHLO\\, for example. The check is applied only if the
+client looping sending \\EHLO\\, for example. The check is applied only if the
client host matches \smtp@_accept@_max@_nonmail@_hosts\.
When a new message is expected, one occurrence of \\RSET\\ is not counted. This
connections are accepted only from hosts listed in \smtp@_reserve@_hosts\.
See also \smtp@_accept@_max@_per@_host\.
-.em
.conf smtp@_active@_hostname string$**$ unset
.index host||name in SMTP responses
.index SMTP||host name in responses
several different hosts. At the start of an SMTP connection, its value is
expanded and used instead of the value of \$primary@_hostname$\ in SMTP
responses. For example, it is used as domain name in the response to an
-incoming \\HELO\\ or \\EHLO\\ command. 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 \$primary@_hostname$\ 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 \smtp@_active@_hostname\ depends on
-the incoming interface address. For example:
+incoming \\HELO\\ or \\EHLO\\ command.
+.em
+It is also used in \\HELO\\ commands for callout verification.
+The active hostname is placed in the \$smtp__active__hostname$\ 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.
+.nem
+
+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 \$primary@_hostname$\ 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 \smtp@_active@_hostname\ depends on the incoming interface address.
+For example:
.display asis
smtp_active_hostname = ${if eq{$interface_address}{10.0.0.1}\
{cox.mydomain}{box.mydomain}}
.endd
-If you set \smtp@_active@_hostname\, you probably also want to set
-\smtp@_banner\, since its default value references \$primary@_hostname$\.
-.nem
.conf smtp@_banner string$**$ "see below"
.index SMTP||welcome banner
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:
.display asis
-smtp_banner = $primary_hostname ESMTP Exim $version_number \
- $tod_full
+.em
+smtp_banner = $smtp_active_hostname ESMTP Exim \
+ $version_number $tod_full
+.nem
.endd
Failure to expand the string causes a panic error. If you want to create a
multiline response to the initial SMTP connection, use `@\n' in the string at
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. 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 `554 SMTP synchronization error' 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. The check can be
-disabled by setting \smtp@_enforce@_sync\ false.
+fewer, but they still exist.
+
+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 `554
+SMTP synchronization error' 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.
+
.em
-See also \pipelining@_advertise@_hosts\.
+The check can be globally disabled by setting \smtp@_enforce@_sync\ 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 \control\ modifier in an ACL
+(see section ~~SECTcontrols). See also \pipelining@_advertise@_hosts\.
.nem
.conf smtp@_etrn@_command string$**$ unset
.conf smtp@_max@_synprot@_errors integer 3
.index SMTP||limiting syntax and protocol errors
.index limit||SMTP syntax and protocol errors
-Exim rejects SMTP commands that contain syntax or protocol errors. In
+Exim rejects SMTP commands that contain syntax or protocol errors. In
particular, a syntactically invalid email address, as in this command:
.display asis
RCPT TO:<abc xyz@a.b.c>
too many syntax or protocol errors in one SMTP session, the connection is
dropped. The limit is set by this option.
-.em
.index \\PIPELINING\\||expected errors
-When the \\PIPELINING\\ extension to SMTP is in use, some protocol errors are
-`expected', for instance, a \\RCPT\\ command after a rejected \\MAIL\\ command.
-Exim assumes that \\PIPELINING\\ will be used if it advertises it (see
-\pipelining@_advertise@_hosts\), and in this situation, `expected' errors do
+When the \\PIPELINING\\ extension to SMTP is in use, some protocol errors are
+`expected', for instance, a \\RCPT\\ command after a rejected \\MAIL\\ command.
+Exim assumes that \\PIPELINING\\ will be used if it advertises it (see
+\pipelining@_advertise@_hosts\), and in this situation, `expected' errors do
not count towards the limit.
-.nem
.conf smtp@_max@_unknown@_commands integer 3
.index SMTP||limiting unknown commands
.index limit||unknown SMTP commands
-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
-.em
-clients
-.nem
+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.
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.
-It is also possible to configure delays explicitly in ACLs. See section
+It is also possible to configure delays explicitly in ACLs. See section
~~SECTACLmodi for details.
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.
+the message is abandoned.
A line is written to the log containing one of the following messages:
.display asis
SMTP command timeout on connection from...
SMTP data timeout on connection from...
.endd
-The former means that Exim was expecting to read an SMTP command; the latter
+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.
550 failing address in "From" header is: <user@dom.ain
.endd
+.em
+.conf spamd@_address string "$tt{127.0.0.1 783}"
+This option is available when Exim is compiled with the content-scanning
+extension. It specifies how Exim connects to SpamAssassin's \spamd\ daemon. See
+section ~~SECTscanspamass for more details.
+.nem
+
.conf split@_spool@_directory boolean false
.index multiple spool directories
.index spool directory||split
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.
-.em
-However, addresses in header lines are checked only when an ACL requests header
+However, addresses in header lines are checked only when an ACL requests header
syntax checking.
-.nem
.conf syslog@_duplication boolean true
.index syslog||duplicate log lines, suppressing
.conf syslog@_facility string unset
.index syslog||facility, setting
-This option sets the syslog `facility' name, used when Exim is logging to
+This option sets the syslog `facility' name, used when Exim is logging to
syslog. The value must be one of the strings `mail', `user', `news', `uucp',
-`daemon', or `local\*x*\' where \*x*\ is a digit between 0 and 7. If this
+`daemon', or `local\*x*\' where \*x*\ is a digit between 0 and 7. If this
option is unset, `mail' is used. See chapter ~~CHAPlog for details of Exim's
logging.
assumed to be in this file if \tls@_privatekey\ is unset. See chapter ~~CHAPTLS
for further details.
-\**Note**\: The certificates defined by this option are used only when Exim is
+\**Note**\: 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 \tls@_certificate\
option in the relevant \%smtp%\ transport.
-.em
.conf tls@_crl string$**$ unset
.index TLS||server certificate revocation list
.index certificate||revocation list for server
This option specifies a certificate revocation list. The expanded value must
be the name of a file that contains a CRL in PEM format.
-.nem
.conf tls@_dhparam string$**$ unset
.index TLS||D-H parameters for server
The value of this option is expanded, and must then be the absolute path to
a file which contains the server's DH parameter values.
-This is used only for OpenSSL. When Exim is linked with GnuTLS, this option is
+This is used only for OpenSSL. When Exim is linked with GnuTLS, this option is
ignored. See section ~~SECTopenvsgnu for further details.
+.em
+.conf tls@_on@_connect@_ports "string list" unset
+This option specifies a list of incoming SSMTP (aka SMTPS) ports that should
+operate the obsolete 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 ~~SECTsupobssmt.
+.nem
+
.conf tls@_privatekey string$**$ unset
.index TLS||server private key, location of
-The value of this option is expanded, and must then be the absolute path to
-a file which contains the server's private key.
-If this option is unset, the private key is assumed to be in the same file as
-the server's certificates. See chapter ~~CHAPTLS for further details.
+The value of this option is expanded, and must then be the absolute path to a
+file which contains the server's private key. If this option is unset, the
+private key is assumed to be in the same file as the server's certificates. See
+chapter ~~CHAPTLS for further details.
.conf tls@_remember@_esmtp boolean false
.index TLS||esmtp state, remembering
support for broken clients that fail to send a new \\EHLO\\ after starting a
TLS session.
-.em
.conf tls@_require@_ciphers string$**$ unset
.index TLS||requiring specific ciphers
.index cipher||requiring specific
This option controls which ciphers can be used for incoming TLS connections.
-(The \%smtp%\ transport has an option of the same name for controlling outgoing
-connections.) This option is expanded for each connection, so can be varied for
+The \%smtp%\ 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. Details are given in section ~~SECTreqciphsslgnu.
+in somewhat different ways.
+.em
+If GnuTLS is being used, the client controls the preference order of the
+available ciphers.
.nem
+Details are given in sections ~~SECTreqciphssl and ~~SECTreqciphgnu.
.conf tls@_try@_verify@_hosts "host list$**$" unset
.index TLS||client certificate verification
.index TLS||client certificate verification
.index certificate||verification of client
This option, along with \tls@_try@_verify@_hosts\, controls the checking of
-certificates from clients.
-The expected certificates are defined by \tls@_verify@_certificates\, which
-must be set. A configuration error occurs if either \tls@_verify@_hosts\ or
+certificates from clients.
+The expected certificates are defined by \tls@_verify@_certificates\, which
+must be set. A configuration error occurs if either \tls@_verify@_hosts\ or
\tls@_try@_verify@_hosts\ is set and \tls@_verify@_certificates\ is not set.
Any client that matches \tls@_verify@_hosts\ is constrained by
.index trusted group
.index group||trusted
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.
+or which has one of them as a supplementary group, is trusted.
The groups can be specified numerically or by name.
See section ~~SECTtrustedadmin for details of what trusted callers are
permitted to do. If neither \trusted@_groups\ nor \trusted@_users\ is set, only
.index trusted user
.index user||trusted
If this option is set, any process that is running as one of the listed users
-is trusted.
+is trusted.
The users can be specified numerically or by name.
See section ~~SECTtrustedadmin for details of what trusted callers are
permitted to do. If neither \trusted@_groups\ nor \trusted@_users\ is set, only
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 \$sender@_ident$\, so you can, for example, restrict
-users to setting senders that start with their login ids
+users to setting senders that start with their login ids
followed by a hyphen
by a setting like this:
.display asis
\delay@_warning\. Details of the file's contents are given in chapter
~~CHAPemsgcust. See also \bounce@_message@_file\.
-.em
.conf write@_rejectlog boolean true
.index reject log||disabling
If this option is set false, Exim no longer writes anything to the reject log.
See chapter ~~CHAPlog for details of what Exim writes to its logs.
-.nem
.endconf
.index options||generic, for routers
.index generic options||router
-This chapter describes the generic options that apply to all routers,
+This chapter describes the generic options that apply to all routers,
identifying those that are preconditions. For a general description of how a
-router operates, see sections ~~SECTrunindrou and ~~SECTrouprecon. The second
-of these sections specifies the order in which the preconditions are tested.
-The order of expansion of the options that provide data for a transport is:
-\errors@_to\, \headers@_add\, \headers@_remove\, \transport\.
+router operates, see sections ~~SECTrunindrou and ~~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: \errors@_to\,
+\headers@_add\, \headers@_remove\, \transport\.
-.startconf
+.startconf routers
.conf address@_data string$**$ unset
.index router||data attached to address
When the expansion succeeds, the value is retained with the address, and can be
accessed using the variable \$address@_data$\ in the current router, subsequent
-routers, and the eventual transport.
+routers, and the eventual transport.
-\**Warning**\: if the current or any subsequent router is a \%redirect%\ router
+\**Warning**\: if the current or any subsequent router is a \%redirect%\ router
that runs a user's filter file, the contents of \$address@_data$\ are
accessible in the filter. This is not normally a problem, because such data is
-usually either not confidential or it `belongs' to the current user, but if you
-do put confidential data into \$address@_data$\ you need to remember this
+usually either not confidential or it `belongs' to the current user, but if you
+do put confidential data into \$address@_data$\ you need to remember this
point.
Even if the router declines or passes, the value of \$address@_data$\ remains
file = ${extract{mailbox}{$address_data}}
.endd
This makes the configuration file less messy, and also reduces the number of
-lookups. (Exim does cache the most recent lookup, but there may be several
-addresses in a message which cause lookups to occur.)
+lookups (though Exim does cache lookups).
-The \address@_data\ 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 \address@_data\ is set by a
-router when verifying an address from an ACL, its value is available for use in
-the rest of the ACL statement.
+The \address@_data\ 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
+.em
+\$address@_data$\ 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 \$sender@_address@_data$\.
+.nem
.conf address@_test "boolean (precondition)" true
.index router||skipping when address testing
If this option is set false, the router is skipped when routing is being tested
by means of the \-bt-\ 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 `already scanned' indicator when testing real address
+first router sends messages to an external scanner, because it saves you
+having to set the `already scanned' indicator when testing real address
routing.
.display asis
cannot_route_message = Unknown local user
.endd
-on the final router that checks for local users. If string expansion fails, the
+on the final router that checks for local users. If string expansion fails, 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
part lists (for example, \local@_parts\), case-sensitive matching can be turned
on by `+caseful' as a list item. See section ~~SECTcasletadd for more details.
+.em
+The value of the \$local@_part$\ variable is forced to lower case while a
+router is running unless \caseful@_local@_part\ is set. When a router assigns
+an address to a transport, the value of \$local@_part$\ 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 \$original@_local@_part$\
+and \$parent@_local@_part$\ are those that were used by the redirecting router.
+
+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 \control\
+modifier that can be used to specify case-sensitive processing within the ACL
+(see section ~~SECTcontrols).
+.nem
.conf check@_local@_user "boolean (precondition)" false
.index local user, checking in router
.index router||checking for local user
+.index \(/etc/passwd)\
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 \*getpwnam()*\ function rather
than trying to read \(/etc/passwd)\ directly. This means that other methods of
holding password data (such as NIS) are supported. If the local part is a local
user, \$home$\ 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 ~~SECTrouprecon). However, the
-value of \$home$\ can be overridden by \router@_home@_directory\.
-If the local part is not a local user, the router is skipped.
+preconditions that are evaluated after this one (the order of evaluation is
+given in section ~~SECTrouprecon). However, the value of \$home$\ can be
+overridden by \router@_home@_directory\. If the local part is not a local user,
+the router is skipped.
If you want to check that the local part is either the name of a local user
-or matches something else, you cannot combine \check@_local@_user\ with a
-setting of \local@_parts\, because that specifies the logical \*and*\ of the
-two conditions. However, you can use a \%passwd%\ lookup in a \local@_parts\
+or matches something else, you cannot combine \check@_local@_user\ with a
+setting of \local@_parts\, because that specifies the logical \*and*\ of the
+two conditions. However, you can use a \%passwd%\ lookup in a \local@_parts\
setting to achieve this. For example:
.display asis
local_parts = passwd;$local_part : lsearch;/etc/other/users
up a home directory) do not occur when a \%passwd%\ lookup is used in a
\local@_parts\ (or any other) precondition.
+
.conf condition "string$**$ (precondition)" unset
.index router||customized precondition
This option specifies a general precondition test that has to succeed for the
-router to be called. The string is expanded, and if the result is 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), the router is skipped, and
-the address is offered to the next one. This provides a means of applying
-special-purpose conditions to the running of routers.
+router to be called. The \condition\ option is the last precondition to be
+evaluated (see section ~~SECTrouprecon). The string is expanded, and if the
+result is 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), the router
+is skipped, and the address is offered to the next one.
+.em
+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).
+
+The \condition\ 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:
+.display asis
+condition = ${if >{$message_age}{600}}
+.endd
+Because of the default behaviour of the string expansion, this is equivalent to
+.display asis
+condition = ${if >{$message_age}{600}{true}{}}
+.endd
+.nem
If the expansion fails (other than forced failure) delivery is deferred. Some
-of the other options below are common special cases that could in fact be
-specified using \condition\.
-Note that \condition\ is the last precondition to be evaluated (see
-section ~~SECTrouprecon).
+of the other precondition options are common special cases that could in fact
+be specified using \condition\.
.conf debug@_print string$**$ unset
.index testing||variables in drivers
If this option is set and debugging is enabled (see the \-d-\ 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
+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 \condition\
.conf disable@_logging boolean false
If this option is set true, nothing is logged for any routing errors
-.em
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.
-.nem
.conf domains "domain list$**$ (precondition)" unset
.index router||restricting to specific domains
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 \$domain@_data$\ for use in string
expansions of the driver's private options.
-See section ~~SECTrouprecon for a list of the order in which preconditions
+See section ~~SECTrouprecon for a list of the order in which preconditions
are evaluated.
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.
-\errors@_to\ is expanded before \headers@_add\, \headers@_remove\, and
+address verifies successfully.
+\errors@_to\ is expanded before \headers@_add\, \headers@_remove\, and
\transport\.
If the option is unset, or the expansion is forced to fail, or the result of
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' \(.forward)\ files, while leaving it
-on for the system alias file.
-See section ~~SECTrouprecon for a list of the order in which preconditions
+on for the system alias file.
+See section ~~SECTrouprecon for a list of the order in which preconditions
are evaluated.
The use of the SMTP \\EXPN\\ command is controlled by an ACL (see chapter
.index router||setting group
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
+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 \check@_local@_user\ is set, when the default
is taken from the password information. See also \initgroups\ and \user\ and
.conf headers@_add string$**$ unset
.index header lines||adding
.index router||adding header lines
+.em
This option specifies a string of text that is expanded at routing time, and
-associated with any addresses that are processed by the router
-when delivering a message. This option has no effect when an address is just
-being verified.
+associated with any addresses that are accepted by the router. 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
+~~SECTheadersaddrem.
The \headers@_add\ option is expanded after \errors@_to\, but before
-\headers@_remove\ and \transport\.
-If the expanded string is empty, or if the expansion is forced to fail, the
-option has no effect. Other expansion failures are treated as configuration
-errors. The expanded string must be in the form of one or more RFC 2822 header
-lines, separated by newlines (coded as `@\n'). For example:
-.display asis
-headers_add = X-added-header: added by $primary_hostname\n\
- X-added-second: another added header line
-.endd
-Exim does not check the syntax of these added header lines. If an address
-passes through several routers as a result of aliasing or forwarding
-operations, any \headers@_add\ or \headers@_remove\ specifications are
-cumulative. This does not apply for multiple routers that result from the use
-of `unseen'.
+\headers@_remove\ and \transport\. If the expanded string is empty, or if the
+expansion is forced to fail, the option has no effect. Other expansion failures
+are treated as configuration errors.
-At transport time, all the original headers listed in \headers__remove\ are
-removed. If there are multiple instances of any listed header, they are all
-removed.
-Then the new headers specified by \headers@_add\ are added, in the order in
-which they were attached to the address. Finally, any additional headers
-specified by the transport are added. It is not possible to remove headers
-added to an address by \headers@_add\.
-
-Because the addition does not happen until transport time, header lines that
-are added by \headers@_add\ are not accessible by means of the \$header@_xxx$\
-expansion syntax. Conversely, header lines that are removed by
-\headers@_remove\ remain visible.
-
-Addresses with different \headers@_add\ or \headers@_remove\ settings cannot be
-delivered together in a batch. The \headers@_add\ option cannot be used for a
-\%redirect%\ router that has the \one@_time\ option set.
+\**Warning**\: The \headers@_add\ option cannot be used for a \%redirect%\
+router that has the \one@_time\ option set.
+.nem
.conf headers@_remove string$**$ unset
.index header lines||removing
.index router||removing header lines
-The string is expanded at routing time and is then associated with any
-addresses that are processed by the router when delivering a message. This
-option has no effect when an address is being verified. The \headers@_remove\
-option is expanded after \errors@_to\ and \headers@_add\, but before
-\transport\. If the expansion is forced to fail, the option has no effect.
-Other expansion failures are treated as configuration errors.
-
.em
-After expansion, the string 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.
+This option specifies a string of text that is expanded at routing time, and
+associated with any addresses that are accepted by the router. However, this
+option has no effect when an address is just being verified. The way in which
+the text is used to remove header lines at transport time is described in
+section ~~SECTheadersaddrem.
+
+The \headers@_remove\ option is expanded after \errors@_to\ and \headers@_add\,
+but before \transport\. If the expansion is forced to fail, the option has no
+effect. Other expansion failures are treated as configuration errors.
+
+\**Warning**\: The \headers@_remove\ option cannot be used for a \%redirect%\
+router that has the \one@_time\ option set.
.nem
-For example:
-.display asis
-headers_remove = return-receipt-to:acknowledge-to
-.endd
-The list is used at transport time as described under \headers@_add\ above. The
-\headers@_remove\ option cannot be used for a \%redirect%\ router that has the
-\one@_time\ option set.
+
.conf ignore@_target@_hosts "host list$**$" unset
.index IP address||discarding
.display asis
ignore_target_hosts = 127.0.0.1
.endd
-on the relevant router.
-.em
-If all the hosts found by a \%dnslookup%\ router are discarded in this way, the
-router declines. In a conventional configuration, an attempt to mail to such a
-domain would then normally provoke the `unrouteable domain' error, and an
-attempt to verify an address in the domain would fail.
+on the relevant router. If all the hosts found by a \%dnslookup%\ 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 `unrouteable
+domain' error, and an attempt to verify an address in the domain would fail.
Similarly, if \ignore@_target@_hosts\ is set on an \%ipliteral%\ router, the
router declines if presented with one of the listed addresses.
-.nem
This option may also be useful for ignoring link-local and site-local IPv6
addresses. Because, like all host lists, the value of \ignore@_target@_hosts\
is expanded before use as a list, it is possible to make it dependent on the
domain that is being routed.
+.em
+During its expansion, \$host@_address$\ is set to the IP address that is being
+checked.
+.nem
running, the prefix is removed from the local part, and is available in the
expansion variable \$local@_part@_prefix$\. If the router accepts the address,
this remains true during subsequent delivery.
-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 \rcpt@_include@_affixes\ true on the
+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 \rcpt@_include@_affixes\ true on the
relevant transport.
The prefix facility is commonly used to handle local parts of the form
.index router||restricting to specific local parts
.index local part||checking in router
The router is run only if the local part of the address matches the list.
-See section ~~SECTrouprecon for a list of the order in which preconditions
+See section ~~SECTrouprecon for a list of the order in which preconditions
are evaluated, and
section ~~SECTlocparlis for a discussion of local part lists. Because the
string is expanded, it is possible to make it depend on the domain, for
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 \require@_files\ list, expanding each item separately.
+through the \require@_files\ list, expanding each item separately.
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.
-If any expansion is forced to fail, the item is ignored. Other expansion
+If any expansion is forced to fail, the item is ignored. Other expansion
failures cause routing of the address to be deferred.
If any expanded string is empty, it is ignored. Otherwise, except as described
transport (for example \(.procmailrc)\).
During delivery, the \*stat()*\ function is run as root, but there is a
-facility for some checking of the accessibility of a file by another user.
+facility for some checking of the accessibility of a file by another user.
This is not a proper permissions check, but just a `rough' check that
operates as follows:
may yield the error \\EACCES\\ (`Permission denied'). This means that the Exim
user is not permitted to read one of the directories on the file's path.
-\**Warning 2**\: Even when Exim is running as root while delivering a message,
-\*stat()*\ can yield \\EACCES\\ for a file on an NFS directory that is mounted
+\**Warning 2**\: Even when Exim is running as root while delivering a message,
+\*stat()*\ can yield \\EACCES\\ for a file in an NFS directory that is mounted
without root access.
+.em
+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.
-In both cases,
-the default action is to consider this 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 file name (or the exclamation
-mark that precedes the file name for non-existence) is preceded by a plus sign,
-the \\EACCES\\ error is treated as if the file did not exist. For example:
+The default action for handling an unresolved \\EACCES\\ is to consider it to
+be caused by a configuration error,
+.nem
+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 file name (or the
+exclamation mark that precedes the file name for non-existence) is preceded by
+a plus sign, the \\EACCES\\ error is treated as if the file did not exist. For
+example:
.display asis
require_files = +/some/file
.endd
If the router is not an essential part of verification (for example, it
-handles users' \(.forward)\ files), another solution is to set the \verify\
+handles users' \(.forward)\ files), another solution is to set the \verify\
option false so that the router is skipped when verifying.
for transport delays; they are controlled by a generic transport option of the
same name.
-.em
-The setting of \retry@_use@_local@_part\ applies only to the router on which it
-appears. If the router generates child addresses, they are routed
+The setting of \retry@_use@_local@_part\ 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.
-.nem
.conf router@_home@_directory string$**$ unset
Expansion of \router@_home@_directory\ happens immediately after the
\check@_local@_user\ test (if configured), before any further expansions take
-place.
+place.
(See section ~~SECTrouprecon for a list of the order in which preconditions
are evaluated.)
While the router is running, \router__home@_directory\ overrides the value of
.index local host||MX pointing to
This option applies to those routers that use a recipient address to find a
list of remote hosts. Currently, these are the \%dnslookup%\, \%ipliteral%\,
-and \%manualroute%\ routers.
+and \%manualroute%\ routers.
Certain configurations of the \%queryprogram%\ router can also specify a list
of remote hosts.
Usually such routers are configured to send the message to a remote host via an
.conf senders "address list$**$ (precondition)" unset
.index router||checking senders
If this option is set, the router is skipped unless the message's sender
-address matches something on the list.
-See section ~~SECTrouprecon for a list of the order in which preconditions
+address matches something on the list.
+See section ~~SECTrouprecon for a list of the order in which preconditions
are evaluated.
There are issues concerning verification when the running of routers is
The \translate@_ip@_address\ string is expanded for every IP address generated
by the router, with the generated address set in \$host@_address$\. If the
-expansion is forced to fail, no action is taken.
+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
.conf transport string$**$ unset
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 \errors@_to\,
-\headers@_add\, and \headers@_remove\,
-and result must be the name of one of the configured transports. If it is
-not, delivery is deferred.
+only for verification. The value of the option is expanded at routing time,
+after the expansion of \errors@_to\, \headers@_add\, and \headers@_remove\, and
+result must be the name of one of the configured transports. If it is not,
+delivery is deferred.
The \transport\ option is not used by the \%redirect%\ router, but it does have
some private options that set up transports for pipe and file deliveries (see
\transport@_home@_directory\ is not set for the router, the home directory for
the tranport is taken from the password data if \check@_local@_user\ is set for
the router. Otherwise it is taken from \router@_home@_directory\ if that option
-is set; if not, no home directory is set for the transport.
+is set; if not, no home directory is set for the transport.
See chapter ~~CHAPenvironment for further details of the local delivery
environment.
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 \more\. There is little point in setting \more\
-false if \unseen\ is always true, but it may be useful in cases when the value
+overriding a false setting of \more\. There is little point in setting \more\
+false if \unseen\ is always true, but it may be useful in cases when the value
of \unseen\ contains expansion items (and therefore, presumably, is sometimes
true and sometimes false).
The \unseen\ option can be used to cause
.index copy of message (\unseen\ option)
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
-`parent' that has two children -- one that is delivered as specified by this
+carrying out a normal delivery. In effect, the current address is made into a
+`parent' that has two children -- one that is delivered as specified by this
router, and a clone that goes on to be routed further.
Header lines added to the address (or specified for removal) by this router or
by previous routers affect the `unseen' copy of the message only. The clone
-that continues to be processed by further routers starts with no added headers
+that continues to be processed by further routers starts with no added headers
and none specified for removal.
However, any data that was set by the \address@_data\ option in the current or
.index filter||user for processing
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
+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 \%redirect%\ router when running a filter file.
The default is unset, except when \check@_local@_user\ is set. In this case,
and \verify@_recipient\.
\**Warning**\: 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
+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.
.conf verify@_recipient "boolean (precondition)" true
If this option is false, the router is skipped when verifying recipient
addresses
or testing recipient verification using \-bv-\.
-See section ~~SECTrouprecon for a list of the order in which preconditions
+See section ~~SECTrouprecon for a list of the order in which preconditions
are evaluated.
.conf verify@_sender "boolean (precondition)" true
If this option is false, the router is skipped when verifying sender addresses
or testing sender verification using \-bvs-\.
-See section ~~SECTrouprecon for a list of the order in which preconditions
+See section ~~SECTrouprecon for a list of the order in which preconditions
are evaluated.
.endconf
.set runningfoot "dnslookup router"
.index \%dnslookup%\ router
.index routers||\%dnslookup%\
-The \%dnslookup%\ router looks up the hosts that handle mail for the given
-domain in the DNS. A transport must always be set for this router, unless
-\verify@_only\ is set.
+The \%dnslookup%\ 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 \verify@_only\ is set.
-.em
-If SRV support is configured (see \check@_srv\ below), Exim first searches for
+If SRV support is configured (see \check@_srv\ 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, \mx@_domains\ can be set to disable the direct use of address records.
Unless they have the highest priority (lowest MX value), MX records that point
to the local host, or to any host name that matches \hosts__treat__as__local\,
are discarded, together with any other MX records of equal or lower priority.
-.nem
.index MX record||pointing to local host
.index local host||MX pointing to
address record, is the local host, or matches \hosts__treat__as__local\, what
happens is controlled by the generic \self\ option.
-There are a number of private options that can be used to vary the way the DNS
-lookup is handled.
+.em
+.section Problems with DNS lookups
+.rset SECTprowitdnsloo "~~chapter.~~section"
+There have been problems with DNS servers when SRV records are looked up.
+Some mis-behaving 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 \dns@_again@_means@_nonexist\ option can help with this
+problem, but it is heavy-handed because it is a global option.
+
+For this reason, there are two options, \srv@_fail@_domains\ and
+\mx@_fail@_domains\, that control what happens when a DNS lookup in a
+\%dnslookup%\ router results in a DNS failure or a `try again' 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 `no
+such record'. 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 \mx@_domains\, in which case routing
+fails.
+.nem
+
+.section Private options for dnslookup
+The private options for the \%dnslookup%\ router are as follows:
+
+
+.startconf dnslookup
-.startconf
.index options||\%dnslookup%\ router
.conf check@_secondary@_mx boolean false
.index MX record||checking for secondary
differently to other domains. The way in which Exim decides whether a host is
the local host is described in section ~~SECTreclocipadd.
-.em
.conf check@_srv string$**$ unset
.index SRV record||enabling use of
-The dnslookup router supports the use of SRV records (see RFC 2782) in
+The \%dnslookup%\ 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 \check@_srv\ option to the name of the service
required. For example,
normal way.
When the expansion succeeds, the router searches first for SRV records for
-the given service (it assumes TCP protocol). A single SRV record with the
-host name \"."\ indicates `no such service for this domain'; 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.
-
-However, 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 `weight' feature which
-some people might find useful when trying to split an SMTP load between
-hosts of different power.
+the given service (it assumes TCP protocol). A single SRV record with a
+host name that consists of just a single dot indicates `no such service for
+this domain'; 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.
+
+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 `weight' feature which some people might find useful when
+trying to split an SMTP load between hosts of different power.
+
+.em
+See section ~~SECTprowitdnsloo above for a discussion of Exim's behaviour when
+there is a DNS lookup error.
.nem
.conf mx@_domains "domain list$**$" unset
.index MX record||required to exist
.index SRV record||required to exist
-.em
A domain that matches \mx@_domains\ is required to have either an MX or an SRV
record in order to be recognised. (The name of this option could be improved.)
-.nem
For example, if all the mail hosts in \*fict.example*\ are known to have MX
records, except for those in \*discworld.fict.example*\, you could use this
setting:
has no MX record should be bounced immediately instead of being routed using
the address record.
+.em
+.conf mx@_fail@_domains "domain list$**$" unset
+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
+~~SECTprowitdnsloo for more discussion.
+.nem
+
+
.conf qualify@_single boolean true
.index DNS||resolver options
.index DNS||qualifying single-component names
without processing them independently,
provided the following conditions are met:
.numberpars $.
-No router that processed the address specified \headers@_add\ or
+No router that processed the address specified \headers@_add\ or
\headers@_remove\.
.nextp
-The router did not change the address in any way, for example, by `widening'
+The router did not change the address in any way, for example, by `widening'
the domain.
.endp
record, because any domain that does not have its own MX record matches the
local wildcard.
+
+.em
+.conf srv@_fail@_domains "domain list$**$" unset
+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
+~~SECTprowitdnsloo for more discussion.
+.nem
+
+
.conf widen@_domains "string list" unset
.index domain||partial, widening
If a DNS lookup fails and this option is set, each of its strings in turn is
.endconf
-.em
.section Effect of qualify@_single and search@_parents
-When a domain from an envelope recipient is changed by the resolver as a result
+When a domain from an envelope recipient is changed by the resolver as a result
of the \qualify@_single\ or \search@_parents\ options, Exim rewrites the
corresponding address in the message's header lines unless \rewrite@_headers\
is set false. Exim then re-routes the address, using the full domain.
.endd
that may happen while processing a router precondition before the router is
entered. No widening ever takes place for these lookups.
-.nem
.chapter The ipliteral router
.set runningfoot "ipliteral router"
.index \%ipliteral%\ router
-.index domain literal||routing
+.index domain literal||routing
.index routers||\%ipliteral%\
This router has no private options. Unless it is being used purely for
verification (see \verify@_only\) a transport is required to be defined by the
.display asis
root@[192.168.1.1]
.endd
-by setting up delivery to the host with that IP address.
+by setting up delivery to the host with that IP address.
-.em
-If the IP address matches something in \ignore@_target@_hosts\, the router
+If the IP address matches something in \ignore@_target@_hosts\, the router
declines.
-.nem
.index \self\ option||in \%ipliteral%\ router
If an IP literal turns out to refer to the local host, the generic \self\
-option determines what happens.
+option determines what happens.
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
.index \%iplookup%\ router
.index routers||\%iplookup%\
The \%iplookup%\ router was written to fulfil a specific requirement in
-Cambridge University. For this reason, it is not included in the binary of Exim
-by default. If you want to include it, you must set
+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
.display asis
ROUTER_IPLOOKUP=yes
.endd
Since \%iplookup%\ is just a rewriting router, a transport must not be
specified for it.
-.startconf
+.startconf iplookup
.index options||\%iplookup%\ router
.conf hosts string unset
This option must be supplied. Its value is a colon-separated list of host
-names. The hosts are looked up using \*gethostbyname()*\
+names. The hosts are looked up using \*gethostbyname()*\
(or \*getipnodebyname()*\ when available)
and are tried in order until one responds to the query. If none respond, what
happens is controlled by \optional\.
The private options for the \%manualroute%\ router are as follows:
-.startconf
+.startconf manualroute
.index options||\%manualroute%\ router
.conf host@_find@_failed string "freeze"
dict.ref.example mail-1.ref.example:mail-2.ref.example ; \
thes.ref.example mail-3.ref.example:mail-4.ref.example
.endd
-The three parts of a rule are separated by white space. The pattern and the
+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 \route@_list\ 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
-~~SECTdomainlist),
+~~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
.endp
-.em
.section How the list of hosts is used
-When an address is routed to an \%smtp%\ transport by \%manualroute%\, each of
+When an address is routed to an \%smtp%\ transport by \%manualroute%\, 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 \hosts@_randomize\
option, either on the router (see section ~~SECTprioptman above), or on the
route_list = * x.y.z:p.q.r/MX:e.f.g
.endd
If the \hosts@_randomize\ 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 \"/MX"\ it looks up an IP address. If this turns out to
+randomized before any lookups are done. Exim then scans the list; for any name
+that is not followed by \"/MX"\ 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
+happens is controlled by the
.index \self\ option||in \%manualroute%\ router
\self\ option of the router.
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.
-.nem
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
failures when looking up IP addresses: \pass@_on@_timeout\ and
\host@_find@_failed\ are used when relevant.
-.em
The generic \ignore@_target@_hosts\ option applies to all hosts in the list,
whether obtained from an MX lookup or not.
-.nem
.section How the options are used
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:
.numberpars $.
-\randomize\: randomize the order of the hosts in this list, overriding the
+\randomize\: randomize the order of the hosts in this list, overriding the
setting of \hosts@_randomize\ for this routing rule only.
.nextp
\no@_randomize\: do not randomize the order of the hosts in this list,
also look in \(/etc/hosts)\ or other sources of information.
.nextp
\bydns\: 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.
+no address records are found. If there is a temporary DNS error (such as a
+timeout), delivery is deferred.
.endp
For example:
.display asis
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:
-.startconf
+.startconf queryprogram
.index options||\%queryprogram%\ router
.conf command string$**$ unset
This option must be set. It specifies the command that is to be run. The
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 first field is one
-of the following words (case-insensitive):
+containing up to five fields, separated by white space.
+.em
+The maximum length of the line is 1023 characters. Longer lines are silently
+truncated.
+.nem
+The first field is one of the following words (case-insensitive):
.numberpars $.
\*Accept*\: routing succeeded; the remaining fields specify what to do (see
below).
The list of hosts and the lookup type are needed only if the transport is an
\%smtp%\ transport that does not itself supply a list of hosts.
-The format of the list of hosts is the same as for the \%manualroute%\ router.
+The format of the list of hosts is the same as for the \%manualroute%\ router.
As well as host names and IP addresses, it may contain names followed by
\"/MX"\ to specify sublists of hosts that are obtained by looking up MX
records.
-If the lookup type is not specified, Exim behaves as follows when trying to
+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 \*getipnodebyname()*\ or \*gethostbyname()*\, and the
.display asis
accept hosts=x1.y.example:x2.y.example data="rule1"
.endd
-routes the address to the default transport, with a host list containing two
-hosts. When the transport runs, the string `rule1' is in \$address@_data$\.
+routes the address to the default transport, passing a list of two hosts. When
+the transport runs, the string `rule1' is in \$address@_data$\.
driver = redirect
data = ${lookup{$local_part}lsearch{/etc/aliases}}
.endd
-.em
-If the lookup fails, the expanded string in this example is empty. When the
+If the lookup fails, the expanded string in this example is empty. When the
expansion of \data\ 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.
-.nem
A configuration using \file\ is commonly used for handling users' \(.forward)\
files, like this:
\(.forward)\ files, as in the example above. There are two reasons for this:
.numberpars $.
When Exim is receiving an incoming SMTP message from a remote host, it is
-running under the Exim uid, not as root.
-No additional groups are set up, even if the Exim uid is a member of other
+running under the Exim uid, not as root.
+No additional groups are set up, even if the Exim uid is a member of other
groups (that is, the \*initgroups()*\ function is not run).
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
Otherwise, the data must be a comma-separated list of redirection items, as
described in the next section.
.endp
-When a message is redirected to a file (a `mail folder'), the file name 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 ~~SECTfildiropt for a discussion of this issue for
+When a message is redirected to a file (a `mail folder'), the file name 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 ~~SECTfildiropt for a discussion of this issue for
the \%appendfile%\ transport.
(but never to enclose the entire address). In the following description, `item'
refers to what remains after any surrounding double quotes have been removed.
-\**Warning**\: If you use an Exim expansion to construct a redirection address,
-and the expansion contains a reference to \$local@_part$\, you should make use
-of the \quote\ expansion operator, in case the local part contains special
-characters. For example, to redirect all mail for the domain
-\*obsolete.example*\, retaining the existing local part, you could use this
+\**Warning**\: If you use an Exim expansion to construct a redirection address,
+and the expansion contains a reference to \$local@_part$\, you should make use
+of the \quote\ expansion operator, in case the local part contains special
+characters. For example, to redirect all mail for the domain
+\*obsolete.example*\, retaining the existing local part, you could use this
setting:
.display asis
data = ${quote:$local_part}@newdomain.example
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
-.em
-is the same as the current address and was processed by the current router.
-.nem
+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.
addresses are qualified using the value in \qualify@_recipient\, but you can
force the incoming domain to be used by setting \qualify__preserve@_domain\.
-Care must be taken if there are alias names for local users.
-.em
+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:
.display asis
Sam.Reman: spqr
.endd
Now suppose that Sam (whose login id is \*spqr*\) wants to save copies of
-messages in the local mailbox, and also forward copies elsewhere. He creates
+messages in the local mailbox, and also forward copies elsewhere. He creates
this forward file:
.display asis
Sam.Reman, spqr@reme.elsewhere.example
.endd
With these settings, an incoming message addressed to \*Sam.Reman*\ fails. The
\%redirect%\ router for system aliases does not process \*Sam.Reman*\ the
-second time round, because it has previously routed it,
-.nem
+second time round, because it has previously routed it,
and the following routers presumably cannot handle the alias. The forward file
should really contain
.display asis
.index address redirection||to pipe
An item is treated as a pipe command if it begins with `|' 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 \pipe@_transport\ option.
-.em
+command must be specified by the \pipe@_transport\ 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.
-.nem
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
forward slash character, it is interpreted as a directory name rather than a
file name, and \directory@_transport\ is used instead.
-.em
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.
.index \(/dev/null)\
However, if a redirection item is the path \(/dev/null)\, delivery to it is
bypassed at a high level, and the log entry shows `$*$$*$bypassed$*$$*$'
instead of a transport name. In this case the user and group are not used.
-.nem
.nextp
.index included address list
.index address redirection||included external list
:include:<<path name>>
.endd
a list of further items is taken from the given file and included at that
-point.
-\**Note**\: such a file can not be a filter file; it is just an out-of-line
+point.
+\**Note**\: 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
message is generated. This has the same effect as specifing \(/dev/null)\, but
can be independently disabled.
-\**Warning**\: If \":blackhole:"\ 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
+\**Warning**\: If \":blackhole:"\ 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
\(/dev/null)\.
.nextp
X.Employee: :fail: Gone away, no forwarding address
.endd
In the case of an address that is being verified from an ACL or as the subject
-of a \\VRFY\\ command, the text is included in the SMTP error response by
-default. In an ACL, an explicitly provided message overrides the default, but
-the default message is available in the variable \$acl@_verify@_message$\ and
-can therefore be included in a custom message if this is desired. Exim sends a
-451 SMTP code for a :::defer::, and 550 for :::fail::. In non-SMTP cases the
-text is included in the error message that Exim generates.
+of a
+.index \\VRFY\\||error text, display of
+\\VRFY\\ command, the text is included in the SMTP error response by
+default.
+.em
+.index \\EXPN\\||error text, display of
+The text is not included in the response to an \\EXPN\\ command.
+.nem
+
+In an ACL, an explicitly provided message overrides the default, but the
+default message is available in the variable \$acl@_verify@_message$\ and can
+therefore be included in a custom message if this is desired. Exim sends a 451
+SMTP code for a :::defer::, and 550 for :::fail::. In non-SMTP cases the text
+is included in the error message that Exim generates.
The private options for the \%redirect%\ router are as follows:
-.startconf
+.startconf redirect
.index options||\%redirect%\ router
.conf allow@_defer boolean false
Setting this option allows Exim to interpret redirection data that starts with
`@#Exim filter' or `@#Sieve filter' as a set of filtering instructions. There
are some features of Exim filter files that some administrators may wish to
-lock out; see the \forbid@_filter@_xxx\ options below. The filter is run using
-the uid and gid set by the generic \user\ and \group\ options. These take their
-defaults from the password data if \check@_local@_user\ is set, so in the
-normal case of users' personal filter files, the filter is run as the relevant
-user. When \allow@_filter\ is set true, Exim insists that either
-\check@_local@_user\ or \user\ is set.
+lock out; see the \forbid@_filter@_xxx\ options below.
+.em
+It is also possible to lock out Exim filters or Sieve filters while allowing
+the other type; see \forbid@_exim@_filter\ and \forbid@_sieve@_filter\.
+.nem
+
+The filter is run using the uid and gid set by the generic \user\ and \group\
+options. These take their defaults from the password data if
+\check@_local@_user\ is set, so in the normal case of users' personal filter
+files, the filter is run as the relevant user. When \allow@_filter\ is set
+true, Exim insists that either \check@_local@_user\ or \user\ is set.
.conf allow@_freeze boolean false
configuration file for handling users' \(.forward)\ files. It is recommended
for this use of the \%redirect%\ router.
-.em
When \check@_ancestor\ 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 \(.forward)\ file pointing back to A. For example, within a single
+and B has a \(.forward)\ file pointing back to A. For example, within a single
domain, the local part `Joe.Bloggs' is aliased to `jb' and \(@~jb/.forward)\
contains:
-.nem
.display
@\Joe.Bloggs, <<other item(s)>>
.endd
A \%redirect%\ router sets up a direct delivery to a file when a path name not
ending in a slash is specified as a new `address'. The transport used is
specified by this option, which, after expansion, must be the name of a
-configured transport.
+configured transport.
This should normally be an \%appendfile%\ transport.
When it is running, the file name is in \$address@_file$\.
If this option is true, the :::blackhole:: item may not appear in a redirection
list.
+.em
+.conf forbid@_exim@_filter boolean false
+If this option is set true, only Sieve filters are permitted when
+\allow@_filter\ is true.
+.nem
+
+
.conf forbid@_file boolean false
.index delivery||to file, forbidding
.index Sieve filter||forbidding delivery to a file
.conf forbid@_filter@_reply boolean false
If this option is true, this router may not generate an automatic reply
-message. Automatic replies can be generated only from Exim filter files, not
-from traditional forward files or Sieve filters. This option is forced to be
-true if \one@_time\ is set.
+message. Automatic replies can be generated only from Exim
+.em
+or Sieve filter files, not from traditional forward files.
+.nem
+This option is forced to be true if \one@_time\ is set.
.conf forbid@_filter@_run boolean false
If this option is true, string expansions in Exim filter files are not allowed
specifies delivery to a pipe, either from an Exim filter or from a conventional
forward file. This option is forced to be true if \one@_time\ is set.
+.em
+.conf forbid@_sieve@_filter boolean false
+If this option is set true, only Exim filters are permitted when
+\allow@_filter\ is true.
+.nem
+
+
.conf hide@_child@_in@_errmsg boolean false
.index bounce message||redirection details, suppressing
If this option is true, it prevents Exim from quoting a child address if it
.index address redirection||one-time expansion
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
+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
list is in addition to the local user's primary group when \check@_local@_user\
is set. See \check@_group\ above.
-.em
-.conf qualify@_domain string$**$ unset
-If this option is set and an unqualified address (one without a domain) is
-generated, it is qualified with the domain specified by expanding this string,
-instead of the global setting in \qualify@_recipient\. If the expansion fails,
-the router declines. If you want to revert to the default, you can have the
-expansion generate \$qualify@_recipient$\.
-.nem
-
.conf pipe@_transport string$**$ unset
A \%redirect%\ router sets up a direct delivery to a pipe when a string starting
with a vertical bar character is specified as a new `address'. The transport
used is specified by this option, which, after expansion, must be the name of a
-configured transport.
+configured transport.
This should normally be a \%pipe%\ transport.
When the transport is run, the pipe command is in \$address@_pipe$\.
+.conf qualify@_domain string$**$ unset
+If this option is set and an unqualified address (one without a domain) is
+generated, it is qualified with the domain specified by expanding this string,
+instead of the global setting in \qualify@_recipient\. If the expansion fails,
+the router declines. If you want to revert to the default, you can have the
+expansion generate \$qualify@_recipient$\.
+
.conf qualify@_preserve@_domain boolean false
.index domain||in redirection, preserving
.index preserving domain in redirection
.index address redirection||domain, preserving
If this is set and an unqualified address (one without a domain) is generated,
-it is qualified with the domain of the
-.em
+it is qualified with the domain of the
parent address (the immediately preceding ancestor) instead of the local
\qualify@_domain\ or global \qualify@_recipient\ value.
-.nem
.conf repeat@_use boolean true
If this option is set false, the router is skipped for a child address that has
A \%redirect%\ router sets up an automatic reply when a \mail\ or \vacation\
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 \%autoreply%\ transport. Other transports are
+This should normally be an \%autoreply%\ transport. Other transports are
unlikely to do anything sensible or useful.
.conf rewrite boolean true
subject to address rewriting. Otherwise, they are treated like new addresses
and are rewritten according to the global rewriting rules.
+
+.em
+.conf sieve@_vacation@_directory string$**$ unset
+.index Sieve filter||vacation directory
+To enable the `vacation' extension for Sieve filters, you must set
+\sieve@_vacation@_directory\ to the directory where vacation databases are held
+(do not put anything else in that directory), and ensure that the
+\reply@_transport\ option refers to an \%autoreply%\ transport.
+.nem
+
+
.conf skip@_syntax@_errors boolean false
.index forward file||broken
.index address redirection||broken files
so it is passed to the following routers.
.index Sieve filter||syntax errors in
-Currently, any syntax errors in a Sieve filter file cause the `keep' action to
-occur. The values of \skip@_syntax@_errors\, \syntax@_errors@_to\, and
+.em
+Syntax errors in a Sieve filter file cause the `keep' action to
+occur. This action is specified by RFC 3028.
+.nem
+The values of \skip@_syntax@_errors\, \syntax@_errors@_to\, and
\syntax@_errors@_text\ are not used.
\skip@_syntax@_errors\ can be used to specify that errors in users' forward
Exim also sets a specific current directory while running the transport; for
some transports a home directory setting is also relevant. The \%pipe%\
-transport is the only one which sets up environment variables; see section
+transport is the only one that sets up environment variables; see section
~~SECTpipeenv for details.
The values used for the uid, gid, and the directories may come from several
\user\ options. However, values may also be given in the transport's own
configuration, and these override anything that comes from the router.
+
+.em
+.section Concurrent deliveries
+.index concurrent deliveries
+.index simultaneous deliveries
+If two different messages for the same local recpient arrive more or less
+simultaneously, the two delivery processes are likely to run concurrently. When
+the \%appendfile%\ 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.
+
+However, when you use a \%pipe%\ transport, it is up to you to arrange any
+locking that is needed. Here is a silly example:
+.display asis
+my_transport:
+ driver = pipe
+ command = /bin/sh -c 'cat >>/some/file'
+.endd
+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
+\exim@_lock\ utility program (see section ~~SECTmailboxmaint) to lock a file
+using the same algorithm that Exim itself uses.
+.nem
+
+
.section Uids and gids
.rset SECTenvuidgid "~~chapter.~~section"
.index local transports||uid and gid
local_users:
driver = accept
check_local_user
- transport = group_delivery
+ transport = group_delivery
# Transports ...
# This transport overrides the group
.index transport||generic options for
The following generic options apply to all transports:
-.startconf
+.startconf transports
.conf body@_only boolean false
.index transport||body only
.index message||transporting body only
logged, and delivery is deferred.
.conf disable@_logging boolean false
-If this option is set true, nothing is logged for any
-.em
-deliveries by the transport or for any
-.nem
+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.
.index testing||variables in drivers
If this option is set and debugging is enabled (see the \-d-\ 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
+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 \headers@_add\
.conf headers@_add string$**$ unset
.index header lines||adding in transport
.index transport||header lines, adding
-This option specifies a string of text which is expanded and added to the
-header portion of a message as it is transported. 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. The expanded string should be in the form of one or more RFC
-2822 header lines, separated by newlines (coded as `@\n'), for example:
-.display asis
-headers_add = X-added: this is a header added at $tod_log\n\
- X-added: this is another
-.endd
-Exim does not check the syntax of these added header lines. They are added at
-the end of the existing header lines. If you include a blank line within the
-string, you can subvert this facility into adding text at the start of the
-message's body. This is not recommended. Additional header lines can also be
-specified by routers. See chapter ~~CHAProutergeneric and section
-~~SECTheadersaddrem.
+.em
+This option specifies a string of text that is expanded and added to the header
+portion of a message as it is transported, as described in section
+~~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.
+.nem
.conf headers@_only boolean false
.index transport||header lines only
.conf headers@_remove string$**$ unset
.index header lines||removing
.index transport||header lines, removing
-This option is expanded; the result must consist of a colon-separated list of
-header names, not including the terminating colon, for example:
-.display asis
-headers_remove = return-receipt-to:acknowledge-to
-.endd
-Any existing headers matching those names are not included in any message that
-is transmitted by the transport.
-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
+.em
+This option specifies a string that is expanded into a list of header names;
+these headers are omitted from the message as it is transported, as described
+in section ~~SECTheadersaddrem. Header removal 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.
-
-If there are multiple instances of a header, they are all removed. However,
-added headers may have these names. Thus it is possible to replace a header by
-specifying it in \headers@_remove\ and supplying the replacement in
-\headers@_add\. Headers to be removed can also be specified by routers. See
-chapter ~~CHAProutergeneric and section ~~SECTheadersaddrem.
+.nem
.conf headers@_rewrite string unset
.index transport||header lines, rewriting
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 digits,
optionally followed by K or M.
-If the expansion fails for any reason, including forced failure, or if the
+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
option can be used to support VERP (Variable Envelope Return Paths) -- see
chapter ~~CHAPSMTP.
-\**Note**\: If a delivery error is detected locally,
-.em
+\**Note**\: 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, but to the
previously set errors address (which defaults to the incoming sender address).
-.nem
.conf return@_path@_add boolean false
\shadow@_condition\ is unset, or its expansion does not result in the empty
string or one of the strings `0' or `no' or `false', 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
+If expansion fails, no action is taken except that non-forced expansion
failures cause a log line to be written.
The result of the shadow transport is discarded and does not affect the
(this in fact is done from a third process, to avoid deadlock).
The command must be specified as an absolute path.
+.em
+The lines of the message that are written to the transport filter are
+terminated by newline (`@\n').
+.nem
The message is passed to the filter before any SMTP-specific processing, such
as turning `@\n' into `@\r@\n' and escaping lines beginning with a dot, and
also before any processing implied by the settings of \check@_string\ and
\escape@_string\ in the \%appendfile%\ or \%pipe%\ transports.
-The filter's standard output is read and written to the message's destination.
+.em
+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.
+.nem
The filter can perform any transformations it likes, but of course should take
care not to break RFC 2822 syntax. A demonstration Perl script is provided in
\(util/transport-filter.pl)\; this makes a few arbitrary modifications just to
the \size@_addition\ option on the \%smtp%\ transport, either to allow for
additions to the message, or to disable the use of \\SIZE\\ altogether.
-The value of the option is the command string for starting up 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 \%pipe%\ transport: Exim breaks it up
-into arguments and then expands each argument separately. The special argument
-\$pipe@_addresses$\ 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 \%pipe%\ transport, it seemed sensible
-not to change it.)
+The value of the \transport@_filter\ 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 \%pipe%\ transport:
+Exim breaks it up into arguments and then expands each argument separately. The
+special argument \$pipe@_addresses$\ 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 \%pipe%\
+transport, it seemed sensible not to change it.)
.index \$host$\
.index \$host@_address$\
.endd
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.
+.em
+The command should normally yield a zero return code. A non-zero code is taken
+to mean that the transport filter failed in some way. Delivery of the message
+is deferred. It is not possible to cause a message to be bounced from a
+transport filter.
+.nem
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
.conf transport@_filter@_timeout time 5m
.index transport||filter, timeout
-When Exim is reading the output of a transport filter, it a applies a timeout
-that can be set by this option. Exceeding the timeout is treated as a
+When Exim is reading the output of a transport filter, it a applies a timeout
+that can be set by this option. Exceeding the timeout is treated as a
temporary delivery failure.
associated group is taken as the value of the gid to be used if the \group\
option is not set.
-.em
For deliveries that use local transports, a user and group are normally
specified explicitly or implicitly (for example, as a result of
\check@_local@_user\) by the router or transport.
-.nem
.index hints database||access by remote transport
For remote transports, you should leave this option unset unless you really are
In an \%lmtp%\ transport, when delivering over `local SMTP' to some process,
a single copy saves time, and is the normal way LMTP is expected to work.
.nextp
-In a \%pipe%\ transport, when passing the message
-to a scanner program or
+In a \%pipe%\ transport, when passing the message
+to a scanner program or
to some other delivery mechanism such as UUCP, multiple recipients may be
acceptable.
.endp
If \batch@_id\ 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.
+Failure of the expansion for any reason, including forced failure, disables
+batching, but it does not stop the delivery from taking place.
.nextp
Batched addresses must also have the same errors address (where to send
delivery errors), the same header additions and removals, the same user and
\use@_bsmtp\ option, because it always delivers using the SMTP protocol.
.index \%pipe%\ transport||with multiple addresses
-If you are not using BSMTP, but are using a \%pipe%\ transport, you can include
-\$pipe@_addresses$\ 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
+If you are not using BSMTP, but are using a \%pipe%\ transport, you can include
+\$pipe@_addresses$\ 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.
If you are using a batching \%appendfile%\ transport without \use@_bsmtp\, the
only way to preserve the recipient addresses is to set the \envelope@_to@_add\
-option. This causes an ::Envelope-to:: header line to be added to the message,
+option. This causes an ::Envelope-to:: header line to be added to the message,
containing all the recipients.
\%appendfile%\ 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. `Batch SMTP'
-format is often used in this case (see the \use@_bsmtp\ option).
+format is often used in this case (see the \use@_bsmtp\ option).
.section The file and directory options
.rset SECTfildiropt "~~chapter.~~section"
-The \file\ option specifies a single file, to which the message is appended;
-the \directory\ option specifies a directory, in which a new file containing
+The \file\ option specifies a single file, to which the message is appended;
+the \directory\ 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 \*must*\ be set.
operation. There are two cases:
.numberpars $.
If neither \file\ nor \directory\ is set, the redirection operation
-must specify an absolute path (one that begins with \"/"\). This is the most
-common case when users with local accounts use filtering to sort mail into
+must specify an absolute path (one that begins with \"/"\). This is the most
+common case when users with local accounts use filtering to sort mail into
different folders. See for example, the \%address@_file%\ 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
+name of a directory. A delivery to a directory can also be forced by setting
\maildir@_format\ or \mailstore@_format\.
.nextp
If \file\ or \directory\ 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 \$address@_file$\ are used in some way in the string expansion.
+contents of \$address@_file$\ are used in some way in the string expansion.
.endp
.index Sieve filter||configuring \%appendfile%\
.endd
or Sieve filter commands of the form:
.display asis
-require "fileinto";
+require "fileinto";
fileinto "folder23";
.endd
In this situation, the expansion of \file\ or \directory\ in the transport must
-transform the relative path into an appropriate absolute file name. In the case
-of Sieve filters, the name \*inbox*\ must be handled. It is the name that is
-used as a result of a `keep' action in the filter. This example shows one way
+transform the relative path into an appropriate absolute file name. In the case
+of Sieve filters, the name \*inbox*\ must be handled. It is the name that is
+used as a result of a `keep' action in the filter. This example shows one way
of handling this requirement:
.display asis
file = ${if eq{$address_file}{inbox} \
}} \
}
.endd
-With this setting of \file\, \*inbox*\ refers to the standard mailbox location,
+With this setting of \file\, \*inbox*\ refers to the standard mailbox location,
absolute paths are used without change, and other folders are in the \(mail)\
directory within the home directory.
.section Private options for appendfile
.index options||\%appendfile%\ transport
-.startconf
+.startconf appendfile
.conf allow@_fifo boolean false
.index fifo (named pipe)
.conf batch@_id string$**$ unset
See the description of local delivery batching in chapter ~~CHAPbatching.
-However, batching is automatically disabled for \%appendfile%\ deliveries that
-happen as a result of forwarding or aliasing or other redirection directly to a
+However, batching is automatically disabled for \%appendfile%\ deliveries that
+happen as a result of forwarding or aliasing or other redirection directly to a
file.
.conf batch@_max integer 1
If \use@_bsmtp\ is set the values of \check@_string\ and \escape@_string\ are
forced to `.' and `..' respectively, and any settings in the configuration are
ignored. Otherwise, they default to `From ' and `>From ' when the \file\ option
-is set, and unset when
+is set, and unset when
any of the \directory\, \maildir\, or \mailstore\ options are set.
The default settings, along with \message@_prefix\ and \message@_suffix\, are
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 \directory@_mode\ option.
+.em
+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.
+.nem
.conf create@_file string "anywhere"
This option constrains the location of files and directories that are created
exists and is older than this value, it is assumed to have been left behind by
accident, and Exim attempts to remove it.
+.em
+.conf mailbox@_filecount string$**$ unset
+.index mailbox||specifying size of
+.index size||of mailbox
+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.
+
+.conf mailbox@_size string$**$ unset
+.index mailbox||specifying size of
+.index size||of mailbox
+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.
+.nem
+
.conf maildir@_format boolean false
.index maildir format||specifying
If this option is set with the \directory\ option, the delivery is into a new
\\SUPPORT@_MAILDIR\\ is present in \(Local/Makefile)\. See section
~~SECTmaildirdelivery below for further details.
-.em
.conf maildir@_quota@_directory@_regex string "See below"
.index maildir format||quota, directories included in
.index quota||maildir, directories included in
maildir_quota_directory_regex = ^(?:cur|new|\..*)$
.endd
which includes the \(cur)\ and \(new)\ directories, and any maildir++ folders
-(directories whose names begin with a dot). If you want to exclude the
+(directories whose names begin with a dot). If you want to exclude the
\(Trash)\
folder from the count (as some sites do), you need to change this setting to
.display asis
.endd
This uses a negative lookahead in the regular expression to exclude the
directory whose name is \(.Trash)\.
-.nem
.conf maildir@_retries integer 10
This option specifies the number of times to retry when writing a file in
\**Note**\: The \message@_prefix\ and \message@_suffix\ options are not
automatically changed by the use of \mbx@_format\. They should normally be set
-empty when using MBX format, so this option almost always appears in this
+empty when using MBX format, so this option almost always appears in this
combination:
.display asis
mbx_format = true
or to the total space used in the directory tree when the \directory\ 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.
-.em
+individually inspected and their sizes summed.
(See \quota@_size@_regex\ and \maildir@_use@_size@_file\ for ways to avoid this
in environments where users have no shell access to their mailboxes).
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.
-.nem
A file's size is taken as its \*used*\ value. Because of blocking effects, this
may be a lot less than the actual amount of disk space allocated to the file.
fails because this quota is exceeded, the handling of the error is as for
system quota failures.
-.em
-\**Note**\: A value of zero is interpreted as `no quota'.
-.nem
+\**Note**\: A value of zero is interpreted as `no quota'.
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
maildir_tag = ,S=$message_size
quota_size_regex = ,S=(\d+)
.endd
-The regular expression should not assume that the length is at the end of the
-file name (even though \maildir@_tag\ puts it there) because maildir MUAs
+The regular expression should not assume that the length is at the end of the
+file name (even though \maildir@_tag\ puts it there) because maildir MUAs
sometimes add other information onto the ends of message file names.
.conf quota@_warn@_message string$**$ "see below"
The contents of the \message@_prefix\ and \message@_suffix\ options 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
+with a single linefeed, so they
must
be changed to end with \"@\r@\n"\ if \use@_crlf\ is set.
.index locking files
Once the file is open, unless both \use@_fcntl@_lock\ and \use@_flock@_lock\
are false, it is locked using \*fcntl()*\ or \*flock()*\ or both. If
-\use@_mbx@_lock\ is false, an exclusive lock is requested in each case.
+\use@_mbx@_lock\ is false, an exclusive lock is requested in each case.
However, if \use@_mbx@_lock\ is true,
Exim takes out a shared lock on the open file,
and an exclusive lock on the file whose name is
.index delivery||to single file
.index `From' line
When the \directory\ option is set instead of \file\, each message is delivered
-into a newly-created file or set of files. When \%appendfile%\ is activated
-directly from a \%redirect%\ router, neither \file\ nor \directory\ is normally
-set, because the path for delivery is supplied by the router. (See for example,
-the \%address@_file%\ transport in the default configuration.) In this case,
-delivery is to a new file if either the path name ends in \"/"\, or the
+into a newly-created file or set of files. When \%appendfile%\ is activated
+directly from a \%redirect%\ router, neither \file\ nor \directory\ is normally
+set, because the path for delivery is supplied by the router. (See for example,
+the \%address@_file%\ transport in the default configuration.) In this case,
+delivery is to a new file if either the path name ends in \"/"\, or the
\maildir@_format\ or \mailstore@_format\ option is set.
No locking is required while writing the message to a new file, so the various
\check@_string\, \message@_prefix\, and \message@_suffix\ are all unset when
any of \directory\, \maildir@_format\, or \mailstore@_format\ is set.
-If Exim is required to check a \quota\ 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 \quota@_directory\. Also, for maildir deliveries
+If Exim is required to check a \quota\ 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 \quota@_directory\. Also, for maildir deliveries
(see below) the \(maildirfolder)\ convention is honoured.
.index maildir format||description of
If the \maildir@_format\ option is true, Exim delivers each message by writing
it to a file whose name is \(tmp/<<stime>>.H<<mtime>>P<<pid>>.<<host>>)\ in the
-given directory. If the delivery is successful, the file is renamed into the
+given directory. If the delivery is successful, the file is renamed into the
\(new)\ subdirectory.
In the file name, <<stime>> is the current time of day in seconds, and
the parent directory instead of the current directory when calculating the
amount of space used.
+.em
+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 \mailbox@_size\ option as a way of importing it into Exim.
+.nem
+
.section Using tags to record message sizes
-If \maildir@_tag\ is set, the string is expanded for each delivery.
+If \maildir@_tag\ is set, the string is expanded for each delivery.
When the maildir file is renamed into the \(new)\ 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 \*stat()*\ call fails with \\ENAMETOOLONG\\,
-the tag is dropped and the maildir file is created with no tag.
+the tag is dropped and the maildir file is created with no tag.
Tags can be used to encode the size of files in their names; see
-\quota@_size@_regex\ above for an example. The expansion of \maildir@_tag\
+\quota@_size@_regex\ above for an example. The expansion of \maildir@_tag\
happens after the message has been written. The value of the \$message@_size$\
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
colon is inserted.
-.em
.section Using a maildirsize file
.index quota||in maildir delivery
.index maildir format||\(maildirsize)\ file
file is maintained (with a zero quota setting), but no quota is imposed.
A regular expression is available for controlling which directories in the
-maildir participate in quota calculations. See the description of the
+maildir participate in quota calculations. See the description of the
\maildir@_quota@_directory@_regex\ option above for details.
-.nem
.section Mailstore delivery
.index transports||\%autoreply%\
.index \%autoreply%\ transport
The \%autoreply%\ transport is not a true transport in that it does not cause
-the message to be transmitted. Instead, it generates another mail message. It
-is usually run as the result of mail filtering, a `vacation' 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 \%autoreply%\ transport always have empty envelope sender
-addresses, like bounce messages.
+the message to be transmitted. Instead, it generates a new mail message.
+.em
+If the router that passes the message to this transport does not have the
+\unseen\ option set, the original message (for the current recipient) is not
+delivered anywhere. However, when the \unseen\ 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.
+.nem
+
+The \%autoreply%\ transport is usually run as the result of mail filtering, a
+`vacation' 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 \%autoreply%\ transport always have
+empty envelope sender addresses, like bounce messages.
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
+transport is run as a consequence of a
\mail\
or \vacation\ command in a filter file, the parameters of the message are
supplied by the filter, and passed with the address. The transport's options
Non-printing characters are not permitted in the header lines generated for the
message that \%autoreply%\ creates, with the exception of newlines that are
-immediately followed by whitespace. If any non-printing characters are found,
+immediately followed by whitespace. 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 \print@_topbitchars\ global option.
.section Private options for autoreply
-.startconf
+.startconf autoreply
.index options||\%autoreply%\ transport
.conf bcc string$**$ unset
This specifies the addresses that are to receive `blind carbon copies' of the
.conf mode "octal integer" 0600
If either the log file or the `once' file has to be created, this mode is used.
+.em
+.conf never@_mail "address list$**$" unset
+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.
+.nem
+
.conf once string$**$ unset
-This option names a file or DBM database in which a record of each
+This option names a file or DBM database in which a record of each
::To:: recipient is kept when the message is specified by the transport.
\**Note**\: This does not apply to ::Cc:: or ::Bcc:: recipients.
If \once@_file@_size\ is not set, a DBM database is used, and it is allowed to
.conf subject string$**$ unset
This specifies the contents of the ::Subject:: header when the message is
specified by the transport.
+.em
+It is tempting to quote the original subject in automatic responses. For
+example:
+.display asis
+subject = Re: $h_subject:
+.endd
+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.
+.nem
.conf text string$**$ unset
This specifies a single string to be used as the body of the message when the
The private options of the \%lmtp%\ transport are as follows:
-.startconf
+.startconf lmtp
.index options||\%lmtp%\ transport
.conf batch@_id string$**$ unset
input and output to operate the LMTP protocol.
.conf socket string$**$ unset
-This option must be set if \command\ is not set. The result of expansion must
-be the name of a Unix domain socket. The transport connects to the socket and
+This option must be set if \command\ 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.
.conf timeout time 5m
-The transport is aborted if the created process
+The transport is aborted if the created process
or Unix domain socket
does not respond to LMTP commands or message input within this timeout.
.index transports||\%pipe%\
.index \%pipe%\ transport
The \%pipe%\ transport is used to deliver messages via a pipe to a command
-running in another process. This can happen in one of two ways:
+running in another process.
+.em
+One example is the
+use of \%pipe%\ 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 \%pipe%\ transport can be
+used in one of the following ways:
+.nem
.numberpars $.
-A router routes an address to a transport in the normal way, and the transport
+A router routes one address to a transport in the normal way, and the transport
is configured as a \%pipe%\ transport. In this case, \$local@_part$\ contains
-the address (as usual), and the command which is run is specified by the
-\command\ option on the transport. An example of this is the use of \%pipe%\ as
-a pseudo-remote transport for passing messages to some other delivery mechanism
-(such as UUCP).
+the local part of the address (as usual), and the command that is run is
+specified by the \command\ option on the transport.
+.nextp
+.em
+If the \batch@_max\ option is set greater than 1 (the default), the transport
+can be called upon to handle more than one address in a single run. In this
+case, \$local@_part$\ is not set (because it is not unique). However, the
+pseudo-variable \$pipe@_addresses$\ (described in section ~~SECThowcommandrun
+below) contains all the addresses that are being handled.
+.nem
.nextp
A router redirects an address directly to a pipe command (for example, from an
alias or forward file). In this case, \$local@_part$\ contains the local part
command itself. The \command\ option on the transport is ignored.
.endp
-The \%pipe%\ transport is a non-interactive delivery method. Exim can also
-deliver messages over pipes using the LMTP interactive protocol. This is
+The \%pipe%\ transport is a non-interactive delivery method. Exim can also
+deliver messages over pipes using the LMTP interactive protocol. This is
implemented by the \%lmtp%\ transport.
In the case when \%pipe%\ is run as a consequence of an entry in a local user's
directories are also controllable. See chapter ~~CHAPenvironment for details of
the local delivery environment.
+
+.em
+.section Concurrent delivery
+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 \exim@_lock\ utility might be of use.
+.nem
+
+
.section Returned status and data
.index \%pipe%\ transport||returned data
If the command exits with a non-zero return code, the delivery is deemed to
script, it normally means that the script was terminated by a signal whose
value is the return code minus 128.
-If Exim is unable to run the command (that is, if \*execve()*\ 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
+If Exim is unable to run the command (that is, if \*execve()*\ 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.
The \return@_output\ option can affect the result of a pipe delivery. If it is
.section Private options for pipe
.index options||\%pipe%\ transport
-.startconf
+
+.startconf pipe
.conf allow@_commands "string list$**$" unset
.index \%pipe%\ transport||permitted commands
.conf ignore@_status boolean false
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
+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 \temp@_errors\; these cause the delivery to be deferred and
return code that is neither zero nor one of the return codes listed in
\temp@_errors\ (that is, the delivery failed), the first line of output is
written to the main log.
+.em
+This option and \log@_output\ are mutually exclusive. Only one of them may be
+set.
+.nem
.conf log@_output boolean false
If this option is set and the command returns any output, the first line of
output is written to the main log, whatever the return code.
+.em
+This option and \log@_fail@_output\ are mutually exclusive. Only one of them
+may be set.
+.nem
.conf max@_output integer 20K
This specifies the maximum amount of output that the command may produce on its
This option specifies the string that is set up in the \\PATH\\ environment
variable of the subprocess. If the \command\ option does not yield an absolute
path name, the command is sought in the \\PATH\\ directories, in the usual way.
-\**Warning**\: This does not apply to a command specified as a transport
+\**Warning**\: This does not apply to a command specified as a transport
filter.
.conf pipe@_as@_creator boolean false
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.
+.em
+This option and \return@_output\ are mutually exclusive. Only one of them may
+be set.
+.nem
.conf return@_output boolean false
If this option is true, and the command produced any output, the delivery is
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.
+.em
+This option and \return@_fail@_output\ are mutually exclusive. Only one of them
+may be set.
+.nem
.conf temp@_errors "string list" "see below"
.index \%pipe%\ transport||temporary failure
This option contains either a colon-separated list of numbers, or a single
-asterisk. If \ignore@_status\ is false
-.em
+asterisk. If \ignore@_status\ is false
and \return@_output\ is not set,
-.nem
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
The private options of the \%smtp%\ transport are as follows:
.index options||\%smtp%\ transport
-.startconf
+.startconf smtp
.conf allow@_localhost boolean false
.index local host||sending to
.index fallback||hosts specified on transport
.conf gethostbyname boolean false
If this option is true when the \hosts\ and/or \fallback@_hosts\ options are
-being used, names are looked up using \*gethostbyname()*\
+being used, names are looked up using \*gethostbyname()*\
(or \*getipnodebyname()*\ 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 \(/etc/hosts)\.
.index limit||number of MX tried
.index MX record||maximum tried
This option limits the number of IP addresses that are tried for any one
-delivery
+delivery in cases where there are temporary delivery errors. Section
+~~SECTvalhosmax describes in detail how the value of this option is used.
+
.em
-in cases where there are temporary delivery errors.
+.conf hosts@_max@_try@_hardlimit integer 50
+This is an additional check on the maximum number of IP addresses that Exim
+tries for any one delivery. Section ~~SECTvalhosmax describes its use and why
+it exists.
.nem
-Section ~~SECTvalhosmax describes in detail how the value of this option is
-used.
.conf hosts@_nopass@_tls "host list$**$" unset
.index TLS||passing connection
.index TLS||requiring for certain servers
Exim will insist on using a TLS session when delivering to any host that
matches this list. See chapter ~~CHAPTLS for details of TLS.
-\**Note**\: This option affects outgoing mail only. To insist on TLS for
+\**Note**\: This option affects outgoing mail only. To insist on TLS for
incoming messages, use an appropriate ACL.
.index authentication||optional in client
call. The variables \$host$\ and \$host@_address$\ 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,
-.em
+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.
-.nem
For example:
.display asis
interface = <; 192.168.123.123 ; 3ffe:ffff:836f::fe86:a061
it begins with a digit it is taken as a port number; otherwise it is looked up
using \*getservbyname()*\. The default value is normally `smtp', but if
\protocol\ is set to `lmtp', the default is `lmtp'.
-If the expansion fails, or if a port number cannot be found, delivery is
+If the expansion fails, or if a port number cannot be found, delivery is
deferred.
and address of the server during the expansion. See chapter ~~CHAPTLS for
details of TLS.
-\**Note**\: This option must be set if you want Exim to use TLS 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
+\**Note**\: This option must be set if you want Exim to use TLS 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.
-.em
.conf tls@_crl string$**$ unset
.index TLS||client certificate revocation list
.index certificate||revocation list for client
This option specifies a certificate revocation list. The expanded value must
be the name of a file that contains a CRL in PEM format.
-.nem
.conf tls@_privatekey string$**$ unset
.index TLS||client private key, location of
The value of this option must be the absolute path to a file which contains the
client's private key, for use when sending a message over an encrypted
connection. The values of \$host$\ and \$host@_address$\ are set to the name
-and address of the server during the expansion.
-If this option is unset, the private key is assumed to be in the same file as
+and address of the server during the expansion.
+If this option is unset, the private key is assumed to be in the same file as
the certificate.
See chapter ~~CHAPTLS for details of TLS.
.index TLS||requiring specific ciphers
.index cipher||requiring specific
The value of this option must be a list of permitted cipher suites, for use
-when setting up an
+when setting up an outgoing encrypted connection. (There is a global option of
+the same name for controlling incoming connections.) The values of \$host$\ and
+\$host@_address$\ are set to the name and address of the server during the
+expansion. See chapter ~~CHAPTLS for details of TLS; note that this option is
+used in different ways by OpenSSL and GnuTLS (see sections ~~SECTreqciphssl and
+~~SECTreqciphgnu).
.em
-outgoing encrypted connection. (There is a global option of the same name for
-controlling incoming connections.)
+For GnuTLS, the order of the ciphers is a preference order.
.nem
-The values of \$host$\ and \$host@_address$\ are set to the name and address of
-the server during the expansion. See chapter ~~CHAPTLS for details of TLS; note
-that this option is used in different ways by OpenSSL and GnuTLS (see section
-~~SECTreqciphsslgnu).
.conf tls@_tempfail@_tryclear boolean true
-When the server host is not in \hosts@_require@_tls\, and there is a problem in
+When the server host is not in \hosts@_require@_tls\, 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
.endconf
-.section How the value of hosts@_max@_try is used
+.section How the limits for the number of hosts to try are used
.rset SECTvalhosmax "~~chapter.~~section"
.index host||maximum number to try
.index limit||hosts, maximum number tried
+.em
+There are two options that are concerned with the number of hosts that are
+tried when an SMTP delivery takes place. They are \hosts@_max@_try\ and
+\hosts@_max@_try@_hardlimit\.
+.nem
+
The \hosts@_max@_try\ option limits the number of hosts that are tried
for a single delivery. However, despite the term `host' in its name, the option
-actually applies to each IP address independently. In other words, a multihomed
+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.
Many of the larger ISPs have multiple MX records which often point to
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
-\hosts@_max@_try\ is the maximum number that are tried before deferring the
+\hosts@_max@_try\ is the maximum number that are tried before deferring the
delivery. However, the logic cannot be quite that simple.
Firstly, IP addresses that are skipped because their retry times have not
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
\hosts@_max@_retry\ may be tried. The reason for this behaviour is to ensure
-that all IP addresses are considered before timing out an email address.
+that all IP addresses are considered before timing out an email address (but
+see below for an exception).
Secondly, when the \hosts@_max@_try\ 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 used 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:
+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:
-Consider the case of a long list of hosts with one MX value, and a few with a
+Consider the case of a long list of hosts with one MX value, and a few with a
higher MX value. If \hosts@_max@_try\ 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
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 mentioned about, the higher MX hosts would never
-be tried at all because the lower MX hosts are never all past their retry
-times.
-
-With the special check, Exim tries least one address from each MX value, even
-if the \hosts@_max@_try\ limit has already been reached.
-
-
+without the special MX check, the higher MX hosts would never be tried
+.em
+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 \hosts@_max@_try\ limit has
+already been reached.
+
+The above logic means that \hosts@_max@_try\ is not a hard limit, and in
+particular, Exim normally eventually tries all the IP addresses before timing
+out an email address. When \hosts@_max@_try\ 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.
+
+The \hosts@_max@_try@_hardlimit\ 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.
+.nem
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 `canonical' name, and some MTAs do
this. The new RFCs do not contain this suggestion.
-
+
.section Explicitly configured address rewriting
This chapter describes the rewriting rules that can be used in the
main rewrite section of the configuration file, and also in the generic
Others believe that life is not possible without it. Exim provides the
facility; you do not have to use it.
-.em
The main rewriting rules that appear in the `rewrite' 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.
-.nem
Rewriting of addresses in header lines applies only to those headers that
were received with the message, and, in the case of transport rewriting, those
\*fp42@@hitch.fict.example*\ becomes \*Ford.Prefect@@hitch.fict.example*\.
.endp
-.em
.section When does rewriting happen?
.index rewriting||timing of
.index ~~ACL||rewriting addresses in
Configured address rewriting can take place at several different stages of a
-message's processing.
+message's processing.
-At the start of an ACL for \\MAIL\\, the sender address may have been rewritten
+At the start of an ACL for \\MAIL\\, the sender address may have been rewritten
by a special SMTP-time rewrite rule (see section ~~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
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 \$local@_part$\ and \$domain$\ after verification are always the same
-as they were before (that is, they contain the unrewritten -- except for
+as they were before (that is, they contain the unrewritten -- except for
SMTP-time rewriting -- address).
-Once a message's header lines have been received, all the envelope recipient
+Once 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).
.index \*local@_scan()*\ function||address rewriting, timing of
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 \no@_rewrite\ is set on the router.
-.nem
.index envelope sender, rewriting
.index rewriting||at transport time
single-item address list, which means that it is expanded before being tested
against the address.
-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
+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 \"^(?i)"\.
.index numerical variables (\$1$\, \$2$\, etc)||in rewriting rules
.section Retry rules
.index retry||rules
-Each retry rule occupies one line and consists of three parts, separated by
-white space: a pattern, an error name, and a list of retry parameters. The
-pattern must be enclosed in double quotes if it contains white space. The rules
-are searched in order until one is found whose pattern matches the failing host
-or address.
+.em
+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.
+.nem
The pattern is any single item that may appear in an address list (see section
~~SECTaddresslist). It is in fact processed as a one-item address list, which
alice@lookingglass.fict.example * F,24h,30m;
.endd
applies only to temporary failures involving the local part \alice\.
-In practice, almost all rules start with a domain name pattern without a local
+In practice, almost all rules start with a domain name pattern without a local
part.
.index regular expressions||in retry rules
-\**Warning**\: If you use a regular expression in a routing rule, it must match
-a complete address, not just a domain, because that is how regular expressions
-work in address lists.
+\**Warning**\: If you use a regular expression in a routing rule pattern, it
+must match a complete address, not just a domain, because that is how regular
+expressions work in address lists.
.display
^@\Nxyz@\d+@\.abc@\.example@$@\N * G,1h,10m,2 \Wrong\
^@\N[^@@]+@@xyz@\d+@\.abc@\.example@$@\N * G,1h,10m,2 \Right\
\retry@_use@_local@_part\ is set for the transport (it defaults true for all
local transports).
-.em
When Exim is looking for a retry rule after a remote delivery attempt has
failed, what happens depends on the type of failure. After a 4\*xx*\ SMTP
response for a recipient address, the whole address is used when searching the
-retry rules. The rule that is found is used to create a retry time for the
+retry rules. The rule that is found is used to create a retry time for the
failing address.
For a temporary error that is not related to an individual address,
-.nem
(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 `*@@' when matching a regular expression). If this does not match
.index retry||specific errors, specifying
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:
-.numberpars " "
-\*auth@_failed*\: authentication failed when trying to send to a host in the
-\hosts@_require@_auth\ list in an \%smtp%\ transport
-.nextp
-\*refused@_MX*\: connection refused from a host obtained from an MX record
-.nextp
-\*refused@_A*\: connection refused from a host not obtained from an MX record
-.nextp
-\*refused*\: any connection refusal
-.nextp
-\*timeout@_connect@_MX*\: connection timeout from a host obtained from an MX
-record
-.nextp
-\*timeout@_connect@_A*\: connection timeout from a host not obtained from an MX
-record
-.nextp
-\*timeout@_connect*\: any connection timeout
-.nextp
-\*timeout@_MX*\: any timeout from a host obtained from an MX
-record
-.nextp
-\*timeout@_A*\: any timeout from a host not obtained from an MX
-record
-.nextp
-\*timeout*\: any timeout
-.nextp
-\*quota*\: quota exceeded in local delivery by \%appendfile%\
-.nextp
+.em
+
+.push
+.indent 2em
+.tempindent 0
+\auth@_failed\: Authentication failed when trying to send to a host in the
+\hosts@_require@_auth\ list in an \%smtp%\ transport.
+
+.tempindent 0
+\rcpt@_4xx\: A 4\*xx*\ error was received for an outgoing \\RCPT\\ command.
+Either the first or both of the x's can be given as specific digits, for
+example: \"rcpt@_45x"\ or \"rcpt@_436"\. For example, to recognize 452 errors
+given to \\RCPT\\ commands by a particular host, and have retries every ten
+minutes and a one-hour timeout, you could set up a retry rule of this form:
+.display asis
+the.host.name rcpt_452 F,1h,10m
+.endd
+These errors apply to both outgoing SMTP (the \%smtp%\ transport) and outgoing
+LMTP (either the \%lmtp%\ transport, or the \%smtp%\ transport in LMTP mode).
+Note, however, that they apply only to responses to \\RCPT\\ commands.
+
+.tempindent 0
+\refused@_MX\: A connection to a host obtained from an MX record was refused.
+
+.tempindent 0
+\refused@_A\: A connection to a host not obtained from an MX record was
+refused.
+
+.tempindent 0
+\refused\: A connection was refused.
+
+.tempindent 0
+\timeout@_connect@_MX\: A connection attempt to a host obtained from an MX
+record timed out.
+
+.tempindent 0
+\timeout@_connect@_A\: A connection attempt to a host not obtained from an MX
+record timed out.
+
+.tempindent 0
+\timeout@_connect\: A connection attempt timed out.
+
+.tempindent 0
+\timeout@_MX\: There was a timeout while connecting or during an SMTP session
+with a host obtained from an MX record.
+
+.tempindent 0
+\timeout@_A\: There was a timeout while connecting or during an SMTP session
+with a host not obtained from an MX record.
+
+.tempindent 0
+\timeout\: There was a timeout while connecting or during an SMTP session.
+
+.tempindent 0
+\quota\: A mailbox quota was exceeded in a local delivery by the
+\%appendfile%\ transport.
+
.index quota||error testing in retry rule
.index retry||quota error testing
-\*quota@_*\<<time>>: quota exceeded in local delivery, and the mailbox has not
-been read for <<time>>. For example, \*quota@_4d*\ applies to a quota error
-when the mailbox has not been read for four days.
+.tempindent 0
+\quota@_\<<time>>: A mailbox quota was exceeded in a local delivery by
+the \%appendfile%\ transport, and the mailbox has not been accessed for
+<<time>>. For example, \*quota@_4d*\ applies to a quota error when the mailbox
+has not been accessed for four days.
+
+.pop
+
-.em
.index mailbox||time of last read
-\**Warning**\: It is not always possible to determine a `time of last read' for
-a mailbox:
+The idea of \quota@_\<<time>> 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:
.numberpars $.
-If the mailbox is a single file, the time of last access is used.
+If the mailbox is a single file, the time of last access (the `atime') 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.
.nextp
.index maildir format||time of last read
-For a maildir delivery, the time of last modification of the \(new)\
-subdirectory is used. As the mailbox is over quota, no new files will be
-created in the \(new)\ subdirectory, so any change is assumed to be the result
-of an MUA moving a new message to the \(cur)\ directory when it is first read.
-.nextp
-For other kinds of multi-file delivery, the time of last read cannot be
-obtained, and so a retry rule that uses this type of error field is never
-matched.
+For a maildir delivery, the time of last modification of the \(new)\
+subdirectory is used. As the mailbox is over quota, no new files are created in
+the \(new)\ subdirectory, because no new messages are being delivered. Any
+change to the \(new)\ subdirectory is therefore assumed to be the result of an
+MUA moving a new message to the \(cur)\ directory when it is first read. The
+time that is used is therefore the last time that the user read a new message.
+.nextp
+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.
.endp
.nem
-.endp
The quota errors apply both to system-enforced quotas and to Exim's own quota
mechanism in the \%appendfile%\ transport. The \*quota*\ error also applies
when a local delivery is deferred because a partition is full (the \\ENOSPC\\
error).
-.section Retry rule parameters
+.em
+.section Retry rules for specified senders
+.index retry||rules, sender-specific
+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:
+.display
+senders=<<address list>>
+.endd
+The retry timings themselves are then the fourth item. For example:
+.display asis
+* * senders=: F,1h,30m
+.endd
+matches all temporary errors for bounce messages sent to any host. If the
+address list contains white space, it must be enclosed in quotes. For example:
+.display
+a.domain timeout senders="x@b.dom : y@c.dom" G,8h,10m,1.5
+.endd
+When testing retry rules using \-brt-\, you can supply a sender using the \-f-\
+command line option, like this:
+.display asis
+exim -f "" -brt user@dom.ain
+.endd
+If you do not set \-f-\ with \-brt-\, a retry rule that contains a senders list
+is never matched.
+.nem
+
+
+
+.section Retry parameters
.index retry||parameters in rules
-The third field in a retry rule is a sequence of retry parameter sets,
-separated by semicolons. Each set consists of
+The third
+.em
+(or fourth, if a senders list is present)
+.nem
+field in a retry rule is a sequence of retry parameter sets, separated by
+semicolons. Each set consists of
.display
<<letter>>,<<cutoff time>>,<<arguments>>
.endd
.index retry||algorithms
The available algorithms are:
.numberpars $.
-\*F*\: retry at fixed intervals. There is a single time parameter specifying the
-interval.
+\*F*\: retry at fixed intervals. There is a single time parameter specifying
+the interval.
.nextp
-\*G*\: 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.
+\*G*\: 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.
.endp
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
.endd
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.
+failure for the recipient address that counts.
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
.index \\AUTH\\||description of
Very briefly, the way SMTP authentication works is as follows:
.numberpars $.
-The server advertises a number of authentication \*mechanisms*\ in response to
+The server advertises a number of authentication \*mechanisms*\ in response to
the client's \\EHLO\\ command.
.nextp
The client issues an \\AUTH\\ command, naming a specific mechanism. The command
.section Generic options for authenticators
.index authentication||generic options
-.startconf
+.startconf authenticators
.index options||generic, for authenticators
.conf driver string unset
.conf server@_advertise@_condition string$**$ unset
When a server is about to advertise an authentication mechanism, the condition
is expanded. If it yields the empty string, `0', `no', or `false', the
-mechanism is not advertised.
-If the expansion fails, the mechanism is not advertised. If the failure was not
+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 ~~SECTauthexiser below for further discussion.
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
+If expansion of the string fails, the error message is written to the debugging
output, and Exim carries on processing.
.conf server@_set@_id string$**$ unset
.conf server@_mail@_auth@_condition string$**$ unset
This option allows a server to discard authenticated sender addresses supplied
-as part of \\MAIL\\ commands in SMTP connections that are authenticated by the
+as part of \\MAIL\\ commands in SMTP connections that are authenticated by the
driver on which \server__mail__auth@_condition\ is set. The option is not used
as part of the authentication process; instead its (unexpanded) value is
remembered for later use.
.rset SECTauthparamail "~~chapter.~~section"
.index authentication||sender, authenticated
.index \\AUTH\\||on \\MAIL\\ command
-When a client supplied an \\AUTH=\\ item on a \\MAIL\\ command, Exim applies
+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:
.numberpars $.
-If the connection is not using extended SMTP (that is, \\HELO\\ was used rather
+If the connection is not using extended SMTP (that is, \\HELO\\ was used rather
than \\EHLO\\), the use of \\AUTH=\\ is a syntax error.
.nextp
If the value of the \\AUTH=\\ parameter is `@<@>', it is ignored.
.section Authentication on an Exim server
.rset SECTauthexiser "~~chapter.~~section"
.index authentication||on an Exim server
-When Exim receives an \\EHLO\\ command, it advertises the public names of those
-authenticators that are configured as servers, subject to the following
+When Exim receives an \\EHLO\\ command, it advertises the public names of those
+authenticators that are configured as servers, subject to the following
conditions:
.numberpars $.
The client host must match \auth@_advertise@_hosts\ (default $*$).
.nextp
-It the \server@_advertise@_condition\ option is set, its expansion must not
+It the \server@_advertise@_condition\ option is set, its expansion must not
yield the empty string, `0', `no', or `false'.
.endp
-The order in which the authenticators are defined controls the order in which
+The order in which the authenticators are defined controls the order in which
the mechanisms are advertised.
Some mail clients (for example, some versions of Netscape) require the user to
.display asis
server_advertise_condition = ${if eq{$tls_cipher}{}{no}{yes}}
.endd
-If the session is encrypted, \$tls@_cipher$\ is not empty, and so the expansion
+If the session is encrypted, \$tls@_cipher$\ is not empty, and so the expansion
yields `yes', which allows the advertisement to happen.
When an Exim server receives an \\AUTH\\ command from a client, it rejects it
.nextp
No authenticators are configured with server options; or
.nextp
-Expansion of \server@_advertise@_condition\ blocked the advertising of all the
+Expansion of \server@_advertise@_condition\ blocked the advertising of all the
server authenticators.
.endp
Otherwise, Exim runs the ACL specified by \acl@_smtp@_auth\ in order
to decide whether to accept the command. If \acl@_smtp@_auth\ is not set,
-\\AUTH\\ is accepted from any client host.
+\\AUTH\\ is accepted from any client host.
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
+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.
When a message is received from an authenticated host, the value of
-\$received@_protocol$\ is set to `asmtp' instead of `esmtp', and
-\$sender@_host@_authenticated$\ 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.
+\$received@_protocol$\ is set to
+.em
+`esmtpa'
+.nem
+instead of `esmtp', and \$sender@_host@_authenticated$\ 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.
.endd
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.
+whose code value is zero.
\**Warning 1**\: 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.
-\**Warning 2**\: If there are characters in the strings that Perl interprets
-specially, you must use a Perl escape to prevent them being misinterpreted. For
+\**Warning 2**\: 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
.display asis
encode '\0user@domain.com\0pas$$word'
.index \\AUTH\\||on \\MAIL\\ command
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
+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 \server@_mail@_auth\ 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
When running as a server, \%plaintext%\ performs the authentication test by
expanding a string. It has the following options:
-.startconf
+.startconf plaintext
.index options||\%plaintext%\ authenticator (server)
.conf server@_prompts string$**$ unset
expanded and saved in \$authenticated@_id$\. For any other result, a temporary
error code is returned, with the expanded string as the error text.
-\**Warning**\: 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.
+\**Warning**\: 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.
.index authentication||PLAIN mechanism
.index binary zero||in \%plaintext%\ authenticator
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
+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.
fixed_plain:
driver = plaintext
public_name = PLAIN
- server_prompts = :
+ server_prompts = :
server_condition = \
${if and {{eq{$2}{username}}{eq{$3}{mysecret}}}{yes}{no}}
server_set_id = $2
.display asis
AUTH PLAIN
.endd
-to initiate authentication, in which case the server replies with an empty
+to initiate authentication, in which case the server replies with an empty
prompt. The client must respond with the combined data string.
-.em
The data string is base64 encoded, as required by the RFC. This example,
when decoded, is \"<<NUL>>username<<NUL>>mysecret"\, where <<NUL>> represents a
zero byte. This is split up into three strings, the first of which is empty.
The \server@_condition\ option in the authenticator checks that the second two
are \"username"\ and \"mysecret"\ respectively.
-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
+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.
-.nem
A more sophisticated instance of this authenticator could use the user name in
\$2$\ to look up a password in a file or database, and maybe do an encrypted
which it then compares to the supplied password (\$3$\). 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
+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:
.display asis
server_condition = ${lookup{$2}dbm{/etc/authpwd}\
- {${if eq{$value}{$3}{yes}{no}}}{no}}
+ {${if eq{$value}{$3}{yes}{no}}}{no}}
.endd
In this case, if the lookup succeeds, the result is checked; if the lookup
fails, authentication fails. If \crypteq\ is being used instead of \eq\, the
public_name = LOGIN
server_prompts = Username:: : Password::
server_condition = ${if ldapauth \
-.newline
+.newline
{user="cn=${quote_ldap_dn:$1},ou=people,o=example.org" \
pass=${quote:$2} \
-.newline
+.newline
ldap://ldap.example.org/}{yes}{no}}
server_set_id = uid=$1,ou=people,o=example.org
.endd
Note the use of the \quote@_ldap@_dn\ operator to correctly quote the DN for
authentication. However, the basic \quote\ 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 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.
-.section Support for different kinds of authentication
+.section Support for different kinds of authentication
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 \(/etc/passwd)\ (or equivalent), PAM,
.section Using plaintext in a client
The \%plaintext%\ authenticator has just one client option:
-.startconf
+.startconf plaintext
.index options||\%plaintext%\ authenticator (client)
.conf client@_send string$**$ unset
This authenticator has one server option, which must be set to configure the
authenticator as a server:
-.startconf
+.startconf cram@_md5
.index options||\%cram@_md5%\ authenticator (server)
.conf server@_secret string$**$ unset
For example, the following authenticator checks that the user name given by the
client is `ph10', and if so, uses `secret' as the password. For any other user
-name, authentication fails.
+name, authentication fails.
.display asis
fixed_cram:
driver = cram_md5
.section Using cram@_md5 as a client
When used as a client, the \%cram@_md5%\ authenticator has two options:
-.startconf
+.startconf cram@_md5
.index options||\%cram@_md5%\ authenticator (client)
.conf client@_name string$**$ "the primary host name"
+.
+.
+.
+.
+. ============================================================================
+.chapter The cyrus@_sasl authenticator
+.set runningfoot "cyrus@_sasl authenticator"
+.index \%cyrus@_sasl%\ authenticator
+.index authenticators||\%cyrus@_sasl%\
+.index Cyrus, SASL library
+.em
+The code for this authenticator was provided by Matthew Byng-Maddick of A L
+Digital Ltd (\?http://www.aldigital.co.uk?\).
+
+The \%cyrus@_sasl%\ authenticator provides server support for the Cyrus SASL
+library implementation of the RFC 2222 (`Simple Authentication and Security
+Layer'). 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.
+
+The \%cyrus@_sasl%\ 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 \%cyrus@_sasl%\ authenticator. By default it uses the public
+name of the driver to determine which mechanism to support.
+
+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.
+
+.section Using cyrus@_sasl as a server
+The \%cyrus@_sasl%\ authenticator has four private options. It puts the
+username (on a successful authentication) into \$1$\.
+
+.startconf cyrus@_sasl
+.conf server@_hostname string$**$ $tt{$primary@_hostname}
+This option selects the hostname that is used when communicating with
+the library. It is up to the underlying SASL plug-in what it does with
+this data.
+
+.conf server@_mech string $tt{public@_name}
+This option selects the authentication mechanism this driver should
+use. It allows you to use a different underlying mechanism from the
+advertised name. For example:
+.display asis
+sasl:
+ driver = cyrus_sasl
+ public_name = X-ANYTHING
+ server_mech = CRAM-MD5
+ server_set_id = $1
+.endd
+
+.conf server@_realm string unset
+This specifies the SASL realm that the server claims to be in.
+
+.conf server@_service string $tt{smtp}
+This is the SASL service that the server claims to implement.
+
+.endconf
+
+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:
+.display asis
+sasl_cram_md5:
+ driver = cyrus_sasl
+ public_name = CRAM-MD5
+ server_set_id = $1
+
+sasl_plain:
+ driver = cyrus_sasl
+ public_name = PLAIN
+ server_set_id = $1
+.endd
+
+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.
+
+.nem
+
+
.
.
.section Using spa as a server
The \%spa%\ authenticator has just one server option:
-.startconf
+.startconf spa
.index options||\%spa%\ authenticator (server)
.conf server@_password string$**$ unset
.index numerical variables (\$1$\, \$2$\, etc)||in \%spa%\ authenticator
-This option is expanded, and the result must be the cleartext password for the
+This option is expanded, and the result must be the cleartext password for the
authenticating user, whose name is at this point in \$1$\. For example:
.display asis
spa:
public_name = NTLM
server_password = ${lookup{$1}lsearch{/etc/exim/spa_clearpass}}
.endd
-If the expansion is forced to fail, authentication fails. Any other expansion
+If the expansion is forced to fail, authentication fails. Any other expansion
failure causes a temporary error code to be returned.
.endconf
.section Using spa as a client
The \%spa%\ authenticator has the following client options:
-.startconf
+.startconf spa
.index options||\%spa%\ authenticator (client)
.conf client@_domain string$**$ unset
.index TLS||on SMTP connection
.index OpenSSL
.index GnuTLS
-.em
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).
-.nem
-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
-~~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.
+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 ~~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.
RFC 2487 defines how SMTP connections can make use of encryption. Once a
connection is established, the client issues a \\STARTTLS\\ command. If the
mechanism. If the negotiation succeeds, the data that subsequently passes
between them is encrypted.
-Exim also has support for legacy clients that do not use the \\STARTTLS\\
-mechanism. Instead, they connect to a different port on the server (usually
-called the `ssmtp' port), and expect to negotiate a TLS session as soon as the
-connection to the server is established. The \-tls-on-connect-\ command line
-option can be used to run an Exim server in this way from \*inetd*\, and it can
-also be used to run a special daemon that operates in this manner (use \-oX-\
-to specify the port).
-
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
in order to get TLS to work.
+.em
+.section Support for the legacy `ssmtp' (aka `smtps') protocol
+.index ssmtp protocol
+.index smtps protocol
+.index SMTP||ssmtp protocol
+.index SMTP||smtps protocol
+Early implementations of encrypted SMTP used a different TCP port from normal
+SMTP, and expected an encryption negotiation to start immediately, instead of
+waiting for a \\STARTTLS\\ command from the client using the standard SMTP
+port. The protocol was called `ssmtp' or `smtps', and port 465 was allocated
+for this purpose.
+
+This approach was abandoned when encrypted SMTP was standardised, but there are
+still some legacy clients that use it. Exim supports these clients by means of
+the \tls@_on@_connect@_ports\ global option. Its value must be a list of port
+numbers; the most common use is expected to be:
+.display asis
+tls_on_connect_ports = 465
+.endd
+The port numbers specified by this option apply to all SMTP connections, both
+via the daemon and via \*inetd*\. You still need to specify all the ports that
+the daemon uses (by setting \daemon@_smtp@_ports\ or \local@_interfaces\ or the
+\-oX-\ command line option) because \tls@_on@_connect@_ports\ does not add an
+extra port -- rather, it specifies different behaviour on a port that is
+defined elsewhere.
+
+There is also a \-tls-on-connect-\ command line option. This overrides
+\tls@_on@_connect@_ports\; it forces the legacy behaviour for all ports.
+.nem
+
+
+
+
.section OpenSSL vs GnuTLS
.index TLS||OpenSSL \*vs*\ GnuTLS
.rset SECTopenvsgnu "~~chapter.~~section"
There are some differences in usage when using GnuTLS instead of OpenSSL:
.numberpars $.
-.em
-The \tls@_verify@_certificates\ option must contain the name of a file, not the
+The \tls@_verify@_certificates\ option must contain the name of a file, not the
name of a directory (for OpenSSL it can be either).
-.nem
.nextp
The \tls@_dhparam\ option is ignored, because early versions of GnuTLS had no
-facility for varying its Diffie-Hellman parameters. I understand that this has
+facility for varying its Diffie-Hellman parameters. I understand that this has
changed, but Exim has not been updated to provide this facility.
.nextp
GnuTLS uses RSA and D-H parameters that take a substantial amount of
Arranging this is easy; just delete the file when you want new values to be
computed.
.nextp
-.em
-Distinguished Name (DN) strings reported by the OpenSSL library use a slash for
-separating fields; GnuTLS uses commas, in accordance with RFC 2253. This
+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 \$tls@_peerdn$\ variable.
-.nem
.nextp
OpenSSL identifies cipher suites using hyphens as separators, for example:
DES-CBC3-SHA. GnuTLS uses 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 hyhens for OpenSSL and hyphens to
underscores for GnuTLS when processing lists of cipher suites in the
-.em
-\tls@_require@_ciphers\ options (the global option and the \%smtp%\ transport
+\tls@_require@_ciphers\ options (the global option and the \%smtp%\ transport
option).
-.nem
.nextp
-.em
The \tls@_require@_ciphers\ options operate differently, as described in the
-following section.
-.nem
+following sections.
.endp
-.em
-.section Requiring specific ciphers in OpenSSL and GnuTLS
-.rset SECTreqciphsslgnu "~~chapter.~~section"
-.index TLS||requiring specific ciphers
-.index \tls@_require@_ciphers\||OpenSSL \*vs*\ GnuTLS
-This section documents the different ways the \tls@_require@_ciphers\ options
-(the global option and the \%smtp%\ transport option) operate in OpenSSL and
-GnuTLS.
-
-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. The list is colon separated and may contain names like
+.section Requiring specific ciphers in OpenSSL
+.rset SECTreqciphssl "~~chapter.~~section"
+.index TLS||requiring specific ciphers (OpenSSL)
+.index \tls@_require@_ciphers\||OpenSSL
+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. The list is colon separated and may contain names like
DES-CBC3-SHA. Exim passes the expanded value of \tls@_require@_ciphers\
-directly to this function call. The following quotation from
-the OpenSSL documentation specifies what forms of item are allowed in the
-cipher string:
+directly to this function call. The following quotation from the OpenSSL
+documentation specifies what forms of item are allowed in the cipher string:
.numberpars $.
It can consist of a single cipher suite such as RC4-SHA.
.nextp
.endp
.endp
+
+.section Requiring specific ciphers in GnuTLS
+.rset SECTreqciphgnu "~~chapter.~~section"
+.index TLS||requiring specific ciphers (GnuTLS)
+.index \tls@_require@_ciphers\||GnuTLS
The GnuTLS library does not have a combined function like OpenSSL. Instead,
it allows the caller to specify separate lists of key-exchange methods,
main cipher algorithms, and MAC algorithms. Unfortunately, these lists are
At present, Exim permits only the list of main cipher algorithms to be
changed. The \tls@_require@_ciphers\ option is in the same format as for
OpenSSL. Exim searches each item for the name of available algorithm. For
-example, if the list contains RSA@_ARCFOUR@_SHA then ARCFOUR is recognized.
+example, if the list contains RSA@_AES@_SHA then AES is recognized.
The cipher algorithms list starts out with a default set of algorithms. If
the first item in \tls@_require@_ciphers\ does \*not*\ start with an
tls_require_ciphers = AES : 3DES
.endd
allows only cipher suites that use AES and 3DES. The currently recognized
-algorithms are: ARCFOUR@_128, ARCFOUR@_40, ARCFOUR (both of the preceding),
-AES@_256, AES@_128, AES (both of the preceding), and 3DES.
-
-Unrecognized algorithms are ignored. In a client, the order of the list
-specifies a preference order for the algorithms.
+algorithms are:
+.em
+AES@_256, AES@_128, AES (both of the preceding), 3DES, and ARCFOUR@_128.
+Unrecognized algorithms are ignored. In a server, the order of the list is
+unimportant; the server will advertise the availability of all the relevant
+cipher suites. However, in a client, the order of the list specifies a
+preference order for the algorithms. The first one in the client's list that is
+also advertised by the server is tried first. The default order is as listed
+above.
.nem
source of this background information, which is not Exim-specific. (There are a
few comments below in section ~~SECTcerandall.)
-\**Note**\: These options do not apply when Exim is operating as a client --
-they apply only in the case of a server. For a client, you must set the options
+\**Note**\: These options do not apply when Exim is operating as a client --
+they apply only in the case of a server. For a client, you must set the options
of the same name in an \%smtp%\ transport.
With just these options, Exim will work as a server with clients such as
tls_dhparam = /some/file/name
.endd
is set, the SSL library is initialized for the use of Diffie-Hellman ciphers
-with the parameters contained in the file. This increases the set of cipher
+with the parameters contained in the file. This increases the set of cipher
suites that the server supports. See the command
.display asis
openssl dhparam
.endd
for a way of generating this data.
-At present, \tls@_dhparam\ is used only when Exim is linked with OpenSSL. It is
+At present, \tls@_dhparam\ is used only when Exim is linked with OpenSSL. It is
ignored if GnuTLS is being used.
The strings supplied for these three options are expanded every time a client
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 `X=',
unless the \tls@_cipher\ log selector is turned off.
-The \encrypted\ condition can be used to test for specific cipher suites in
+The \encrypted\ condition can be used to test for specific cipher suites in
ACLs.
The ACLs that run for subsequent SMTP commands can check the name of the cipher
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 certificates. These must be available in a file or,
-.em
for OpenSSL only (not GnuTLS), a directory, identified by
\tls@_verify@_certificates\.
-.nem
A file can contain multiple certificates, concatenated end to end. If a
-directory is used
-.em
-(OpenSSL only),
-.nem
+directory is used
+(OpenSSL only),
each certificate must be in a separate file, with a name (or a symbolic link)
of the form <<hash>>.0, where <<hash>> is a hash value constructed from the
certificate. You can compute the relevant hash by running the command
\received@_header@_text\ to change the ::Received:: header. When no certificate
is supplied, \$tls@_peerdn$\ is empty.
-.em
.section Revoked certificates
.index TLS||revoked certificates
.index revocation list
identically named option for the \%smtp%\ 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.
-.nem
.section Configuring an Exim client to use TLS
.index cipher||logging
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
\tls@_verify@_hosts\ or \tls@_try@_verify@_hosts\ matches the client.
-\**Note**\: these options must be set in the \%smtp%\ transport for Exim to use
+\**Note**\: these options must be set in the \%smtp%\ 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.
If \tls@_verify@_certificates\ is set, it must name a file or,
-.em
for OpenSSL only (not GnuTLS), a directory, that contains a collection of
expected server certificates. The client verifies the server's certificate
against this collection, taking into account any revoked certificates that are
in the list defined by \tls@_crl\.
-.nem
If
\tls@_require@_ciphers\ is set on the \%smtp%\ transport, it must contain a
if \\AUTH\\ is in use, before sending the next message.
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
+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
and delay other deliveries to that host.
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
+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.
-There is also a manual override; you can set \hosts@_nopass@_tls\ on the
-\%smtp%\ transport to match those hosts for which Exim should not pass
+There is also a manual override; you can set \hosts@_nopass@_tls\ on the
+\%smtp%\ transport to match those hosts for which Exim should not pass
connections to new processes if TLS has been used.
Other parts of the \*modssl*\ documentation are also helpful, and have
links to further files.
Eric Rescorla's book, \*SSL and TLS*\, published by Addison-Wesley (ISBN
-0-201-61598-3), contains both introductory and more in-depth descriptions.
+0-201-61598-3), contains both introductory and more in-depth descriptions.
Some sample programs taken from the book are available from
.display rm
\?http://www.rtfm.com/openssl-examples/?\
.index policy control||access control lists
Access Control Lists (ACLs) are defined in a separate section of the run time
configuration file, headed by `begin acl'. Each ACL definition starts with a
-name, terminated by a colon. Here is a complete ACL section which contains just
+name, terminated by a colon. Here is a complete ACL section that contains just
one very small ACL:
.display asis
begin acl
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 over a pipe (using the \-bs-\ option).
-The most common use is for controlling which recipients are accepted in
-incoming messages. In addition, you can also 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 ~~CHAPdefconfil.
+when a local process submits a message using SMTP by specifying the \-bs-\
+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
+~~CHAPdefconfil.
.section Testing ACLs
The \-bh-\ command line option provides a way of testing your ACL configuration
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:
.index \\AUTH\\||ACL for
-.index \\DATA\\, ACL for
+.index \\DATA\\, ACLs for
.index \\ETRN\\||ACL for
.index \\EXPN\\||ACL for
.index \\HELO\\||ACL for
.index \\EHLO\\||ACL for
.index \\MAIL\\||ACL for
+.index \\QUIT\\, ACL for
.index \\RCPT\\||ACL for
.index \\STARTTLS\\, ACL for
.index \\VRFY\\||ACL for
+.index SMTP||connection, ACL for
+.index non-smtp message, ACL for
.display
.tabs 20
.if !~~sys.fancy
\acl@_not@_smtp\ $t $rm{ACL for non-SMTP messages}
\acl@_smtp@_auth\ $t $rm{ACL for \\AUTH\\}
\acl@_smtp@_connect\ $t $rm{ACL for start of SMTP connection}
-\acl@_smtp@_data\ $t $rm{ACL after \\DATA\\}
+\acl@_smtp@_data\ $t $rm{ACL after \\DATA\\ is complete}
\acl@_smtp@_etrn\ $t $rm{ACL for \\ETRN\\}
\acl@_smtp@_expn\ $t $rm{ACL for \\EXPN\\}
\acl@_smtp@_helo\ $t $rm{ACL for \\HELO\\ or \\EHLO\\}
\acl@_smtp@_mail\ $t $rm{ACL for \\MAIL\\}
-.newline
\acl@_smtp@_mailauth\ $t $rm{ACL for the \\AUTH\\ parameter of \\MAIL\\}
.newline
+.em
+\acl@_smtp@_mime\ $t $rm{ACL for content-scanning MIME parts}
+\acl@_smtp@_predata\ $t $rm{ACL at start of \\DATA\\ command}
+\acl@_smtp@_quit\ $t $rm{ACL for \\QUIT\\}
+.nem
+.newline
\acl@_smtp@_rcpt\ $t $rm{ACL for \\RCPT\\}
\acl@_smtp@_starttls\ $t $rm{ACL for \\STARTTLS\\}
\acl@_smtp@_vrfy\ $t $rm{ACL for \\VRFY\\}
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
+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.
-However, you cannot test the contents of the message, for example, to verify
-addresses in the headers, at \\RCPT\\ time. Such tests have to appear in the
-ACL that is run after the message has been received, before the final response
-to the \\DATA\\ command is sent. This is the ACL specified by
-\acl@_smtp@_data\. At this time, it is no longer possible to reject individual
-recipients. An error response should reject the entire message. Unfortunately,
-it is known that some MTAs do not treat hard (5$it{xx}) errors correctly at
-this point -- they keep the message on their queues and try again later, but
-that is their problem, though it does waste some of your resources.
-
-The ACL test specified by \acl@_smtp@_connect\ happens after the test specified
-by \host__reject__connection\ (which is now an anomaly) and any TCP Wrappers
-testing (if configured).
-
+.section The non-SMTP ACL
+.index non-smtp message, ACL for
The non-SMTP ACL applies to all non-interactive incoming messages, that is, it
applies to batch SMTP as well as to non-SMTP messages. (Batch SMTP is not
really SMTP.) This ACL is run just before the \*local@_scan()*\ function. Any
example, host tests, and tests on the state of the SMTP connection such as
encryption and authentication) are not relevant and are forbidden in this ACL.
+.section The connect ACL
+.index SMTP||connection, ACL for
+The ACL test specified by \acl@_smtp@_connect\ happens after the test specified
+by \host__reject__connection\ (which is now an anomaly) and any TCP Wrappers
+testing (if configured).
+
+.em
+.section The DATA ACLs
+.index \\DATA\\, ACLs for
+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 \acl@_smtp@_predata\
+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 \acl@_smtp@_data\ ACL is run.
+
+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 \acl@_smtp@_data\, which is the second ACL that is
+associated with the \\DATA\\ command.
+
+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$it{xx}) 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.
+
+.section The MIME ACL
+The \acl@_smtp@_mime\ option is available only when Exim is compiled with the
+content-scanning extension. For details, see chapter ~~CHAPexiscan.
+
+.section The QUIT ACL
+.rset SECTQUITACL "~~chapter.~~section"
+.index \\QUIT\\, ACL for
+The ACL for the SMTP \\QUIT\\ command is anomalous, in that the
+outcome of the ACL does not affect the response code to \\QUIT\\,
+which is always 221. Thus, the ACL does not in fact control any access.
+For this reason, the only verbs that are permitted are \accept\ and \warn\.
+
+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 \logwrite\ modifiers on a \warn\ verb.
+
+You do not need to have a final \accept\, but if you do, you can use a
+\message\ modifier to specify custom text that is sent as part of the 221
+response to \\QUIT\\.
+
+This ACL is run only for a `normal' \\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.
+.nem
+
+.section Finding an ACL to use
+.index ~~ACL||finding which to use
+The value of an \acl@_smtp@_$it{xxx}\ option is expanded before use, so you can
+use different ACLs in different circumstances. The resulting 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:
+.numberpars $.
+If the string begins with a slash, Exim uses it as a file name, and reads its
+contents as an ACL. The lines are processed in the same way as lines in the
+Exim configuration file. In particular, continuation lines are supported, blank
+lines are ignored, as are lines whose first non-whitespace character is `@#'.
+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:
+.display asis
+acl_smtp_data = /etc/acls/\
+ ${lookup{$sender_host_address}lsearch\
+ {/etc/acllist}{$value}{default}}
+.endd
+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.
+.nextp
+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.
+.nextp
+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
+.display asis
+acl_smtp_vrfy = accept
+.endd
+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.
+.endp
+
.section ACL return codes
.index ~~ACL||return codes
-The result of running an ACL is either `accept' or `deny', or, if some test
+.em
+Except for the \\QUIT\\ ACL, which does not affect the SMTP return code (see
+section ~~SECTQUITACL above), the
+.nem
+result of running an ACL is either `accept' or `deny', or, if some test
cannot be completed (for example, if a database is down), `defer'. These
results cause 2$it{xx}, 5$it{xx}, and 4$it{xx} return codes, respectively, to
be used in the SMTP dialogue. A fourth return, `error', occurs when there is an
error such as invalid syntax in the ACL. This also causes a 4$it{xx} return
code.
-The ACLs that are relevant to message reception may also return `discard'. This
+.em
+For the non-SMTP ACL, `defer' and `error' are treated in the same way as
+`deny', because there is no mechanism for passing temporary errors to the
+submitters of non-SMTP messages.
+.nem
+
+ACLs that are relevant to message reception may also return `discard'. This
has the effect of `accept', 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 great care.
+blackholing facility. Use it with care.
If the ACL for \\MAIL\\ returns `discard', all recipients are discarded, and no
ACL is run for subsequent \\RCPT\\ commands. The effect of `discard' in a
-\\RCPT\\ ACL is to discard just the one address. If there are no recipients
-left when the message's data is received, the \\DATA\\ ACL is not run. A
-`discard' return from the \\DATA\\ or the non-SMTP ACL discards all the
+\\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 `discard' return from the \\DATA\\ or the non-SMTP ACL discards all the
remaining recipients.
+.em
+The `discard' return is not permitted for the \acl@_smtp@_predata\ ACL.
+.nem
-The \*local@_scan()*\ function is always run, even if there are no remaining
+.index \*local@_scan()*\ function||when all recipients discarded
+The \*local@_scan()*\ function is always run, even if there are no remaining
recipients; it may create new recipients.
.section Unset ACL options
.index ~~ACL||unset options
-.em
The default actions when any of the \acl@_$it{xxx}\ options are unset are not
all the same. \**Note**\: These defaults apply only when the relevant ACL is
-not defined at all. For any defined ACL, the default action if control reaches
+not defined at all. For any defined ACL, the default action when control reaches
the end of the ACL statements is `deny'.
-.nem
For \acl@_not@_smtp\, \acl@_smtp@_auth\, \acl@_smtp@_connect\,
\acl@_smtp@_data\, \acl@_smtp@_helo\, \acl__smtp__mail\, \acl@_smtp@_mailauth\,
-and \acl@_smtp@_starttls\, the
.em
-action when the ACL is not defined is `accept'.
+\acl@_smtp@_mime\, \acl@_smtp@_predata\, \acl@_smtp@_quit\,
+.nem
+and \acl__smtp__starttls\, the action when the ACL is not defined is `accept'.
For the others (\acl@_smtp@_etrn\, \acl@_smtp@_expn\, \acl@_smtp@_rcpt\, and
\acl@_smtp@_vrfy\), the action when the ACL is not defined is `deny'.
-.nem
This means that \acl@_smtp@_rcpt\ must be defined in order to receive any
messages over an SMTP connection. For an example, see the ACL in the default
configuration file.
.section Data for message ACLs
.index ~~ACL||data for message ACL
-When an ACL for \\MAIL\\, \\RCPT\\, or \\DATA\\ is being run, the variables
-that contain information about the host and the message's sender (for example,
-\$sender@_host@_address$\ and \$sender@_address$\) are set, and can be used in
-ACL statements. In the case of \\RCPT\\ (but not \\MAIL\\ or \\DATA\\),
-\$domain$\ and \$local@_part$\ are set from the argument address.
+.em
+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, \$sender@_host@_address$\ and \$sender@_address$\) are set, and
+can be used in ACL statements. In the case of \\RCPT\\ (but not \\MAIL\\ or
+\\DATA\\), \$domain$\ and \$local@_part$\ are set from the argument address.
-When an ACL for the \\AUTH\\ parameter of \\MAIL\\ is being run, the variables
-that contain information about the host are set, but \$sender@_address$\ is not
-yet set.
+When an ACL for the \\AUTH\\ parameter of \\MAIL\\ is running, the variables
+that contain information about the host are set, but \$sender@_address$\ is not
+yet set. Section ~~SECTauthparamail contains a discussion of this parameter and
+how it is used.
The \$message@_size$\ variable is set to the value of the \\SIZE\\ parameter on
-the \\MAIL\\ command at \\MAIL\\ and \\RCPT\\ time, or -1 if that parameter was
-not given.
-Its value is updated to the true message size by the time the ACL after
-\\DATA\\ is run.
+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).
The \$rcpt@_count$\ variable increases by one for each \\RCPT\\ command
received. The \$recipients@_count$\ 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,
-\$rcpt@_count$\ contains the total number of \\RCPT\\ commands, and
-\$recipients@_count$\ contains the total number of accepted recipients.
+it contains the number of previously accepted recipients. At \\DATA\\ time (for
+both the \\DATA\\ ACLs), \$rcpt@_count$\ contains the total number of \\RCPT\\
+commands, and \$recipients@_count$\ contains the total number of accepted
+recipients.
+.nem
.section Data for non-message ACLs
.rset SECTdatfornon "~~chapter.~~section"
.index ~~ACL||data for non-message ACL
-When an ACL for \\AUTH\\, \\ETRN\\, \\EXPN\\,
-\\STARTTLS\\,
-or \\VRFY\\ is being run, the remainder of the SMTP command line is placed in
+.em
+When an ACL is being run for \\AUTH\\, \\EHLO\\, \\ETRN\\, \\EXPN\\, \\HELO\\,
+.nem
+\\STARTTLS\\, or \\VRFY\\, the remainder of the SMTP command line is placed in
\$smtp@_command@_argument$\. This can be tested using a \condition\ 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
.display asis
acl_check_auth:
accept encrypted = *
+.newline
+.em
accept condition = ${if eq{${uc:$smtp_command_argument}}\
- {CRAM-MD5}{yes}{no}}
+ {CRAM-MD5}}
+.nem
+.newline
deny message = TLS encryption or CRAM-MD5 required
.endd
-(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 \server@_advertise@_condition\ authenticator
+(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 \server@_advertise@_condition\ authenticator
option to do this.)
-.section Use of the ACL selection options
-.index ~~ACL||specifying which to use
-The value of an \acl@_smtp@_$it{xxx}\ option is expanded before use, so you can
-use different ACLs in different circumstances, and in fact the resulting string
-does not have to be the name of a configured list. Having expanded the string,
-Exim searches for an ACL as follows:
-.numberpars $.
-If the string begins with a slash, Exim attempts to open the file and read
-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 `@#'.
-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:
-.display asis
-acl_smtp_data = /etc/acls/\
- ${lookup{$sender_host_address}lsearch\
- {/etc/acllist}{$value}{default}}
-.endd
-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.
-.nextp
-If the string does not start with a slash, and does not contain any spaces,
-Exim searches the ACL section of the configuration for a list whose name
-matches the string.
-.nextp
-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
-.display asis
-acl_smtp_vrfy = accept
-.endd
-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.
-.endp
-
-
.section Format of an ACL
.index ~~ACL||format of
.index ~~ACL||verbs, definition of
An individual ACL consists of a number of statements. Each statement starts
-with a verb, optionally followed by a number of conditions and other modifiers.
-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 `and' conjunction
-between conditions. For example:
+with a verb, optionally followed by a number of conditions and `modifiers'.
+.em
+Modifiers can change the way the verb operates, define error and log messages,
+set variables, insert delays, and vary the processing of accepted messages.
+.nem
+
+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 `and' conjunction between conditions. For
+example:
.display asis
deny dnslists = list1.example
dnslists = list2.example
.endd
+If there are no conditions, the verb is always obeyed.
+.em
+Exim stops evaluating the conditions and modifiers when it reaches a condition
+that fails. What happens then
+.nem
+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.
-If there are no conditions, the verb is always obeyed. What happens if any of
-the conditions are not met 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.
-
-The verbs are as follows:
+.section ACL verbs
+The ACL verbs are as follows:
.numberpars $.
+.index \accept\, ACL verb
\accept\: If all the conditions are met, the ACL returns `accept'. If any of
the conditions are not met, what happens depends on whether \endpass\ appears
-among the conditions (for syntax see below). If the failing condition precedes
-\endpass\, control is passed to the next ACL statement; if it follows
+among the conditions (for syntax see below). If the failing condition is before
+\endpass\, control is passed to the next ACL statement; if it is after
\endpass\, the ACL returns `deny'. Consider this statement, used to check a
\\RCPT\\ command:
.display asis
command is accepted if verification succeeds. However, if verification fails,
the ACL yields `deny', because the failing condition is after \endpass\.
.nextp
-\defer\: If all the conditions are met, the ACL returns `defer' which, in an
-SMTP session, causes a 4\*xx*\ response to be given. For a non-SMTP ACL,
+.index \defer\, ACL verb
+\defer\: If all the conditions are met, the ACL returns `defer' which, in an
+SMTP session, causes a 4\*xx*\ response to be given. For a non-SMTP ACL,
\defer\ is the same as \deny\, because there is no way of sending a temporary
error. For a \\RCPT\\ command, \defer\ is much the same as using a
\%redirect%\ router and \":defer:"\ while verifying, but the \defer\ verb can
be used in any ACL, and even for a recipient it might be a simpler approach.
.nextp
+.index \deny\, ACL verb
\deny\: If all the conditions are met, the ACL returns `deny'. If any of the
conditions are not met, control is passed to the next ACL statement. For
example,
.endd
rejects commands from hosts that are on a DNS black list.
.nextp
-\discard\: This verb behaves like \accept\, except that it returns `discard'
+.index \discard\, ACL verb
+\discard\: This verb behaves like \accept\, except that it returns `discard'
from the ACL instead of `accept'. It is permitted only on ACLs that are
concerned with receiving messages, and it causes recipients to be discarded.
-If the \log@_message\ modifier is set when \discard\ operates, its contents are
-added to the line that is automatically written to the log.
+If the \log@_message\ modifier is set when \discard\ operates, its contents are
+added to the line that is automatically written to the log.
If \discard\ 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
\\DATA\\ do not appear in the log line when the \log@_recipients\ log selector
is set.
.nextp
+.index \drop\, ACL verb
\drop\: This verb behaves like \deny\, except that an SMTP connection is
forcibly closed after the 5\*xx*\ error message has been sent. For example:
.display asis
drop message = I don't take more than 20 RCPTs
- condition = ${if > {$rcpt_count}{20}{yes}{no}}
+.newline
+.em
+ condition = ${if > {$rcpt_count}{20}}
+.nem
.endd
There is no difference between \deny\ and \drop\ for the connect-time ACL. The
connection is always dropped after sending a 550 response.
.nextp
+.index \require\, ACL verb
\require\: 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 `deny'. For
example, when checking a \\RCPT\\ command,
passes control to subsequent statements only if the message's sender can be
verified. Otherwise, it rejects the command.
.nextp
-.em
+.index \warn\, ACL verb
\warn\: If all the conditions are met, a header line is added to an incoming
message and/or a line is written to Exim's main log. In all cases, control
passes to the next ACL statement. The text of the added header line and the log
line are specified by modifiers; if they are not present, a \warn\ verb just
checks its conditions and obeys any `immediate' modifiers such as \set\ and
\logwrite\.
+.em
+There is more about adding header lines in section ~~SECTaddheadwarn.
+.nem
If any condition on a \warn\ statement cannot be completed (that is, there is
-some sort of defer), no header is added and the configured log line is not
-written. No further conditions or modifiers in the \warn\ statement are
+some sort of defer), no header lines are added and the configured log line is
+not written. No further conditions or modifiers in the \warn\ statement are
processed. The incident is logged, but the ACL continues to be processed, from
the next statement onwards.
-When testing an incoming message, the \message\ modifier can be used on a
-\warn\ statement to add an extra header line,
-.nem
-as in this example:
-.display asis
-warn message = X-blacklisted-at: $dnslist_domain
- dnslists = blackholes.mail-abuse.org : \
- dialup.mail-abuse.org
-.endd
-If an identical header line is requested several times (provoked, for example,
-by multiple \\RCPT\\ commands), only one copy is actually added to the message.
-.em
-If the text of the \message\ modifier is not a valid header line,
-\"X-ACL-Warn:"\ is added to the front of it.
-.nem
-
-Header lines that are added by an ACL at \\MAIL\\ or \\RCPT\\ time are not
-visible in string expansions in the ACL for subsequent \\RCPT\\ commands.
-However they are visible in string expansions in the ACL that is run after
-\\DATA\\. If you want to preserve data between \\MAIL\\ and \\RCPT\\ ACLs, you
-can use ACL variables, as described in the next section. If a message is
-rejected after \\DATA\\, all added header lines are included in the entry that
-is written to the reject log.
-
-If a \message\ modifier is present on a \warn\ verb in an ACL that is not
+If a \message\ modifier is present on a \warn\ verb in an ACL that is not
testing an incoming message, it is ignored, and the incident is logged.
-A \warn\ statement may use the \log@_message\ modifier to cause a line to be
-written to the main log when the statement's conditions are true.
-.em
-Just as for \message\, 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 \logwrite\ modifier instead.
-.nem
+A \warn\ statement may use the \log@_message\ modifier to cause a line to be
+written to the main log when the statement's conditions are true.
+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 \logwrite\ modifier instead.
When one of the \warn\ conditions is an address verification that fails, the
text of the verification failure message is in \$acl@_verify@_message$\. If you
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 @\ continuation mechanism.
-It is conventional to align the conditions vertically.
+continue it onto several physical lines by the usual backslash continuation
+mechanism. It is conventional to align the conditions vertically.
.section ACL variables
.rset SECTaclvariables "~~chapter.~~section"
.index ~~ACL||variables
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.
-There are two sets of these variables:
+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. There are two sets
+of these variables:
.numberpars $.
The values of \$acl@_c0$\ to \$acl@_c9$\ persist throughout an SMTP connection.
-They are never reset. Thus, a value that is set while receiving one message is
+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.
.nextp
The values of \$acl@_m0$\ to \$acl@_m9$\ 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.
.endp
-When a message is accepted, the current values of all the ACL variables are
+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 modifier called \set\. For example:
+time. The ACL variables are set by modifier called \set\. For example:
.display asis
accept hosts = whatever
set acl_m4 = some value
.endd
-Note that the leading dollar sign is not used when naming a variable that is to
+\**Note**\: 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
-\warn\ verb without any other modifiers.
+\warn\ verb without any other modifiers or conditions.
.section Condition and modifier processing
!verify = recipient
.endd
causes the ACL to return `deny' if the recipient domain ends in
-\*dom.example*\, but the recipient address cannot be verified.
+\*dom.example*\ and the recipient address cannot be verified.
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
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.
+.em
+The \control\ modifier affects the way an incoming message is handled.
+.nem
The positioning of the modifiers in an ACL statement important, because the
processing of a verb ceases as soon as its outcome is known. Only those
-modifiers that have already been encountered will take effect. For the \accept\
-and \require\ statements, this means that processing stops as soon as a false
-condition is met. For example, consider this use of the \message\ modifier:
+modifiers that have already been encountered will take effect. For example,
+consider this use of the \message\ modifier:
.display asis
require message = Can't verify sender
verify = sender
verify = recipient
message = This message cannot be used
.endd
-If sender verification fails, Exim knows that the result of the statement is
-`deny', so it goes no further. The first \message\ modifier has been seen, so
+If sender verification fails, Exim knows that the result of the statement is
+`deny', so it goes no further. The first \message\ 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 `current', but is never used
because there are no more conditions to cause failure.
For the \deny\ verb, on the other hand, it is always the last \message\
-modifier that is used, because all the conditions must be true for rejection to
-happen. Specifying more than one \message\ modifier does not make sense, and
+modifier that is used, because all the conditions must be true for rejection to
+happen. Specifying more than one \message\ modifier does not make sense, and
the message can even be specified after all the conditions. For example:
.display asis
deny hosts = ...
!senders = *@my.domain.example
message = Invalid sender from client host
.endd
-The `deny' result does not happen until the end of the statement is reached, by
+The `deny' result does not happen until the end of the statement is reached, by
which time Exim has set up the message.
.startitems
.item "control = <<text>>"
-.index message||submission
-This modifier may appear only in ACLs for commands relating to incoming
-messages. It affects the subsequent processing of the message, provided that
-the message is eventually accepted.
+.index \control\, ACL modifier
.em
-The text must be one of the words `freeze', `queue@_only', or `submission' (in
-the latter case, optionally followed by slash-delimited options). The first two
-cause the message to be frozen or just queued (without immediate delivery),
-respectively. The third tells Exim that this message is a submission from a
-local MUA. In this case, Exim applies certain fixups to the message if
-necessary. For example, it add a ::Date:: header line if one is not present.
-Details are given in chapter ~~CHAPmsgproc.
+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 \control\ modifier appears in a \\RCPT\\ ACL.
+
+As there are now quite a few controls that can be applied, they are described
+separately in section ~~SECTcontrols.
.nem
-
-Once one of these controls is set, it remains set for the message. For example,
-if \control\ is used in a \\RCPT\\ ACL, it applies to the whole message, not
-just the individual recipient. The \control\ modifier can be used in several
-different ways. For example:
+The \control\ modifier can be used in several different ways. For example:
.numberpars $.
It can be at the end of an \accept\ statement:
.display asis
-accept ...some conditions...
+accept ...some conditions
control = queue_only
.endd
-In this case, the control is applied when this statement yields `accept'.
+In this case, the control is applied when this statement yields `accept', in
+other words, when the conditions are all true.
.nextp
It can be in the middle of an \accept\ statement:
.display asis
control = queue_only
...some more conditions...
.endd
-If the first set of conditions are true, the control is applied, even if the
+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 `accept' for the control to
be relevant.
control = freeze
accept ...
.endd
-.em
This example of \warn\ does not contain \message\, \log@_message\, or
\logwrite\, so it does not add anything to the message and does not write a log
entry.
+.nextp
+.em
+If you want to apply a control unconditionally, you can use it with a \require\
+verb. For example:
+.display asis
+require control = no_multiline_response
.nem
+.endd
.endp
.item "delay = <<time>>"
+.index \delay\, ACL modifier
.index \-bh-\ option
This modifier causes Exim to wait for the time interval before proceeding. The
time is given in the usual Exim notation. This modifier may appear in any ACL.
-The delay happens as soon as the modifier is processed.
-.em
-However, when testing Exim using the \-bh-\ option, the delay is not actually
-imposed (an appropriate message is output).
-.nem
+The delay happens as soon as the modifier is processed. However, when testing
+Exim using the \-bh-\ option, the delay is not actually imposed (an appropriate
+message is output instead).
Like \control\, \delay\ can be used with \accept\ or
\deny\, for example:
deny ...some conditions...
delay = 30s
.endd
-The delay happens if all the conditions are true, before the statement returns
+The delay happens if all the conditions are true, before the statement returns
`deny'. Compare this with:
.display asis
deny delay = 30s
.endd
.item endpass
+.index \endpass\, ACL modifier
This modifier, which has no argument, is recognized only in \accept\
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 `deny'. See the description of \accept\ above.
.item "log@_message = <<text>>"
+.index \log@_message\, ACL modifier
This modifier sets up a message that is used as part of the log message if the
-ACL denies access
-.em
-or a \warn\ statement's conditions are true.
-.nem
-For example:
+ACL denies access or a \warn\ statement's conditions are true. For example:
.display asis
require log_message = wrong cipher suite $tls_cipher
encrypted = DES-CBC3-SHA
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 \$dnslist@_<<xxx>>$\ variables are set after a DNS
-black list lookup succeeds. If the expansion of \log@_message\ fails, or if the
+black list lookup succeeds. If the expansion of \log@_message\ fails, or if the
result is an empty string, the modifier is ignored.
If you want to use a \warn\ statement to log the result of an address
verification, you can use \$acl__verify__message$\ to include the verification
error message.
-.em
If \log@_message\ is used with a \warn\ statement, `Warning:' 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 \logwrite\ instead of
\log@_message\. In the absence of \log@_message\ and \logwrite\, nothing is
logged for a succesful \warn\ statement.
-.nem
If \log@_message\ is not present and there is no underlying error message (for
example, from the failure of address verification), but \message\ is present,
logging rejections.
.item "logwrite = <<text>>"
+.index \logwrite\, ACL modifier
.index log||in ACL, immediate
This modifier writes a message to a log file as soon as it is encountered when
-processing an ACL. (Compare \log@_message\, which,
-.em
-except in the case of \warn\,
-.nem
-is used only if the ACL statement denies access.) The \logwrite\ modifier can
-be used to log special incidents in ACLs. For example:
-.display
+processing an ACL. (Compare \log@_message\, which, except in the case of
+\warn\, is used only if the ACL statement denies access.) The \logwrite\
+modifier can be used to log special incidents in ACLs. For example:
+.display
accept <<some special conditions>>
control = freeze
logwrite = froze message because ...
.endd
.item "message = <<text>>"
+.index \message\, ACL modifier
This modifier sets up a text string that is expanded and used as an error
-message if the current statement causes the ACL to deny access. The expansion
-happens at the time Exim decides that access is to be denied, not at the time
+message if the current statement causes the ACL to deny access. The expansion
+happens at the time Exim decides that access is to be denied, not at the time
it processes \message\. If the expansion fails, or generates an empty string,
the modifier is ignored. For ACLs that are triggered by SMTP commands, the
message is returned as part of the SMTP error response.
The \message\ modifier is also used with the \warn\ verb to specify one or more
-header lines to be added to an incoming message when all the conditions are
-true.
-If \message\ is used with \warn\ in an ACL that is not concerned with receiving
-a message, it has no effect.
+header lines to be added to an incoming message when all the conditions are
+true. See section ~~SECTaddheadwarn for more details. If \message\ is used with
+\warn\ in an ACL that is not concerned with receiving a message, it has no
+effect.
The text 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. Like \log@_message\,
the contents of \message\ are not expanded until after a condition has failed.
-If \message\ is used on a statement that verifies an address, the message
-specified overrides any message that is generated by the verification process.
+If \message\ 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
\$acl@_verify@_message$\, so you can incorporate it into your message if you
wish. In particular, if you want the text from \:fail:\ items in \%redirect%\
use a \message\ modifier, or make use of \$acl@_verify@_message$\.
.item "set <<acl@_name>> = <<value>>"
-This modifier puts a value into one of the ACL variables (see section
+.index \set\, ACL modifier
+This modifier puts a value into one of the ACL variables (see section
~~SECTaclvariables).
.enditems
+.em
+.section Use of the control modifier
+.rset SECTcontrols "~~chapter.~~section"
+.index \control\, ACL modifier
+The \control\ modifier supports the following settings:
+
+.startitems
+
+.item "control = caseful@_local@_part"
+.item "control = caselower@_local@_part"
+.index ~~ACL||case of local part in
+.index case of local parts
+These two controls are permitted only in the ACL specified by \acl@_smtp@_rcpt\
+(that is, during \\RCPT\\ processing). By default, the contents of
+\$local@_part$\ are lower cased before ACL processing. If
+`caseful@_local@_part' is specified, any uppercase letters in the original
+local part are restored in \$local@_part$\ for the rest of the ACL, or until a
+control that sets `caselower@_local@_part' is encountered.
+
+This control affects only the current recipient. Moreover, it applies 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 \caseful@_local@_part\ generic router option).
+
+This facility could be used, for example, to add a spam score to local parts
+containing upper case letters. For example, using \$acl@_m4$\ to accumulate the
+spam score:
+.display asis
+warn control = caseful_local_part
+ set acl_m4 = ${eval:\
+ $acl_m4 + \
+ ${if match{$local_part}{[A-Z]}{1}{0}}\
+ }
+ control = caselower_local_part
+.endd
+Notice that we put back the lower cased version afterwards, assuming that
+is what is wanted for subsequent tests.
+
+.item "control = enforce@_sync"
+.item "control = no@_enforce@_sync"
+.index SMTP||synchronization checking
+.index synchronization checking in SMTP
+These controls make it possible to be selective about when SMTP synchronization
+is enforced. The global option \smtp@_enforce@_sync\ specifies the initial
+state of the switch (it is true by default). See the description of this option
+in chapter ~~CHAPmainconfig for details of SMTP synchronization checking.
+
+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
+\acl@_smtp@_connect\, 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.
+
+.item "control = fakereject/<<message>>"
+.index fake rejection
+.index rejection, fake
+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.
+
+The text for the 550 response is taken from the \control\ modifier. If no
+message is supplied, the following is used:
+.display asis
+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).
+.endd
+This facilty should be used with extreme caution.
+
+
+.item "control = freeze"
+.index frozen messages||forcing in ACL
+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.
+
+
+.item "control = no@_mbox@_unspool"
+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 `mbox format' 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.
+
+
+.item "control = no@_multiline@_response"
+.index multiline responses, suppressing
+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.
+
+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
+(`use multiline responses for more' 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:
+.numberpars
+Extra information that is normally output as part of a rejection caused by
+sender verification failure is omitted. Only the final line (typically `sender
+verification failed') is sent.
+.nextp
+If a \message\ modifier supplies a multiline response, only the first
+line is output.
+.endp
+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.
+
+
+.item "control = queue@_only"
+.index \queue@_only\
+.index queueing incoming messages
+This control is permitted only for the \\MAIL\\, \\RCPT\\, \\DATA\\, and
+non-SMTP ACLs, in other words, only when a message is being received. If the
+message is accepted, it is placed on Exim's queue and left there for delivery
+by a subsequent queue runner. No immediate delivery process is started. In
+other words, it has the effect as the \queue@_only\ global option. However, the
+control applies only to the current message, not to any subsequent ones that
+may be received in the same SMTP connection.
+
+
+.item "control = submission/<<options>>"
+.index message||submission
+.index submission mode
+This control is permitted only for the \\MAIL\\, \\RCPT\\, and start of data
+ACLs (the latter is the one defined by \acl@_smtp@_predata\). Setting it tells
+Exim that the current message is a submission from a local MUA. In this case,
+Exim operates in `submission mode', and applies certain fixups to the message
+if necessary. For example, it add a ::Date:: header line if one is not present.
+This control is not permitted in the \acl@_smtp@_data\ ACL, because that is too
+late (the message has already been created).
+
+Chapter ~~CHAPmsgproc describes the processing that Exim applies to messages.
+Section ~~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.
+
+.enditems
+.nem
+
+
+.em
+.section Adding header lines with the warn verb
+.rset SECTaddheadwarn "~~chapter.~~section"
+.index header lines||adding in an ACL
+.index header lines||position of added lines
+.index \warn\, ACL verb
+.index \message\, ACL modifier
+The \message\ modifier can be used on a \warn\ statement to add an extra header
+line to an incoming message, as in this example:
+.display asis
+warn message = X-blacklisted-at: $dnslist_domain
+ dnslists = sbl.spamhaus.org : \
+ dialup.mail-abuse.org
+.endd
+If an identical header line is requested several times (provoked, for example,
+by multiple \\RCPT\\ commands), only one copy is actually added to the message.
+If the text of the \message\ modifier contains one or more newlines that are
+not followed by a space or a tab, it is assumed to contain multiple header
+lines. Each one is checked for valid syntax; \"X-ACL-Warn:"\ is added to the
+front of any line that is not a valid header line.
+
+By default, new lines are added 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 ::Received:: lines), immediately after the first
+block of ::Received:: lines, or immediately before any line that is not a
+::Received:: or ::Resent-something:: header.
+
+This is done by specifying `:at@_start:', `:after@_received:', or
+`:at@_start@_rfc:' (or, for completeness, `:at@_end:') 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:
+.display asis
+warn message = :after_received:X-My-Header: something or other...
+.endd
+
+If more than one header is supplied in a single warn statement, 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 will
+end up in reverse order.
+
+\**Warning**\: 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.
+
+.index header lines||added, visibility of
+Header lines that are added by an ACL at \\MAIL\\ or \\RCPT\\ time are not
+visible in string expansions in ACLs for subsequent \\RCPT\\ commands or in the
+\acl@_smtp@_predata\ ACL. However, they are visible in string expansions in the
+ACL that is run after \\DATA\\ is complete (the \acl@_smtp@_data\ ACL). This is
+also true for header lines that are added in the \acl@_smtp@_predata\ ACL.
+If a message is rejected after \\DATA\\, all added header lines are included in
+the entry that is written to the reject log.
+
+If you want to preserve data between \\MAIL\\, \\RCPT\\, and the
+\acl@_smtp@_predata\ ACLs, you can use ACL variables, as described in section
+~~SECTaclvariables.
+.nem
+
.section ACL conditions
.rset SECTaclconditions "~~chapter.~~section"
.index ~~ACL||conditions, list of
+.em
+Some of conditions listed in this section are available only when Exim is
+compiled with the content-scanning extension. They are included here briefly
+for completeness. More detailed descriptions can be found in the discussion on
+content scanning in chapter ~~CHAPexiscan.
+.nem
+
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 \acl@_smtp@_data\
-and \acl__not__smtp\.
-You can use the same condition (obviously with different parameters) more than
-once in the same ACL statement. This provides a way of specifying an `and'
-conjunction.
+be done only in the ACLs specified by \acl@_smtp@_data\ and \acl__not__smtp\.
+You can use the same condition (with different parameters) more than once in
+the same ACL statement. This provides a way of specifying an `and' conjunction.
The conditions are as follows:
.startitems
.item "acl = <<name of acl or ACL string or file name >>"
.index ~~ACL||nested
.index ~~ACL||indirect
+.index \acl\, ACL condition
The possible values of the argument are the same as for the
\acl@_smtp@_$it{xxx}\ options. The named or inline ACL is run. If it returns
-`accept' the condition is true; if it returns `deny' the condition is false; if
-it returns `defer', the current ACL returns `defer'.
-If it returns `drop' and the outer condition denies access, the connection is
-dropped. If it returns `discard', the verb must be \accept\ or \discard\, and
-the action is taken immediately -- no further conditions are tested.
+`accept' the condition is true; if it returns `deny' the condition is false. If
+it returns `defer', the current ACL returns `defer'
+.em
+unless the condition is on a \warn\ verb. In that case, a `defer' return makes
+the condition false. This means that further processing of the \warn\ verb
+ceases, but processing of the ACL continues.
+.nem
+
+If the nested \acl\ returns `drop' and the outer condition denies access,
+the connection is dropped. If it returns `discard', the verb must be \accept\
+or \discard\, and the action is taken immediately -- no further conditions are
+tested.
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
+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.
.item "authenticated = <<string list>>"
+.index \authenticated\, ACL condition
.index authentication||ACL checking
.index ~~ACL||testing for authentication
If the SMTP connection is not authenticated, the condition is false. Otherwise,
.endd
.item "condition = <<string>>"
+.index \condition\, ACL condition
.index customizing||ACL condition
.index ~~ACL||customized test
+.index ~~ACL||testing, customized
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
`no' or `false', the condition is false. If the result is any non-zero number,
or one of the strings `yes' or `true', the condition is true. For any other
values, some error is assumed to have occured, and the ACL returns `defer'.
+
+.em
+.item "decode = <<location>>"
+.index \decode\, ACL condition
+This condition is available only when Exim is compiled with the
+content-scanning extension, and it is allowed only the the ACL defined by
+\acl@_smtp@_mime\. It causes the current MIME part to be decoded into a file.
+For details, see chapter ~~CHAPexiscan.
+.nem
+
+
.item "dnslists = <<list of domain names and other data>>"
+.index \dnslists\, ACL condition
.index DNS list||in ACL
.index black list (DNS)
.index ~~ACL||testing a DNS list
This condition checks for entries in DNS black lists. These are also known as
`RBL lists', after the original Realtime Blackhole List, but note that the use
-of the lists at \*mail-abuse.org*\ now carries a charge.
-There are too many different variants of this condition to describe briefly
+of the lists at \*mail-abuse.org*\ now carries a charge.
+There are too many different variants of this condition to describe briefly
here. See sections ~~SECTmorednslists--~~SECTmorednslistslast for details.
.item "domains = <<domain list>>"
+.index \domains\, ACL condition
.index domain||ACL checking
.index ~~ACL||testing a recipient domain
This condition is relevant only after a \\RCPT\\ command. It checks that the
until the next \domains\ test.
.item "encrypted = <<string list>>"
+.index \encrypted\, ACL condition
.index encryption||checking in an ACL
.index ~~ACL||testing for encryption
If the SMTP connection is not encrypted, the condition is false. Otherwise, the
.endd
.item "hosts = << host list>>"
+.index \hosts\, ACL condition
.index host||ACL checking
.index ~~ACL||testing the client host
This condition tests that the calling host matches the host list. If you have
which gives a custom error message for each denied host.
.item "local@_parts = <<local part list>>"
+.index \local@_parts\, ACL condition
.index local part||ACL checking
.index ~~ACL||testing a local part
This condition is relevant only after a \\RCPT\\ command. It checks that the
the result of the lookup is placed in \$local@_part@_data$\ until the next
\local@_parts\ test.
+
+.em
+.item "malware = <<option>>"
+.index \malware\, ACL condition
+.index ~~ACL||virus scanning
+.index ~~ACL||scanning for viruses
+This condition is available only when Exim is compiled with the
+content-scanning extension. It causes the incoming message to be scanned for
+viruses. For details, see chapter ~~CHAPexiscan.
+.nem
+
+
+.em
+.item "mime@_regex = <<list of regular expressions>>"
+.index \mime@_regex\, ACL condition
+.index ~~ACL||testing by regex matching
+This condition is available only when Exim is compiled with the
+content-scanning extension, and it is allowed only the the ACL defined by
+\acl@_smtp@_mime\. It causes the current MIME part to be scanned for a match
+with any of the regular expressions. For details, see chapter ~~CHAPexiscan.
+.nem
+
+
.item "recipients = <<address list>>"
+.index \recipients\, ACL condition
.index recipient||ACL checking
.index ~~ACL||testing a recipient
This condition is relevant only after a \\RCPT\\ command. It checks the entire
recipient address against a list of recipients.
+
+.em
+.item "regex = <<list of regular expressions>>"
+.index \regex\, ACL condition
+.index ~~ACL||testing by regex matching
+This condition is available only when Exim is compiled with the
+content-scanning extension. It causes the incoming message to be scanned
+for a match with any of the regular expressions. For details, see chapter
+~~CHAPexiscan.
+.nem
+
+
.item "sender@_domains = <<domain list>>"
+.index \sender@_domains\, ACL condition
.index sender||ACL checking
.index ~~ACL||testing a sender domain
This condition tests the domain of the sender of the message against the given
domain list.
\**Note**\: the domain of the sender address is in
-\$sender@_address@_domain$\. It is \*not*\ put in \$domain$\ 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
+\$sender@_address@_domain$\. It is \*not*\ put in \$domain$\ 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 \$domain$\) can
be used to influence the sender checking.
.item "senders = <<address list>>"
+.index \senders\, ACL condition
.index sender||ACL checking
.index ~~ACL||testing a sender
This condition tests the sender of the message against the given list. To test
senders = :
.endd
+
+.em
+.item "spam = <<username>>"
+.index \spam\, ACL condition
+.index ~~ACL||scanning for spam
+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 ~~CHAPexiscan.
+.nem
+
+
.item "verify = certificate"
+.index \verify\, ACL condition
.index TLS||client certificate verification
.index certificate||verification of client
.index ~~ACL||certificate verification
+.index ~~ACL||testing a TLS certificate
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 \tls@_verify@_hosts\
or \tls@_try@_verify@_hosts\ (see chapter ~~CHAPTLS).
.item "verify = header@_sender/<<options>>"
+.index \verify\, ACL condition
.index ~~ACL||verifying sender in the header
.index header lines||verifying the sender in
.index sender||verifying in header
.index verifying||sender in header
This condition is relevant only in an ACL that is run after a message has been
-received, that is, in an ACL specified by \acl@_smtp@_data\. It checks that
-there is a verifiable sender address in at least one of the ::Sender::,
-::Reply-To::, or ::From:: header lines. Details of address verification and the
-options are given later, starting at section ~~SECTaddressverification. You can
-combine this condition with the \senders\ condition to restrict it to bounce
-messages only:
+received, that is, in an ACL specified by \acl@_smtp@_data\
+.em
+or \acl@_not@_smtp\. It checks that there is a verifiable address in at least
+one of the ::Sender::, ::Reply-To::, or ::From:: header lines. Such an address
+is loosely thought of as a `sender' 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.
+.nem
+
+Details of address verification and the options are given later, starting at
+section ~~SECTaddressverification (callouts are described in section
+~~SECTcallver). You can combine this condition with the \senders\ condition to
+restrict it to bounce messages only:
.display asis
deny senders = :
message = A valid sender header is required for bounces
.endd
.item "verify = header@_syntax"
+.index \verify\, ACL condition
.index ~~ACL||verifying header syntax
.index header lines||verifying syntax
.index verifying||header syntax
received, that is, in an ACL specified by \acl@_smtp@_data\
or \acl@_not@_smtp\.
It checks the syntax of all header lines that can contain lists of addresses
-(::Sender::, ::From::, ::Reply-To::, ::To::, ::Cc::, and ::Bcc::).
+(::Sender::, ::From::, ::Reply-To::, ::To::, ::Cc::, and ::Bcc::).
Unqualified addresses (local parts without domains) are permitted only in
locally generated messages and from hosts that match
\sender@_unqualified@_hosts\ or \recipient@_unqualified@_hosts\, as
and this condition can be used to reject such messages.
.item "verify = helo"
+.index \verify\, ACL condition
.index ~~ACL||verifying HELO/EHLO
.index \\HELO\\||verifying
.index \\EHLO\\||verifying
to request it.
.item "verify = recipient/<<options>>"
+.index \verify\, ACL condition
.index ~~ACL||verifying recipient
.index recipient||verifying
.index verifying||recipient
.item "verify = reverse@_host@_lookup"
+.index \verify\, ACL condition
.index ~~ACL||verifying host reverse lookup
.index host||verifying reverse lookup
This condition ensures that a verified host name has been looked up from the IP
one of its aliases, does, when it is itself looked up in the DNS, yield the
original IP address.
-If this condition is used for a locally generated message (that is, when there
+If this condition is used for a locally generated message (that is, when there
is no client host involved), it always succeeds.
.item "verify = sender/<<options>>"
+.index \verify\, ACL condition
.index ~~ACL||verifying sender
.index sender||verifying
.index verifying||sender
-This condition is relevant only after a
-\\MAIL\\ or \\RCPT\\ command, or after a message has been received (the
-\acl@_smtp@_data\ or \acl@_not@_smtp\ ACLs).
+This condition is relevant only after a \\MAIL\\ or \\RCPT\\ command, or after
+a message has been received (the \acl@_smtp@_data\ or \acl@_not@_smtp\ 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. Details of
-verification are given later, starting at section ~~SECTaddressverification.
-Exim caches the result of sender verification, to avoid doing it more than once
-per message.
-
-.item "verify = sender=address/<<options>>"
+condition is true. Otherwise, the sender address is verified.
+.em
+If there is data in the \$address@_data$\ variable at the end of routing, its
+value is placed in \$sender__address__data$\ 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.
+
+Details of verification are given later, starting at section
+~~SECTaddressverification. Exim caches the result of sender verification, to
+avoid doing it more than once per message.
+
+.item "verify = sender=<<address>>/<<options>>"
+.index \verify\, ACL condition
This is a variation of the previous option, in which a modified address is
verified as a sender.
.index black list (DNS)
.index ~~ACL||testing a DNS list
In its simplest form, the \dnslists\ condition tests whether the calling host
-is on a DNS list by looking up the inverted IP address in one or more DNS
-domains. For example, if the calling host's IP address is 192.168.62.43, and
-the ACL statement is
+is on at least one of a number of DNS lists by looking up the inverted IP
+address in one or more DNS domains. For example, if the calling host's IP
+address is 192.168.62.43, and the ACL statement is
.display asis
deny dnslists = blackholes.mail-abuse.org : \
dialups.mail-abuse.org
.endd
-the following domains are looked up:
+the following records are looked up:
.display asis
43.62.168.192.blackholes.mail-abuse.org
-43.62.168.192.dialups.mail-abuse.org
+43.62.168.192.dialups.mail-abuse.org
+.endd
+.em
+As soon as Exim finds an existing DNS record, processing of the list stops.
+Thus, multiple entries on the list provide an `or' conjunction. If you want to
+test that a host is on more than one list (an `and' conjunction), you can use
+two separate conditions:
+.display asis
+deny dnslists = blackholes.mail-abuse.org
+ dnslists = dialups.mail-abuse.org
.endd
+.nem
If a DNS lookup times out or otherwise fails to give a decisive answer, Exim
-behaves as if the host is not on the relevant list. This is usually the
-required action when \dnslists\ is used with \deny\ (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:
+behaves as if the host
+.em
+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.
+.nem
+This is usually the required action when \dnslists\ is used with \deny\ (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:
.index \"+include@_unknown"\
.index \"+exclude@_unknown"\
.index \"+defer@_unknown"\
connections (but your local name server cache should be active).
+.em
+.section Specifying the IP address for a DNS list lookup
+.index DNS list||keyed by explicit IP address
+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:
+.display asis
+deny dnslists = black.list.tls/192.168.1.2
+.endd
+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
+~~SECTmulkeyfor below.
+.nem
+
+
.section DNS lists keyed on domain names
+.index DNS list||keyed by domain name
There are some lists that are keyed on domain names rather than inverted IP
addresses (see for example the \*domain based zones*\ link at
-\?http://www.rfc-ignorant.org/?\).
-.em
-No reversing of components is used with these lists.
-.nem
-You can change the name that is looked up in a DNS list by adding additional
-data to a \dnslists\ item, introduced by a slash. For example,
+\?http://www.rfc-ignorant.org/?\). 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,
.display asis
deny message = Sender's domain is listed at $dnslist_domain
dnslists = dsn.rfc-ignorant.org/$sender_address_domain
.display asis
tld.example.dsn.rfc-ignorant.org
.endd
-You can mix entries with and without additional data in the same \dnslists\
-condition.
+.em
+A single \dnslists\ condition can contain entries for both names and IP
+addresses. For example:
+.display asis
+deny dnslists = sbl.spamhaus.org : \
+ dsn.rfc-ignorant.org/$sender_address_domain
+.endd
+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.
+.nem
+
+
+.em
+.section Multiple explicit keys for a DNS list
+.rset SECTmulkeyfor "~~chapter.~~section"
+.index DNS list||multiple keys for
+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:
+.display asis
+dnslists = black.list.tld/name.1::name.2
+.endd
+or to change the separator character, like this:
+.display asis
+dnslists = black.list.tld/<;name.1;name.2
+.endd
+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:
+.display asis
+dnslists = black.list.tld/<;192.168.1.2;a.domain
+.endd
+The DNS lookups that occur are:
+.display asis
+2.1.168.192.black.list.tld
+a.domain.black.list.tld
+.endd
+Once a DNS record has been found (that matches a specific IP return
+address, if specified -- see section ~~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.
+
+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:
+.display asis
+dnslists = black.list.tld/a.domain : black.list.tld/b.domain
+dnslists = black.list.tld/a.domain::b.domain
+.endd
+However, when the data for the list is obtained from a lookup, the second form
+is usually much more convenient. Consider this example:
+.display asis
+deny message = The mail servers for the domain \
+ $sender_address_domain \
+ are listed at $dnslist_domain ($dnslist_value); \
+ see $dnslist_text.
+ dnslists = sbl.spamhaus.org/<|${lookup dnsdb {>|a=<|\
+ ${lookup dnsdb {>|mxh=\
+ $sender_address_domain} }} }
+.endd
+Note the use of \">|"\ 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:
+.display asis
+dnslists = sbl.spahmaus.org/<|192.168.2.3|192.168.5.6|...
+.endd
+Thus, this example checks whether or not the IP addresses of the sender
+domain's mail servers are on the Spamhaus black list.
+.nem
+
+
.section Data returned by DNS lists
+.index DNS list||data returned from
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.
Some DNS lists may return more than one address record.
.section Variables set from DNS lists
+.index DNS list||variables set from
When an entry is found in a DNS list, the variable \$dnslist@_domain$\
contains the name of the domain that matched, \$dnslist@_value$\ contains the
data from the entry, and \$dnslist@_text$\ contains the contents of any
.section Additional matching conditions for DNS lists
-If you add an equals sign and an IP address after a \dnslists\ domain name, you
-can restrict its action to DNS records with a matching right hand side. For
-example,
+.rset SECTaddmatcon "~~chapter.~~section"
+.index DNS list||matching specific returned data
+You can add an equals sign and an IP address after a \dnslists\ domain name in
+order to restrict its action to DNS records with a matching right hand side.
+For example,
.display asis
deny dnslists = rblplus.mail-abuse.org=127.0.0.2
.endd
any address record is considered to be a match. If more than one address record
is found on the list, they are all checked for a matching right-hand side.
-If you want to specify a constraining address and also change the name that is
-looked up, the address list must be specified first. For example:
-.display asis
-deny dnslists = dsn.rfc-ignorant.org\
- =127.0.0.2/$sender_address_domain
-.endd
-
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 \dnslists\
condition is true. For example:
deny dnslists = a.b.c=127.0.0.2,127.0.0.3
.endd
-If the character `&' is used instead of `=', the comparison for each listed
-IP address is done by a bitwise `and' 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
+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:
+.display asis
+deny dnslists = dsn.rfc-ignorant.org\
+ =127.0.0.2/$sender_address_domain
+.endd
+
+If the character `&' is used instead of `=', the comparison for each listed
+IP address is done by a bitwise `and' 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:
.display asis
dnslists = a.b.c&0.0.0.3
.section DNS lists and IPv6
.rset SECTmorednslistslast "~~chapter.~~section"
-If Exim is asked to do a dnslist lookup for an IPv6 address, it inverts it
+.index IPv6||DNS black lists
+.index DNS list||IPv6 usage
+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
.display asis
.display asis
*.3.some.list.example. A 127.0.0.1
.endd
-is probably intended to put the entire 3.0.0.0/8 IPv4 network on the list.
-Unfortunately, it also matches the entire 3@:@:/124 IPv6 network.
+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.
-You can exclude IPv6 addresses from DNS lookups by making use of a suitable
+You can exclude IPv6 addresses from DNS lookups by making use of a suitable
\condition\ condition, as in this example:
.display asis
-deny condition = ${if isip4{$sender_host_address}{yes}{no}}
+.newline
+.em
+deny condition = ${if isip4{$sender_host_address}}
+.nem
+.newline
dnslists = some.list.example
.endd
verify = sender/callout
verify = recipient/defer_ok/callout=10s,defer_ok
.endd
-The first stage of verification is to run the address through the routers, in
-`verify mode'. 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 \verify\ and \verify@_only\ (see chapter ~~CHAProutergeneric).
-
-If there is a defer error while doing this verification routing, the ACL
+.em
+The first stage of address verification, which always happens, is to run the
+address through the routers, in `verify mode'. 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 \verify\ and \verify@_only\
+(see chapter ~~CHAProutergeneric). If routing fails, verification fails.
+The available options are as follows:
+.numberpars $.
+If the \callout\ option is specified, successful routing to one or more remote
+hosts is followed by a `callout' to those hosts as an additional check.
+Callouts and their sub-options are discussed in the next section.
+.nextp
+If there is a defer error while doing verification routing, the ACL
normally returns `defer'. However, if you include \defer@_ok\ in the options,
-the condition is forced to be true instead.
+the condition is forced to be true instead. Note that this is a main
+verification option as well as a suboption for callouts.
+.nextp
+The \no@_details\ option is covered in section ~~SECTsenaddver, which discusses
+the reporting of sender address verification failures.
+.endp
+
+.index verifying||address, differentiating failures
+After an address verification failure, \$sender@_verify@_failure$\ or
+\$recipient@_verify@_failure$\ (as appropriate) contains one of the following
+words:
+.numberpars $.
+\qualify\: The address was unqualified (no domain), and the message
+was neither local nor came from an exempted host.
+.nextp
+\route\: Routing failed.
+.nextp
+\mail\: Routing succeeded, and a callout was attempted; rejection
+occurred at or before the \\MAIL\\ command (that is, on initial
+connection, \\HELO\\, or \\MAIL\\).
+.nextp
+\recipient\: The \\RCPT\\ command in a callout was rejected.
+.nextp
+\postmaster\: The postmaster check in a callout was rejected.
+.endp
+
+The main use of these variables is expected to be to distinguish between
+rejections of \\MAIL\\ and rejections of \\RCPT\\ in callouts.
+
+.nem
+
.section Callout verification
.rset SECTcallver "~~chapter.~~section"
verifying an address. However, Exim does cache the results of callouts, which
helps to reduce the cost. Details of caching are in the next section.
-.em
-Recipient callouts are usually used only between hosts that are controlled by
-the same administration. For example, a corporate gateway host could use
+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.
-.nem
-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 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.
If the \callout\ 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 \%dnslookup%\ or a
-\%manualroute%\ router, where the router specifies the hosts. However, if a
-router that does not set up hosts routes to an \%smtp%\ transport with a
+\%manualroute%\ router, where the router specifies the hosts. However, if a
+router that does not set up hosts routes to an \%smtp%\ transport with a
\hosts\ setting, the transport's hosts are used. If an \%smtp%\ transport has
\hosts@_override\ set, its hosts are always used, whether or not the router
supplies a host list.
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.) Otherwise, the default SMTP port is used. If a remote transport
+specifies an outgoing interface, this is used; otherwise the interface is not
specified.
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:
.display
-HELO <<primary host name>>
+.newline
+.em
+HELO <<smtp active host name>>
+.nem
+.newline
MAIL FROM:@<@>
RCPT TO:<<the address to be tested>>
QUIT
.endd
\\LHLO\\ is used instead of \\HELO\\ if the transport's \protocol\ option is
-set to `lmtp'.
+set to `lmtp'.
-.em
-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
-\use@_sender\ and \use@_postmaster\ options, described in the next section.
-.nem
+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
+\use@_sender\ and \use@_postmaster\ options, described in the next section.
If the response to the \\RCPT\\ command is a 2$it{xx} code, the verification
succeeds. If it is 5$it{xx}, the verification fails. For any other condition,
\callout\ option is given, in which case the condition is forced to succeed.
+
+
.section Additional parameters for callouts
.rset CALLaddparcall "~~chapter.~~section"
-.index callout||timeout, specifying
+.index callout||additional parameters for
The \callout\ option can be followed by an equals sign and a number of optional
parameters, separated by commas. For example:
.display asis
separate verify options, is retained for backwards compatibility, but is now
deprecated. The additional parameters for \callout\ are as follows:
-.numberpars $.
-<<a time>>: This specifies the timeout that applies for the callout attempt to
-each host. For example:
+.startitems
+
+.item "<<a time interval>>"
+.index callout||timeout, specifying
+This specifies the timeout that applies for the callout attempt to each host.
+For example:
.display asis
verify = sender/callout=5s
.endd
The default is 30 seconds. The timeout is used for each response from the
remote host.
-.nextp
+.em
+It is also used for the intial connection, unless overridden by the \connect\
+parameter.
+.nem
+
+.em
+.item "connect = <<time interval>>"
+.index callout||connection timeout, specifying
+This parameter makes it possible to set a different (usually
+smaller) timeout for making the SMTP connection.
+For example:
+.display asis
+verify = sender/callout=5s,connect=1s
+.endd
+If not specified, this timeout defaults to the general timeout value.
+.nem
+
+.item "defer@_ok"
.index callout||defer, action on
-\defer@_ok\: 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.
-.nextp
+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.
+
+.em
+.item "mailfrom = <<email address>>"
+.index callout||sender when verifying header
+When verifying addresses in header lines using the \header@_sender\
+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 \mailfrom\ callout parameter allows you to
+specify what address to use in the \\MAIL\\ command. For example:
+.display asis
+require verify = header_sender/callout=mailfrom=abcd@x.y.z
+.endd
+This parameter is available only for the \header@_sender\ verification option.
+.nem
+
+.em
+.item "maxwait = <<time interval>>"
+.index callout||overall timeout, specifying
+This parameter sets an overall timeout for performing a callout verification.
+For example:
+.display asis
+verify = sender/callout=5s,maxwait=30s
+.endd
+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).
+.nem
+
+.item "no@_cache"
.index callout||cache, suppressing
.index caching||callout, suppressing
-\no@_cache\: The callout cache is neither read nor updated.
-.nextp
+When this parameter is given, the callout cache is neither read nor updated.
+
+.item "postmaster"
.index callout||postmaster, checking
-\postmaster\: A successful callout check is followed by a similar check for the
-local part \*postmaster*\ at the same domain. If this address is rejected, the
-callout fails. 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.
-.nextp
+When this parameter is set, a sucessful callout check is followed by a similar
+check for the local part \*postmaster*\ at the same domain. If this address is
+rejected, the callout fails. 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.
+
+.em
+.item "postmaster@_mailfrom = <<email address>>"
+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:
+.display asis
+require verify = sender/callout=postmaster_mailfrom=abc@x.y.z
+.endd
+If both \postmaster\ and \postmaster@_mailfrom\ are present, the rightmost one
+overrides. The \postmaster\ parameter is equivalent to this example:
+.display asis
+require verify = sender/callout=postmaster_mailfrom=
+.endd
+\**Warning**\: 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.
+.nem
+
+.item "random"
.index callout||`random' check
-\random\: Before doing the normal callout check, Exim does a
+When this parameter is set, before doing the normal callout check, Exim does a
check for a `random' local part at the same domain. The local part is not
really random -- it is defined by the expansion of the option
\callout@_random@_local@_part\, which defaults to
specific local parts. If the `random' 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.
-.nextp
+
+.item "use@_postmaster"
.index callout||sender for recipient check
-.em
-\use@_postmaster\: This option applies to recipient callouts only. For example:
+This parameter applies to recipient callouts only. For example:
.display asis
deny !verify = recipient/callout=use_postmaster
.endd
It causes a non-empty postmaster address to be used in the \\MAIL\\ command
when performing the callout. The local part of the address is \"postmaster"\
and the domain is the contents of \$qualify@_domain$\.
-.nextp
-\use@_sender\: This option applies to recipient callouts only. For example:
+
+.item "use@_sender"
+This option applies to recipient callouts only. For example:
.display asis
require verify = recipient/callout=use_sender
.endd
It causes the message's actual sender address to be used in the \\MAIL\\
-command when performing the callout, instead of an empty address. The cache for
-such callouts 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. This option should be set only when you know that the
-called hosts make use of the sender when checking recipients.
+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.
+
+.enditems
+
+.em
+If you use any of the parameters that set a non-empty sender for the \\MAIL\\
+command (\mailfrom\, \postmaster@_mailfrom\, \use@_postmaster\, or
+\use@_sender\), 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 \use@_postmaster\ or \use@_sender\ in
+these circumstances.
+
+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.
+
+Another issue to think about when using non-empty senders for callouts is
+caching. When you set \mailfrom\ or \use@_sender\, 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.
+
.nem
-.endp
.section Callout caching
.index hints database||callout cache
.index callout||caching
.index caching||callout
-Exim caches the results of callouts in order to reduce the amount of resources
+Exim caches the results of callouts in order to reduce the amount of resources
used, unless you specify the \no@_cache\ parameter with the \callout\ option.
-A hints database called `callout' is used for the cache. Two different record
-types are used: one records the result of a callout check for a specific
+A hints database called `callout' 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 \*postmaster*\).
(default 2h) and \callout@_positive@_expire\ (default 24h), respectively.
If a host gives a negative response to an SMTP connection, or rejects any
-commands up to and including
+commands up to and including
.display asis
MAIL FROM:<>
.endd
-.em
(but not including the \\MAIL\\ command with a non-empty address),
-.nem
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
ensures that, for example, a host that stops accepting `random' local parts
will eventually be noticed.
-The callout caching mechanism is based entirely 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.
+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.
.section Sender address verification reporting
+.rset SECTsenaddver "~~chapter.~~section"
.index verifying||suppressing error details
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
.if ~~sys.fancy
.figure "Controlled relaying" rm
.indent 0
-.call aspic
+.call aspic -sgcal -nv
centre ~~sys.linelength;
magnify 0.8;
boundingbox 30;
.section Checking a relay configuration
.rset SECTcheralcon "~~chapter.~~section"
.index relaying||checking control of
-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
+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 \-bh-\ option to run a fake SMTP session with which you interact.
For specifically testing for unwanted relaying, the host
-\*relay-test.mail-abuse.org*\ provides a useful service. If you telnet to this
-host from the host on which Exim is running, using the normal telnet port, you
-will see a normal telnet connection message and then quite a long delay. Be
-patient. The remote host is making an SMTP connection back to your host, and
-trying a number of common probes to test for open relay vulnerability. The
+\*relay-test.mail-abuse.org*\ provides a useful service. If you telnet to this
+host from the host on which Exim is running, using the normal telnet port, you
+will see a normal telnet connection message and then quite a long delay. Be
+patient. The remote host is making an SMTP connection back to your host, and
+trying a number of common probes to test for open relay vulnerability. The
results of the tests will eventually appear on your terminal.
.
.
. ============================================================================
-.chapter Adding a local scan function to Exim
-.set runningfoot "local scan function"
-.rset CHAPlocalscan "~~chapter"
-.index \*local@_scan()*\ function||description of
-.index customizing||input scan using C function
-.index policy control||by local scan function
-
-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. You can do a
-certain amount through string expansions and the \condition\ condition in the
-ACL that runs after the SMTP \\DATA\\ command or the ACL for non-SMTP messages
-(see chapter ~~CHAPACL), but this has its limitations.
-
-.index \exiscan\
-An increasingly popular way of doing additional checking is to make use of the
-Exiscan patch for Exim, which adds ACL conditions that perform body scans of
-various kinds. This is available from
-.if ~~html
-[(A HREF="http://duncanthrax.net/exiscan-acl/")]
-/?http://duncanthrax.net/exiscan-acl/?\.
-[(/A)]
-.else
-\?http:@/@/duncanthrax.net/exiscan-acl/?\.
-.fi
-
-To allow for even more general checking that can be customized 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.
-
-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.
-
-Exim applies a timeout to calls of the local scan function, and there is an
-option called \local@_scan@_timeout\ for setting it. The default is 5 minutes.
-Zero means `no timeout'.
-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.
-
-
-.section Building Exim to use a local scan function
-.index \*local@_scan()*\ function||building Exim to use
-To make use of the local scan function feature, you must tell Exim where your
-function is before building Exim, by setting \\LOCAL@_SCAN@_SOURCE\\ in your
-\(Local/Makefile)\. A recommended place to put it is in the \(Local)\
-directory, so you might set
+.chapter Content scanning
+.set runningfoot "content scanning"
+.rset CHAPexiscan "~~chapter"
+.index content scanning
+.em
+The content-scanning extension of Exim, formerly known as `exiscan', 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.
+
+If you want to include the content-scanning features when you compile Exim, you
+need to arrange for \\WITH@_CONTENT@_SCAN\\ to be defined in your
+\(Local/Makefile)\. When you do that, the Exim binary is built with:
+.numberpars $.
+An additional ACL (\acl@_smtp@_mime\) that is run for all MIME parts.
+.nextp
+Additional ACL conditions and modifiers: \decode\, \malware\, \mime@_regex\,
+\regex\, and \spam\. These can be used in the ACL that is run at the end of
+message reception (the \acl@_smtp@_data\ ACL).
+.nextp
+An additional control feature (`no@_mbox@_unspool') that saves spooled copies
+of messages, or parts of messages, for debugging purposes.
+.nextp
+Additional expansion variables that are set in the new ACL and by the new
+conditions.
+.nextp
+Two new main configuration options: \av@_scanner\ and \spamd@_address\.
+.endp
+There is another content-scanning configuration option for \(Local/Makefile)\,
+called \\WITH@_OLD@_DEMIME\\. If this is set, the old, deprecated \demime\ ACL
+condition is compiled, in addition to all the other content-scanning features.
+
+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 \(Local/Makefile)\. Such features are not documented in
+this manual. You can find out about them by reading the file called
+\(doc/experimental.txt)\.
+
+All the content-scanning facilites work on a MBOX copy of the message that is
+temporarily created in a file called:
+.display
+<<spool@_directory>>/scan/<<message@_id>>/<<message@_id>>.eml
+.endd
+The \(.eml)\ 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 \acl@_smtp@_data\ ACL has finished running, unless
+.display asis
+control = no_mbox_unspool
+.endd
+has been encountered. When the MIME ACL decodes files, they are put into the
+same directory by default.
+
+
+.section Scanning for viruses
+.rset SECTscanvirus "~~chapter.~~section"
+.index virus scanning
+.index content scanning||for viruses
+.index content scanning||the \malware\ condition
+The \malware\ ACL condition lets you connect virus scanner software to Exim. It
+supports a `generic' interface to scanners called via the shell, and
+specialized interfaces for `daemon' type virus scanners, which are resident in
+memory and thus are much faster.
+
+.index \av@_scanner\
+You can set the \av@_scanner\ option in first part of the Exim configuration
+file to specify which scanner to use, together with any additional options that
+are needed. The basic syntax is as follows:
+.display
+av@_scanner = <<scanner-type>>:<<option1>>:<<option2>>:[...]
+.endd
+If you do not set \av@_scanner\, it defaults to
.display asis
-LOCAL_SCAN_SOURCE=Local/local_scan.c
+av_scanner = sophie:/var/run/sophie
.endd
-for example. The function must be called \*local@_scan()*\. 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)\.
+If the value of \av@_scanner\ starts with dollar character, it is expanded
+before use.
-If you want to make use of Exim's run time configuration file to set options
-for your \*local@_scan()*\ function, you must also set
+The following scanner types are supported in this release:
+.numberpars $.
+.index virus scanners||Kaspersky
+\aveserver\: This is the scanner daemon of Kaspersky Version 5. You can get a
+trial version at \?http://www.kaspersky.com?\. This scanner type takes one
+option, which is the path to the daemon's UNIX socket. The default is shown in
+this example:
.display asis
-LOCAL_SCAN_HAS_OPTIONS=yes
+av_scanner = aveserver:/var/run/aveserver
.endd
-in \(Local/Makefile)\ (see section ~~SECTconoptloc below).
-
+.nextp
+.index virus scanners||clamd
+\clamd\: This daemon-type scanner is GPL and free. You can get it at
+\?http://www.clamav.net/?\. Clamd does not seem to unpack MIME containers, so
+it is recommended to unpack MIME attachments in the MIME ACL. It takes one
+option: either the path and name of a UNIX socket file, or a hostname or IP
+number, and a port, separated by space, as in the second of these examples:
+.display asis
+av_scanner = clamd:/opt/clamd/socket
+av_scanner = clamd:192.168.2.100 1234
+.endd
+If the option is unset, the default is \(/tmp/clamd)\. Thanks to David Saez for
+contributing the code for this scanner.
-.section API for local@_scan()
-.rset SECTapiforloc "~~chapter.~~section"
-.index \*local@_scan()*\ function||API description
-You must include this line near the start of your code:
+.nextp
+.index virus scanners||command line interface
+\cmdline\: 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:
+.numberpars
+The full path and name of the scanner binary, with all command line options,
+and a placeholder (%s) for the directory to scan.
+.nextp
+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 `virus found'. This is called the
+`trigger' expression.
+.nextp
+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
+`name' expression.
+.endp
+For example, Sophos Sweep reports a virus on a line like this:
.display asis
-#include "local_scan.h"
+Virus 'W32/Magistr-B' found in file ./those.bat
.endd
-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 \"unsigned char"\ called \"uschar"\.
-It also contains the following macro definitions, to simplify casting character
-strings and pointers to character strings:
+For the trigger expression, we can just match the word `found'. 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:
.display asis
-#define CS (char *)
-#define CCS (const char *)
-#define CSS (char **)
-#define US (unsigned char *)
-#define CUS (const unsigned char *)
-#define USS (unsigned char **)
+av_scanner = cmdline:\
+ /path/to/sweep -all -rec -archive %s:\
+ found:'(.+)'
.endd
-The function prototype for \*local@_scan()*\ is:
+.nextp
+.index virus scanners||DrWeb
+\drweb\: The DrWeb daemon scanner (\?http://www.sald.com/?\) interface
+takes one argument, either a full path to a UNIX socket, or an IP address and
+port separated by whitespace, as in these examples:
.display asis
-extern int local_scan(int fd, uschar **return_text);
+av_scanner = drweb:/var/run/drwebd.sock
+av_scanner = drweb:192.168.2.20 31337
.endd
-The arguments are as follows:
-.numberpars $.
-\fd\ 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.
-\**Warning**\: You must \*not*\ close this file descriptor.
-
-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 \"-D"\ 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.
+If you omit the argument, the default path \(/usr/local/drweb/run/drwebd.sock)\
+is used. Thanks to Alex Miller for contributing the code for this scanner.
.nextp
-\return@_text\ 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.
-.endp
-The function must return an \int\ value which is one of the following macros:
-.numberpars $.
-\"LOCAL@_SCAN@_ACCEPT"\
+.index virus scanners||F-Secure
+\fsecure\: The F-Secure daemon scanner (\?http://www.f-secure.com?\) takes one
+argument which is the path to a UNIX socket. For example:
+.display asis
+av_scanner = fsecure:/path/to/.fsav
+.endd
+If no argument is given, the default is \(/var/run/.fsav)\. Thanks to Johan
+Thelmen for contributing the code for this scanner.
-The message is accepted. If you pass back a string of text, it is saved with
-the message, and made available in the variable \$local@_scan@_data$\. No
-newlines are permitted (if there are any, they are turned into spaces) and the
-maximum length of text is 1000 characters.
.nextp
-\"LOCAL@_SCAN@_ACCEPT@_FREEZE"\
+.index virus scanners||Kaspersky
+\kavdaemon\: This is the scanner daemon of Kaspersky Version 4. This version of
+the Kaspersky scanner is outdated. Please upgrade (see \aveserver\ above). This
+scanner type takes one option, which is the path to the daemon's UNIX socket.
+For example:
+.display asis
+av_scanner = kavdaemon:/opt/AVP/AvpCtl
+.endd
+The default path is \(/var/run/AvpCtl)\.
-This behaves as \\LOCAL@_SCAN@_ACCEPT\\, except that the accepted message is
-queued without immediate delivery, and is frozen.
.nextp
-\"LOCAL@_SCAN@_ACCEPT@_QUEUE"\
+.index virus scanners||mksd
+\mksd\: This is a daemon type scanner that is aimed mainly at Polish users,
+though some parts of documentation are now available in English. You can get it
+at \?http://linux.mks.com.pl/?\. The only option for this scanner type is the
+maximum number of processes used simultaneously to scan the attachments,
+provided that the demime facility is employed and also provided that mksd has
+been run with at least the same number of child processes. For example:
+.display asis
+av_scanner = mksd:2
+.endd
+You can safely omit this option (the default value is 1).
-This behaves as \\LOCAL@_SCAN@_ACCEPT\\, except that the accepted message is
-queued without immediate delivery.
.nextp
-\"LOCAL@_SCAN@_REJECT"\
+.index virus scanners||Sophos and Sophie
+\sophie\: Sophie is a daemon that uses Sophos' \libsavi\ library to scan for
+viruses. You can get Sophie at \?http://www.vanja.com/tools/sophie/?\. The only
+option for this scanner type is the path to the UNIX socket that Sophie uses
+for client communication. For example:
+.display asis
+av_scanner = sophie:/tmp/sophie
+.endd
+The default path is \(/var/run/sophie)\, so if you are using this, you can omit
+the option.
+.endp
-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
-\"@\n"\ in log lines.
-If no message is given, `Administrative prohibition' is used.
+When \av@_scanner\ is correctly set, you can use the \malware\ condition in the
+\\DATA\\ ACL. The \av@_scanner\ option is expanded each time \malware\ is
+called. This makes it possible to use different scanners. See further below for
+an example. The \malware\ 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 \av@_scanner\ disables
+this caching, in which case each use of the \malware\ condition causes a new
+scan of the message.
+
+The \malware\ condition takes a right-hand argument that is expanded before
+use. It can then be one of
+.numberpars $.
+`true', `*', or `1', 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.
.nextp
-\"LOCAL@_SCAN@_TEMPREJECT"\
-
-The message is temporarily rejected; the returned text is used as an error
-message as for \\LOCAL@_SCAN@_REJECT\\. If no message is given, `Temporary
-local problem' is used.
+`false' or `0', in which case no scanning is done and the condition fails
+immediately.
.nextp
-\"LOCAL@_SCAN@_REJECT@_NOLOGHDR"\
+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.
+.endp
+You can append \"/defer@_ok"\ to the \malware\ condition to accept messages even
+if there is a problem with the virus scanner.
-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
-\rejected@_header\ log selector for just this rejection. If \rejected@_header\
-is already unset (see the discussion of the \log@_selection\ option in section
-~~SECTlogselector), this code is the same as \\LOCAL@_SCAN@_REJECT\\.
+.index \$malware@_name$\
+When a virus is found, the condition sets up an expansion variable called
+\$malware@_name$\ that contains the name of the virus. You can use it in a
+\message\ modifier that specifies the error returned to the sender, and/or in
+logging data.
-.nextp
-\"LOCAL@_SCAN@_TEMPREJECT@_NOLOGHDR"\
+If your virus scanner cannot unpack MIME and TNEF containers itself, you should
+use the \demime\ condition (see section ~~SECTdemimecond) before the \malware\
+condition.
-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\\.
-.endp
+Here is a very simple scanning example:
+.display asis
+deny message = This message contains malware ($malware_name)
+ demime = *
+ malware = *
+.endd
+The next example accepts messages when there is a problem with the scanner:
+.display asis
+deny message = This message contains malware ($malware_name)
+ demime = *
+ malware = */defer_ok
+.endd
+The next example shows how to use an ACL variable to scan with both sophie and
+aveserver. It assumes you have set:
+.display asis
+av_scanner = $acl_m0
+.endd
+in the main Exim configuration.
+.display asis
+deny message = This message contains malware ($malware_name)
+ set acl_m0 = sophie
+ malware = *
-If the message is not being received by interactive SMTP, rejections are
-reported by writing to \stderr\ or by sending an email, as configured by the
-\-oe-\ command line options.
+deny message = This message contains malware ($malware_name)
+ set acl_m0 = aveserver
+ malware = *
+.endd
-.section Configuration options for local@_scan()
-.rset SECTconoptloc "~~chapter.~~section"
-.index \*local@_scan()*\ function||configuration options
-It is possible to have option settings in the main configuration file
-that set values in static variables in the \*local@_scan()*\ module. If you
-want to do this, you must have the line
+.section Scanning with SpamAssassin
+.rset SECTscanspamass "~~chapter.~~section"
+.index content scanning||for spam
+.index spam scanning
+.index SpamAssassin, scanning with
+The \spam\ ACL condition calls SpamAssassin's \spamd\ daemon to get a spam
+score and a report for the message. You can get SpamAssassin at
+\?http://www.spamassassin.org?\, or, if you have a working Perl installation,
+you can use CPAN by running:
.display asis
-LOCAL_SCAN_HAS_OPTIONS=yes
+perl -MCPAN -e 'install Mail::SpamAssassin'
.endd
-in your \(Local/Makefile)\ when you build Exim. (This line is in
-\(OS/Makefile-Default)\, commented out). Then, in the \*local@_scan()*\ source
-file, you must define static variables to hold the option values, and a table to
-define them.
+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.
-The table must be a vector called \local@_scan@_options\, of type
-\"optionlist"\. 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 \local@_scan@_options\ you must also define a
-variable called \local@_scan@_options@_count\ that contains the number of
-entries in the table. Here is a short example, showing two kinds of option:
+.index \spamd@_address\
+After having installed and configured SpamAssassin, start the \spamd\ daemon.
+By default, it listens on 127.0.0.1, TCP port 783. If you use another host or
+port for \spamd\, you must set the \spamd@_address\ option in the global part
+of the Exim configuration as follows (example):
.display asis
-static int my_integer_option = 42;
-static uschar *my_string_option = US"a default string";
+spamd_address = 192.168.99.45 387
+.endd
+You do not need to set this option if you use the default. As of version 2.60,
+\spamd\ also supports communication over UNIX sockets. If you want to use
+these, supply \spamd@_address\ with an absolute file name instead of a
+address/port pair:
+.display asis
+spamd_address = /var/run/spamd_socket
+.endd
-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);
+You can have multiple \spamd\ servers to improve scalability. These can reside
+on other hardware reachable over the network. To specify multiple \spamd\
+servers, put multiple address/port pairs in the \spamd@_address\ option,
+separated with colons:
+.display asis
+spamd_address = 192.168.2.10 783 : \
+ 192.168.2.11 783 : \
+ 192.168.2.12 783
.endd
-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:
+Up to 32 \spamd\ servers are supported. The servers are
+queried in a random fashion. When a server fails to respond
+to the connection attempt, all other servers are tried
+until one succeeds. If no server responds, the \spam\
+condition defers.
+
+\**Warning**\: It is not possible to use the UNIX socket connection method with
+multiple \spamd\ servers.
+
+Here is a simple example of the use of the \spam\ condition in a DATA ACL:
.display asis
-begin local_scan
-my_integer = 99
-my_string = some string of text...
+deny message = This message was classified as SPAM
+ spam = joe
.endd
-The available types of option data are as follows:
+The right-hand side of the \spam\ condition specifies the username that
+SpamAssassin should scan for. If you do not want to scan for a particular user,
+but rather use the SpamAssassin system-wide default profile, you can scan for
+an unknown user, or simply use `nobody'. However, you must put something on the
+right-hand side.
-.startitems
+The username allows you to use per-domain or per-user antispam profiles. The
+right-hand side is expanded before being used, so you can put lookups or
+conditions there. When the right-hand side evaluates to `0' or `false', no
+scanning is done and the condition fails immediately.
-.item opt@_bool
-This specifies a boolean (true/false) option. The address should point to
-a variable of type \"BOOL"\, which will be set to \\TRUE\\ or \\FALSE\\, which
-are macros that are defined as `1' and `0', 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.)
+The \spam\ condition returns true if the threshold specified in the user's
+SpamAssassin profile has been matched or exceeded. If you want to use the
+\spam\ condition for its side effects (see the variables below), you can make
+it always return `true' by appending \":true"\ to the username.
-.item "opt@_fixed"
-This specifies a fixed point number, such as is used for load averages.
-The address should point to a variable of type \"int"\. The value is stored
-multiplied by 1000, so, for example, 1.4142 is truncated and stored as 1414.
+.index spam scanning||returned variables
+When the \spam\ condition is run, it sets up the following expansion
+variables:
-.item "opt@_int"
-This specifies an integer; the address should point to a variable of type
-\"int"\. The value may be specified in any of the integer formats accepted by
-Exim.
+.push
+.indent 2em
-.item "opt@_mkint"
-This is the same as \opt@_int\, except that when such a value is output in a
-\-bP-\ listing, if it is an exact number of kilobytes or megabytes, it is
-printed with the suffix K or M.
+.tempindent 0
+\$spam@_score$\: The spam score of the message, for example `3.4' or `30.5'.
+This is useful for inclusion in log or reject messages.
-.item "opt@_octint"
-This also specifies an integer, but the value is always interpeted as an
-octal integer, whether or not it starts with the digit zero, and it is
-always output in octal.
+.tempindent 0
+\$spam@_score@_int$\: The spam score of the message, multiplied by ten, as an
+integer value. For example `34' or `305'. This is useful for numeric
+comparisons in conditions. This variable is special; it is saved with the
+message, and written to Exim's spool file. This means that it can be used
+during the whole life of the message on your Exim system, in particular, in
+routers or transports during the later delivery phase.
-.item "opt@_stringptr"
-This specifies a string value; the address must be a pointer to a
-variable that points to a string (for example, of type \"uschar $*$"\).
+.tempindent 0
+\$spam@_bar$\: A string consisting of a number of `+' or `@-' characters,
+representing the integer part of the spam score value. A spam score of 4.4
+would have a \$spam@_bar$\ value of `++++'. This is useful for inclusion in
+warning headers, since MUAs can match on such strings.
-.item "opt@_time"
-This specifies a time interval value. The address must point to a variable of
-type \"int"\. The value that is placed there is a number of seconds.
+.tempindent 0
+\$spam@_report$\: A multiline text table, containing the full SpamAssassin
+report for the message. Useful for inclusion in headers or reject messages.
-.enditems
+.pop
-If the \-bP-\ command line option is followed by \"local@_scan"\, Exim prints
-out the values of all the \*local@_scan()*\ options.
+The \spam\ condition caches its results. If you call it again with the same user
+name, it does not scan again, but rather returns the same values as before.
+The \spam\ condition returns DEFER if there is any error while running the
+message through SpamAssassin. If you want to treat DEFER as FAIL (to pass on to
+the next ACL statement block), append \"/defer@_ok"\ to the right-hand side of
+the spam condition, like this:
+.display asis
+deny message = This message was classified as SPAM
+ spam = joe/defer_ok
+.endd
+This causes messages to be accepted even if there is a
+problem with \spamd\.
-.section Available Exim variables
-.index \*local@_scan()*\ function||available Exim variables
-The header \(local@_scan.h)\ 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 variable by
-calling \*expand@_string()*\. The exported variables are as follows:
+Here is a longer, commented example of the use of the \spam\
+condition:
+.display asis
+# put headers in all messages (no matter if spam or not)
+warn message = X-Spam-Score: $spam_score ($spam_bar)
+ spam = nobody:true
+warn message = X-Spam-Report: $spam_report
+ spam = nobody:true
-.startitems
+# add second subject line with *SPAM* marker when message
+# is over threshold
+warn message = Subject: *SPAM* $h_Subject:
+ spam = nobody
-.item "unsigned int debug@_selector"
-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
-\*local@_scan()*\; they are defined as macros:
-.numberpars $.
-The \"D@_v"\ bit is set when \-v-\ 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.
+# reject spam at high scores (> 12)
+deny message = This message scored $spam_score spam points.
+ spam = nobody:true
+ condition = ${if >{$spam_score_int}{120}{1}{0}}
+.endd
+
+
+
+.section Scanning MIME parts
+.rset SECTscanmimepart "~~chapter.~~section"
+.index content scanning||MIME parts
+.index MIME content scanning
+.index \acl@_smtp@_mime\
+The \acl@_smtp@_mime\ global option defines an ACL that is called once for each
+MIME part of a message, including multipart types, in the sequence of their
+position in the message.
+
+This ACL is called (possibly many times) just before the \acl@_smtp@_data\ ACL,
+but only if the message has a ::MIME-Version:: header. When a call to the MIME
+ACL does not yield `accept', ACL processing is aborted and the appropriate
+result code is sent to the remote client. The \acl@_smtp@_data\ ACL is not
+called in this circumstance.
+
+At the start of the 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 `message/rfc822'. If you want to decode a MIME part
+into a disk file, you can use the \decode\ modifier. The general syntax is:
+.display
+decode = [/<<path>>/]<<filename>>
+.endd
+The right hand side is expanded before use. After expansion,
+the value can be:
+.numberpars
+`0' or `false', in which case no decoding is done.
.nextp
-The \"D@_local@_scan"\ bit is provided for use by \*local@_scan()*\; it is set
-by the \"+local@_scan"\ debug selector. It is not included in the default set
-of debugging bits.
+The string `default'. In that case, the file is put in the temporary `default'
+directory \(<<spool@_directory>>/scan/<<message@_id>>/)\ with a sequential file
+name consisting of the message id and a sequence number. The full path and name
+is available in \$mime@_decoded@_filename$\ after decoding.
+.nextp
+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 file name.
+.nextp
+If the string does not start with a slash, it is used as the
+filename, and the default path is then used.
.endp
-Thus, to write to the debugging output only when \"+local@_scan"\ has been
-selected, you should use code like this:
+You can easily decode a file with its original, proposed
+filename using
.display asis
-if ((debug_selector & D_local_scan) != 0)
- debug_printf("xxx", ...);
+decode = $mime_filename
.endd
+However, you should keep in mind that \$mime@_filename$\ might contain
+anything. If you place files outside of the default path, they are not
+automatically unlinked.
-.item "uschar *expand@_string@_message"
-After a failing call to \*expand@_string()*\ (returned value NULL), the
-variable \expand__string__message\ contains the error message, zero-terminated.
+For RFC822 attachments (these are messages attached to messages, with a
+content-type of `message/rfc822'), the ACL is called again in the same manner
+as for the primary message, only that the \$mime@_is@_rfc822$\ 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.
-.item "header@_line *header@_list"
-A pointer to a chain of header lines. The \header@_line\ structure is discussed
-below.
+The MIME ACL supports the \regex\ and \mime@_regex\ conditions. These can be
+used to match regular expressions against raw and decoded MIME parts,
+respectively. They are described in section ~~SECTscanregex.
-.item "header@_line *header@_last"
-A pointer to the last of the header lines.
+.index MIME content scanning||returned variables
+The following list describes all expansion variables that are
+available in the MIME ACL:
-.item "uschar *headers@_charset"
-The value of the \headers@_charset\ configuration option.
+.push
+.indent 2em
-.item "BOOL host@_checking"
-This variable is TRUE during a host checking session that is initiated by the
-\-bh-\ command line option.
+.tempindent 0
+\$mime@_boundary$\:
+If the current part is a multipart (see \$mime@_is@_multipart$\) below, it
+should have a boundary string, which is stored in this variable. If the current
+part has no boundary parameter in the ::Content-Type:: header, this variable
+contains the empty string.
-.item "uschar *interface@_address"
-The IP address of the interface that received the message, as a string. This
-is NULL for locally submitted messages.
+.tempindent 0
+\$mime@_charset$\:
+This variable contains the character set identifier, if one was found in the
+::Content-Type:: header. Examples for charset identifiers are:
+.display asis
+us-ascii
+gb2312 (Chinese)
+iso-8859-1
+.endd
+Please note that this value is not normalized, so you should do matches
+case-insensitively.
-.item "int interface@_port"
-The port on which this message was received.
+.tempindent 0
+\$mime@_content@_description$\:
+This variable contains the normalized content of the ::Content-Description::
+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.
-.item "uschar *message@_id"
-This variable contains the message id for the incoming message as a
-zero-terminated string.
+.tempindent 0
+\$mime@_content@_disposition$\:
+This variable contains the normalized content of the ::Content-Disposition::
+header. You can expect strings like `attachment' or `inline' here.
+.tempindent 0
+\$mime@_content@_id$\:
+This variable contains the normalized content of the ::Content-ID:: header.
+This is a unique ID that can be used to reference a part from another part.
-.item "uschar *received@_protocol"
-The name of the protocol by which the message was received.
+.tempindent 0
+\$mime@_content@_size$\:
+This variable is set only after the \decode\ 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 \$mime@_content@_size$\ of zero.
-.item "int recipients@_count"
-The number of accepted recipients.
+.tempindent 0
+\$mime@_content@_transfer@_encoding$\:
+This variable contains the normalized content of the
+::Content-transfer-encoding:: header. This is a symbolic name for an encoding
+type. Typical values are `base64' and `quoted-printable'.
-.item "recipient@_item *recipients@_list"
-.index recipient||adding in local scan
-.index recipient||removing in local scan
-The list of accepted recipients, held in a vector of length
-\recipients@_count\. The \recipient@_item\ structure is discussed below. You
-can add additional recipients by calling \*receive@_add@_recipient()*\ (see
-below). You can delete recipients by removing them from the vector and adusting
-the value in \recipients@_count\. In particular, by setting \recipients@_count\
-to zero you remove all recipients. If you then return the value
-\"LOCAL@_SCAN@_ACCEPT"\, the message is accepted, but immediately blackholed.
-To replace the recipients, set \recipients@_count\ to zero and then call
-\*receive@_add@_recipient()*\ as often as needed.
+.tempindent 0
+\$mime@_content@_type$\: If the MIME part has a ::Content-Type:: header, this
+variable contains its value, lowercased, and without any options (like `name'
+or `charset'). Here are some examples of popular MIME types, as they may appear
+in this variable:
+.display asis
+text/plain
+text/html
+application/octet-stream
+image/jpeg
+audio/midi
+.endd
+If the MIME part has no ::Content-Type:: header, this variable contains the
+empty string.
-.item "uschar *sender@_address"
-The envelope sender address. For bounce messages this is the empty string.
+.tempindent 0
+\$mime@_decoded@_filename$\:
+This variable is set only after the \decode\ modifier (see above) has been
+successfully run. It contains the full path and file name of the file
+containing the decoded data.
-.item "uschar *sender@_host@_address"
-The IP address of the sending host, as a string. This is NULL for
-locally-submitted messages.
+.tempindent 0
+\$mime@_filename$\: 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 ::Content-Type:: or ::Content-Disposition:: headers. The filename will be
+RFC2047 decoded, but no additional sanity checks are done. If no filename was
+found, this variable contains the empty string.
-.item "uschar *sender@_host@_authenticated"
-The name of the authentication mechanism that was used, or NULL if the message
-was not received over an authenticated SMTP connection.
+.tempindent 0
+\$mime@_is@_coverletter$\:
+This variable attempts to differentiate the `cover letter' of an e-mail from
+attached data. It can be used to clamp down on flashy or unneccessarily encoded
+content in the cover letter, while not restricting attachments at all.
-.item "uschar *sender@_host@_name"
-The name of the sending host, if known.
+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:
+.numberpars
+The outermost MIME part of a message is always a cover letter.
+.nextp
+If a multipart/alternative or multipart/related MIME part is a cover letter, so
+are all MIME subparts within that multipart.
+.nextp
+If any other multipart is a cover letter, the first subpart is a cover letter,
+and the rest are attachments.
+.nextp
+All parts contained within an attachment multipart are attachments.
+.endp
-.item "int sender@_host@_port"
-The port on the sending host.
+As an example, the following will ban `HTML mail' (including that sent with
+alternative plain text), while allowing HTML files to be attached. HTML
+coverletter mail attached to non-HMTL coverletter mail will also be allowed:
+.display asis
+deny message = HTML mail is not accepted here
+ !condition = $mime_is_rfc822
+ condition = $mime_is_coverletter
+ condition = ${if eq{$mime_content_type}{text/html}{1}{0}}
+.endd
-.item "BOOL smtp@_input"
-This variable is TRUE for all SMTP input, including BSMTP.
-.item "BOOL smtp@_batched@_input"
-This variable is TRUE for BSMTP input.
+.tempindent 0
+\$mime@_is@_multipart$\:
+This variable has the value 1 (true) when the current part has the main type
+`multipart', for example `multipart/alternative' or `multipart/mixed'. Since
+multipart entities only serve as containers for other parts, you may not want
+to carry out specific actions on them.
-.item "int store@_pool"
-The contents of this variable control which pool of memory is used for new
-requests. See section ~~SECTmemhanloc for details.
+.tempindent 0
+\$mime@_is@_rfc822$\:
+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.
-.enditems
+.tempindent 0
+\$mime@_part@_count$\:
+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
+\$mime@_is@_rfc822$\). The counter stays set after \acl@_smtp@_mime\ 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.
+.pop
-.section Structure of header lines
-The \header@_line\ structure contains the members listed below.
-You can add additional header lines by calling the \*header@_add()*\ function
-(see below). You can cause header lines to be ignored (deleted) by setting
-their type to $*$.
-.startitems
+.section Scanning with regular expressions
+.rset SECTscanregex "~~chapter.~~section"
+.index content scanning||with regular expressions
+.index regular expressions||content scanning with
+You can specify your own custom regular expression matches on the full body of
+the message, or on individual MIME parts.
-.item "struct header@_line *next"
-A pointer to the next header line, or NULL for the last line.
+The \regex\ 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 \regex\ condition matches
+linewise, with a maximum line length of 32K characters. That means you cannot
+have multiline matches with the \regex\ condition.
-.item "int type"
-A code identifying certain headers that Exim recognizes. The codes are printing
-characters, and are documented in chapter ~~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, ::Envelope-sender:: header lines.) Effectively,
-$*$ means `deleted'.
+The \mime@_regex\ 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 \decode\ modifier earlier in the ACL, it is
+decoded automatically when \mime@_regex\ is executed (using default path and
+filename values). If the decoded data is larger than 32K, only the first 32K
+characters are checked.
-.item "int slen"
-The number of characters in the header line, including the terminating and any
-internal newlines.
+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 \"@\N"\ facility to disable expansion.
+Here is a simple example that contains two regular expressions:
+.display asis
+deny message = contains blacklisted regex ($regex_match_string)
+ regex = [Mm]ortgage : URGENT BUSINESS PROPOSAL
+.endd
+The conditions returns true if any one of the regular expressions matches. The
+\$regex@_match@_string$\ expansion variable is then set up and contains the
+matching regular expression.
-.item "uschar *text"
-A pointer to the text of the header. It always ends with a newline, followed by
-a zero byte. Internal newlines are preserved.
+\**Warning**\: With large messages, these conditions can be fairly
+CPU-intensive.
-.enditems
+.section The demime condition
+.rset SECTdemimecond "~~chapter.~~section"
+.index content scanning||MIME checking
+.index MIME content scanning
+The \demime\ ACL condition provides MIME unpacking, sanity checking and file
+extension blocking. It uses a simpler interface to MIME decoding than the MIME
+ACL functionality, but provides no additional facilities. Please note that this
+condition is deprecated and kept only for for backward compatibility. You must
+set the \\WITH@_OLD@_DEMIME\\ option in \(Local/Makefile)\ at build time to be
+able to use the \demime\ condition.
-.section Structure of recipient items
-The \recipient@_item\ structure contains these members:
+The \demime\ condition unpacks MIME containers in the message. It detects
+errors in MIME containers and can match file extensions found in the message
+against a list. Using this facility produces files containing the unpacked MIME
+parts of the message in the temporary scan directory. If you do antivirus
+scanning, it is recommened that you use the \demime\ condition before the
+antivirus (\malware\) condition.
-.startitems
+On the right-hand side of the \demime\ condition you can pass a colon-separated
+list of file extensions that it should match against. For example:
+.display asis
+deny message = Found blacklisted file attachment
+ demime = vbs:com:bat:pif:prf:lnk
+.endd
+If one of the file extensions is found, the condition is true, otherwise it is
+false. If there is a temporary error while demimeing (for example, `disk
+full'), the condition defers, and the message is temporarily rejected (unless
+the condition is on a \warn\ verb).
-.item "uschar *address"
-This is a pointer to the recipient address as it was received.
+The right-hand side is expanded before being treated as a list, so you can have
+conditions and lookups there. If it expands to an empty string, `false', or
+zero (`0'), no demimeing is done and the condition is false.
-.item "int pno"
-This is used in later Exim processing when top level addresses are created
-by the \one@_time\ option. It is not relevant at the time \*local@_scan()*\ is
-run and
-must always contain -1 at this stage.
+The \demime\ condition set the following variables:
-.item "uschar *errors@_to"
-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 \errors@_to\ generic
-router option.)
-If a \*local@_scan()*\ function sets an \errors@_to\ field to an unqualified
-address, Exim qualifies it using the domain from \qualify@_recipient\.
-When \*local@_scan()*\ is called, the \errors@_to\ field is NULL for all
-recipients.
-.enditems
+.push
+.indent 2em
+.tempindent 0
+\$demime@_errorlevel$\: When an error is detected in a MIME container, this
+variable contains the severity of the error, as an integer number. The higher
+the value, the more severe the error. If this variable is unset or zero, no
+error occurred.
-.section Available Exim functions
-.index \*local@_scan()*\ function||available Exim functions
-The header \(local@_scan.h)\ gives you access to a number of Exim functions.
-These are the only ones that are guaranteed to be maintained from release to
-release:
+.tempindent 0
+\$demime@_reason$\: When \$demime@_errorlevel$\ is greater than zero, this
+variable contains a human-readable text string describing the MIME error that
+occurred.
-.startitems
+.tempindent 0
+\$found@_extension$\: When the \demime\ condition is true, this variable
+contains the file extension it found.
+
+.pop
+
+Both \$demime@_errorlevel$\ and \$demime@_reason$\ are set by the first call of
+the \demime\ condition, and are not changed on subsequent calls.
-.item "pid@_t child@_open(uschar **argv, uschar **envp, int newumask, int *infdptr, int *outfdptr, BOOL make@_leader)"
-This function creates a child process that runs the command specified by
-\argv\. The environment for the process is specified by \envp\, which can be
-NULL if no environment variables are to be passed. A new umask is supplied for
-the process in \newumask\.
+If you do not want to check for file extensions, but rather use the \demime\
+condition for unpacking or error checking purposes, pass `*' as the
+right-hand side value. Here is a more elaborate example of how to use this
+facility:
+.display asis
+# Reject messages with serious MIME container errors
+deny message = Found MIME error ($demime_reason).
+ demime = *
+ condition = ${if >{$demime_errorlevel}{2}{1}{0}}
-Pipes to the standard input and output of the new process are set up
-and returned to the caller via the \infdptr\ and \outfdptr\ arguments. The
-standard error is cloned to the standard output. If there are any file
-descriptors `in the way' in the new process, they are closed. If the final
-argument is TRUE, the new process is made into a process group leader.
+# Reject known virus spreading file extensions.
+# Accepting these is pretty much braindead.
+deny message = contains $found_extension file (blacklisted).
+ demime = com:vbs:bat:pif:scr
-The function returns the pid of the new process, or -1 if things go wrong.
+# Freeze .exe and .doc files. Postmaster can
+# examine them and eventually thaw them.
+deny log_message = Another $found_extension file.
+ demime = exe:doc
+ control = freeze
+.endd
-.item "int child@_close(pid@_t pid, int timeout)"
-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:
-.numberpars $.
->= 0
+.nem
-The process terminated by a normal exit and the value is the process ending
-status.
-.nextp
-< 0 and > --256
-The process was terminated by a signal and the value is the negation of the
-signal number.
-.nextp
---256
-The process timed out.
-.nextp
---257
+.
+.
+.
+.
+. ============================================================================
+.chapter Adding a local scan function to Exim
+.set runningfoot "local scan function"
+.rset CHAPlocalscan "~~chapter"
+.index \*local@_scan()*\ function||description of
+.index customizing||input scan using C function
+.index policy control||by local scan function
-The was some other error in wait(); \errno\ is still set.
-.endp
+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.
+.em
+The content scanning extension (chapter ~~CHAPexiscan) has facilities for
+passing messages to external virus and spam scanning software. You can also do
+.nem
+a certain amount in Exim itself through string expansions and the \condition\
+condition in the ACL that runs after the SMTP \\DATA\\ command or the ACL for
+non-SMTP messages (see chapter ~~CHAPACL), but this has its limitations.
+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.
-.item "pid@_t child@_open@_exim(int *fd)"
-This function provide you with a means of submitting a new message to
-Exim. (Of course, you can also call \(/usr/sbin/sendmail)\ yourself if you
-want, but this packages it all up for you.) The function creates a pipe,
-forks a subprocess that is running
-.display asis
-exim -t -oem -oi -f <>
-.endd
-and returns to you (via the \"int *"\ 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 ::To::, ::Cc::, and/or ::Bcc:: header lines.
+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.
-When you have finished, call \*child@_close()*\ 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.
+Exim applies a timeout to calls of the local scan function, and there is an
+option called \local@_scan@_timeout\ for setting it. The default is 5 minutes.
+Zero means `no timeout'.
+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.
-.item "void debug@_printf(char *, ...)"
-This is Exim's debugging function, with arguments as for \*(printf()*\. The
-output is written to the standard error stream. If no debugging is selected,
-calls to \*debug@_printf()*\ have no effect. Normally, you should make calls
-conditional on the \"local@_scan"\ debug selector by coding like this:
+
+.section Building Exim to use a local scan function
+.index \*local@_scan()*\ function||building Exim to use
+To make use of the local scan function feature, you must tell Exim where your
+function is before building Exim, by setting \\LOCAL@_SCAN@_SOURCE\\ in your
+\(Local/Makefile)\. A recommended place to put it is in the \(Local)\
+directory, so you might set
.display asis
-if ((debug_selector & D_local_scan) != 0)
- debug_printf("xxx", ...);
+LOCAL_SCAN_SOURCE=Local/local_scan.c
.endd
+for example. The function must be called \*local@_scan()*\. 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)\.
-.item "uschar *expand@_string(uschar *string)"
-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 \expand@_string@_message\ 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 \*store@_get()*\. See section
-~~SECTmemhanloc below for a discussion of memory handling.
-
-.item "void header@_add(int type, char *format, ...)"
-This function allows you to add additional header lines. 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 \*sprintf()*\.
-You may include internal newlines if you want, and you must ensure that the
-string ends with a newline.
+If you want to make use of Exim's run time configuration file to set options
+for your \*local@_scan()*\ function, you must also set
+.display asis
+LOCAL_SCAN_HAS_OPTIONS=yes
+.endd
+in \(Local/Makefile)\ (see section ~~SECTconoptloc below).
-.item "uschar *lss@_b64encode(uschar *cleartext, int length)"
-.index base64 encoding||functions for \*local@_scan()*\ use
-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 \*store@_get()*\. It is
-zero-terminated.
-.item "int lss@_b64decode(uschar *codetext, uschar **cleartext)"
-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.
-.item "int lss@_match@_domain(uschar *domain, uschar *list)"
-This function checks for a match in a domain list. Domains are always
-matched caselessly. The return value is one of the following:
-.display
-OK $rm{match succeeded}
-FAIL $rm{match failed}
-DEFER $rm{match deferred}
+.section API for local@_scan()
+.rset SECTapiforloc "~~chapter.~~section"
+.index \*local@_scan()*\ function||API description
+You must include this line near the start of your code:
+.display asis
+#include "local_scan.h"
+.endd
+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 \"unsigned char"\ called \"uschar"\.
+It also contains the following macro definitions, to simplify casting character
+strings and pointers to character strings:
+.display asis
+#define CS (char *)
+#define CCS (const char *)
+#define CSS (char **)
+#define US (unsigned char *)
+#define CUS (const unsigned char *)
+#define USS (unsigned char **)
.endd
-DEFER is usually caused by some kind of lookup defer, such as the
-inability to contact a database.
-
-.item "int lss@_match@_local@_part(uschar *localpart, uschar *list, BOOL caseless)"
-This function checks for a match in a local part list. The third argument
-controls case-sensitivity. The return values are as for
-\*lss@_match@_domain()*\.
-
-.item "int lss@_match@_address(uschar *address, uschar *list, BOOL caseless)"
-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 \*lss@_match@_domain()*\.
-.item "int lss@_match@_host(uschar *host@_name, uschar *host@_address, uschar *list)"
-This function checks for a match in a host list. The most common usage is
-expected to be
+The function prototype for \*local@_scan()*\ is:
.display asis
-lss_match_host(sender_host_name, sender_host_address, ...)
+extern int local_scan(int fd, uschar **return_text);
.endd
-An empty address field matches an empty item in the host list. If the
-host name is NULL, the name corresponding to \$sender@_host@_address$\ is
-automatically looked up if a host name is required to match an item in the
-list. The return values are as for \*lss@_match@_domain()*\, but in addition,
-\*lss@_match@_host()*\ returns ERROR in the case when it had to look up a host
-name, but the lookup failed.
+The arguments are as follows:
+.numberpars $.
+\fd\ 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.
+\**Warning**\: You must \*not*\ close this file descriptor.
-.item "void log@_write(unsigned int selector, int which, char *format, ...)"
-This function writes to Exim's log files. The first argument should be zero (it
-is concerned with \log@_selector\). The second argument can be \"LOG@_MAIN"\ or
-\"LOG@_REJECT"\ or
-\"LOG@_PANIC"\ or the inclusive `or' 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.
+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 \"-D"\ 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.
+.nextp
+\return@_text\ 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.
+.endp
+The function must return an \int\ value which is one of the following macros:
+.numberpars $.
+\"LOCAL@_SCAN@_ACCEPT"\
-.item "void receive@_add@_recipient(uschar *address, int pno)"
-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 \qualify@_recipient\ domain. The second argument must always be -1.
+The message is accepted. If you pass back a string of text, it is saved with
+the message, and made available in the variable \$local@_scan@_data$\. No
+newlines are permitted (if there are any, they are turned into spaces) and the
+maximum length of text is 1000 characters.
+.nextp
+\"LOCAL@_SCAN@_ACCEPT@_FREEZE"\
-This function does not allow you to specify a private \errors@_to\ address (as
-described with the structure of \recipient@_item\ 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:
-.display asis
-receive_add_recipient(US"monitor@mydom.example", -1);
-recipients_list[recipients_count-1].errors_to =
- US"postmaster@mydom.example";
-.endd
+This behaves as \\LOCAL@_SCAN@_ACCEPT\\, except that the accepted message is
+queued without immediate delivery, and is frozen.
+.nextp
+\"LOCAL@_SCAN@_ACCEPT@_QUEUE"\
-.item "uschar *rfc2047@_decode(uschar *string, BOOL lencheck, uschar *target, int zeroval, int *lenptr, uschar **error)"
-This function decodes strings that are encoded according to RFC 2047. Typically
-these are the contents of header lines. First, each encoded `word' 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 \*iconv()*\ 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.
+This behaves as \\LOCAL@_SCAN@_ACCEPT\\, except that the accepted message is
+queued without immediate delivery.
+.nextp
+\"LOCAL@_SCAN@_REJECT"\
-The first argument is the string to be decoded. If \lencheck\ is TRUE, the
-maximum MIME word length is enforced. The third argument is the target
-encoding, or NULL if no translation is wanted.
-
-.index binary zero||in RFC 2047 decoding
-If a binary zero is encountered in the decoded string, it is replaced by the
-contents of the \zeroval\ argument. For use with Exim headers, the value must
-not be 0 because header lines are handled as zero-terminated strings.
+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
+\"@\n"\ in log lines.
+If no message is given, `Administrative prohibition' is used.
+.nextp
+\"LOCAL@_SCAN@_TEMPREJECT"\
-The function returns the result of processing the string, zero-terminated; if
-\lenptr\ is not NULL, the length of the result is set in the variable to which
-it points. When \zeroval\ is 0, \lenptr\ should not be NULL.
+The message is temporarily rejected; the returned text is used as an error
+message as for \\LOCAL@_SCAN@_REJECT\\. If no message is given, `Temporary
+local problem' is used.
+.nextp
+\"LOCAL@_SCAN@_REJECT@_NOLOGHDR"\
-If an error is encountered, the function returns NULL and uses the \error\
-argument to return an error message. The variable pointed to by \error\ 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.
+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
+\rejected@_header\ log selector for just this rejection. If \rejected@_header\
+is already unset (see the discussion of the \log@_selection\ option in section
+~~SECTlogselector), this code is the same as \\LOCAL@_SCAN@_REJECT\\.
+.nextp
+\"LOCAL@_SCAN@_TEMPREJECT@_NOLOGHDR"\
-.item "int smtp@_fflush(void)"
-This function is used in conjunction with \*smtp@_printf()*\, as described
-below.
+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\\.
+.endp
-.item "void smtp@_printf(char *, ...)"
-The arguments of this function are like \*printf()*\; 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 \smtp@_input\ is TRUE and \smtp@_batched@_input\ is
-FALSE. If you want to test for an incoming message from another host (as
-opposed to a local process that used the \-bs-\ command line option), you can
-test the value of \sender@_host@_address\, which is non-NULL when a remote host
-is involved.
+If the message is not being received by interactive SMTP, rejections are
+reported by writing to \stderr\ or by sending an email, as configured by the
+\-oe-\ command line options.
-If an SMTP TLS connection is established, \*smtp@_printf()*\ uses the TLS
-output function, so it can be used for all forms of SMTP connection.
-Strings that are written by \*smtp@_printf()*\ from within \*local@_scan()*\
-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:
-.display asis
-smtp_printf("550-this is some extra info\r\n");
-return LOCAL_SCAN_REJECT;
-.endd
-Note that you can also create multi-line responses by including newlines in
-the data returned via the \return@_text\ argument. The added value of using
-\*smtp@_printf()*\ is that, for instance, you could introduce delays between
-multiple output lines.
+.section Configuration options for local@_scan()
+.rset SECTconoptloc "~~chapter.~~section"
+.index \*local@_scan()*\ function||configuration options
+It is possible to have option settings in the main configuration file
+that set values in static variables in the \*local@_scan()*\ module. If you
+want to do this, you must have the line
+.display asis
+LOCAL_SCAN_HAS_OPTIONS=yes
+.endd
+in your \(Local/Makefile)\ when you build Exim. (This line is in
+\(OS/Makefile-Default)\, commented out). Then, in the \*local@_scan()*\ source
+file, you must define static variables to hold the option values, and a table to
+define them.
-The \*smtp@_printf()*\ function does not return any error indication, because it
-does not automatically flush 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 \*smtp@_fflush()*\, which has no
-arguments. It flushes the output stream, and returns a non-zero value if there
-is an error.
+The table must be a vector called \local@_scan@_options\, of type
+\"optionlist"\. 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 \local@_scan@_options\ you must also define a
+variable called \local@_scan@_options@_count\ that contains the number of
+entries in the table. Here is a short example, showing two kinds of option:
+.display asis
+static int my_integer_option = 42;
+static uschar *my_string_option = US"a default string";
-.item "void *store@_get(int)"
-This function accesses Exim's internal store (memory) manager. It gets a new
-chunk of memory whose size is given by the argument. Exim bombs out if it ever
-runs out of memory. See the next section for a discussion of memory handling.
+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);
+.endd
+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:
+.display asis
+begin local_scan
+my_integer = 99
+my_string = some string of text...
+.endd
+The available types of option data are as follows:
-.item "void *store@_get@_perm(int)"
-This function is like \*store@_get()*\, but it always gets memory from the
-permanent pool. See the next section for a discussion of memory handling.
+.startitems
-.item "uschar *string@_copy(uschar *string)"
-.item "uschar *string@_copyn(uschar *string, int length)" 0
-.item "uschar *string@_sprintf(char *format, ...)" 0
-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.
+.item opt@_bool
+This specifies a boolean (true/false) option. The address should point to
+a variable of type \"BOOL"\, which will be set to \\TRUE\\ or \\FALSE\\, which
+are macros that are defined as `1' and `0', 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.)
+
+.item "opt@_fixed"
+This specifies a fixed point number, such as is used for load averages.
+The address should point to a variable of type \"int"\. The value is stored
+multiplied by 1000, so, for example, 1.4142 is truncated and stored as 1414.
+
+.item "opt@_int"
+This specifies an integer; the address should point to a variable of type
+\"int"\. The value may be specified in any of the integer formats accepted by
+Exim.
+
+.item "opt@_mkint"
+This is the same as \opt@_int\, except that when such a value is output in a
+\-bP-\ listing, if it is an exact number of kilobytes or megabytes, it is
+printed with the suffix K or M.
+
+.item "opt@_octint"
+This also specifies an integer, but the value is always interpeted as an
+octal integer, whether or not it starts with the digit zero, and it is
+always output in octal.
+
+.item "opt@_stringptr"
+This specifies a string value; the address must be a pointer to a
+variable that points to a string (for example, of type \"uschar $*$"\).
+
+.item "opt@_time"
+This specifies a time interval value. The address must point to a variable of
+type \"int"\. The value that is placed there is a number of seconds.
.enditems
+If the \-bP-\ command line option is followed by \"local@_scan"\, Exim prints
+out the values of all the \*local@_scan()*\ options.
-.section More about Exim's memory handling
-.rset SECTmemhanloc "~~chapter.~~section"
-.index \*local@_scan()*\ function||memory handling
-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.
+.section Available Exim variables
+.index \*local@_scan()*\ function||available Exim variables
+The header \(local@_scan.h)\ 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 variable by
+calling \*expand@_string()*\. The exported variables are as follows:
-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.
+.startitems
-If you want to allocate memory that remains available for subsequent messages
-in the same SMTP connection, you should set
+.item "unsigned int debug@_selector"
+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
+\*local@_scan()*\; they are defined as macros:
+.numberpars $.
+The \"D@_v"\ bit is set when \-v-\ 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.
+.nextp
+The \"D@_local@_scan"\ bit is provided for use by \*local@_scan()*\; it is set
+by the \"+local@_scan"\ debug selector. It is not included in the default set
+of debugging bits.
+.endp
+Thus, to write to the debugging output only when \"+local@_scan"\ has been
+selected, you should use code like this:
.display asis
-store_pool = POOL_PERM
+if ((debug_selector & D_local_scan) != 0)
+ debug_printf("xxx", ...);
.endd
-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 \store@_pool\ or
-set it explicitly to \\POOL@_MAIN\\.
-The pool setting applies to all functions that get dynamic memory, including
-\*expand@_string()*\, \*store@_get()*\, and the \*string@_xxx()*\ functions.
-There is also a convenience function called \*store@_get@_perm()*\ that gets a
-block of memory from the permanent pool while preserving the value of
-\store@_pool\.
+.item "uschar *expand@_string@_message"
+After a failing call to \*expand@_string()*\ (returned value NULL), the
+variable \expand__string__message\ contains the error message, zero-terminated.
+.item "header@_line *header@_list"
+A pointer to a chain of header lines. The \header@_line\ structure is discussed
+below.
+.item "header@_line *header@_last"
+A pointer to the last of the header lines.
+.item "uschar *headers@_charset"
+The value of the \headers@_charset\ configuration option.
+.item "BOOL host@_checking"
+This variable is TRUE during a host checking session that is initiated by the
+\-bh-\ command line option.
-.
-.
-.
-.
-. ============================================================================
-.chapter System-wide message filtering
-.set runningfoot "system filtering"
-.rset CHAPsystemfilter "~~chapter"
-.index filter||system filter
-.index filtering all mail
-.index system filter
-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 $it{system filter}.
+.item "uschar *interface@_address"
+The IP address of the interface that received the message, as a string. This
+is NULL for locally submitted messages.
-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 \deliver\
-commands in a system router provide new envelope recipient addresses.
-The system filter must be an Exim filter. It cannot be a Sieve filter.
+.item "int interface@_port"
+The port on which this message was received.
-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 \first@_delivery\ condition in an \if\ command in the filter to prevent
-it happening on retries.
+.item "uschar *message@_id"
+This variable contains the message id for the incoming message as a
+zero-terminated string.
-\**Warning**\: Because the system filter runs just once, variables that are
-specific to individual recipient addresses, such as \$local@_part$\ and
-\$domain$\, are not set, and the `personal' 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 \%redirect%\ router, as
-described in section ~~SECTperaddfil below.
-.section Specifying a system filter
-.index uid (user id)||system filter
-.index gid (group id)||system filter
-The name of the file that contains the system filter must be specified by
-setting \system@_filter\. If you want the filter to run under a uid and gid
-other than root, you must also set \system@_filter@_user\ and
-\system@_filter@_group\ as appropriate. For example:
-.display asis
-system_filter = /etc/mail/exim.filter
-system_filter_user = exim
-.endd
-If a system filter generates any deliveries directly to files or pipes (via the
-\save\ or \pipe\ commands), transports to handle these deliveries must be
-specified by setting \system@_filter@_file@_transport\ and
-\system@_filter@_pipe@_transport\, respectively. Similarly,
-\system@_filter@_reply@_transport\ must be set to handle any messages generated
-by the \reply\ command.
+.item "uschar *received@_protocol"
+The name of the protocol by which the message was received.
-.section Testing a system filter
-You can run simple tests of a system filter in the same way as for a user
-filter, but you should use \-bF-\ rather than \-bf-\, so that features that
-are permitted only in system filters are recognized.
+.item "int recipients@_count"
+The number of accepted recipients.
-.section Contents of a system filter
-The language used to specify system filters is the same as for users' filter
-files. It is described in the separate end-user document \*Exim's interface to
-mail filtering*\. 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 \-bf-\,
-they cause errors.
+.item "recipient@_item *recipients@_list"
+.index recipient||adding in local scan
+.index recipient||removing in local scan
+The list of accepted recipients, held in a vector of length
+\recipients@_count\. The \recipient@_item\ structure is discussed below. You
+can add additional recipients by calling \*receive@_add@_recipient()*\ (see
+below). You can delete recipients by removing them from the vector and adusting
+the value in \recipients@_count\. In particular, by setting \recipients@_count\
+to zero you remove all recipients. If you then return the value
+\"LOCAL@_SCAN@_ACCEPT"\, the message is accepted, but immediately blackholed.
+To replace the recipients, set \recipients@_count\ to zero and then call
+\*receive@_add@_recipient()*\ as often as needed.
-.index frozen messages||manual thaw, testing in filter
-There are two special conditions which, though available in users' filter
-files, are designed for use in system filters. The condition \first@_delivery\
-is true only for the first attempt at delivering a message, and
-\manually@_thawed\ 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 \auto__thaw\ setting does not.
+.item "uschar *sender@_address"
+The envelope sender address. For bounce messages this is the empty string.
-\**Warning**\: If a system filter uses the \first@_delivery\ condition to
-specify an `unseen' (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.
+.item "uschar *sender@_host@_address"
+The IP address of the sending host, as a string. This is NULL for
+locally-submitted messages.
-When a system filter finishes running, the values of the variables \$n0$\ --
-\$n9$\ are copied into \$sn0$\ -- \$sn9$\ and are thereby made available to
-users' filter files. Thus a system filter can, for example, set up `scores' to
-which users' filter files can refer.
+.item "uschar *sender@_host@_authenticated"
+The name of the authentication mechanism that was used, or NULL if the message
+was not received over an authenticated SMTP connection.
+.item "uschar *sender@_host@_name"
+The name of the sending host, if known.
-.section Additional variable for system filters
-The expansion variable \$recipients$\, 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.
-
+.item "int sender@_host@_port"
+The port on the sending host.
-.section Defer, freeze, and fail commands for system filters
-.index freezing messages
-.index message||freezing
-.index message||forced failure
-.index \fail\||in system filter
-.index \freeze\ in system filter
-.index \defer\ in system filter
-There are three extra commands (\defer\, \freeze\ and \fail\) which are always
-available in system filters, but are not normally enabled in users' filters.
-(See the \allow@_defer\,
-\allow@_freeze\ and \allow@_fail\ options for the \%redirect%\ router.) These
-commands can optionally be followed by the word \text\ and a string containing
-an error message, for example:
-.display asis
-fail text "this message looks like spam to me"
-.endd
-The keyword \text\ is optional if the next character is a double quote.
+.item "BOOL smtp@_input"
+This variable is TRUE for all SMTP input, including BSMTP.
-The \defer\ command defers delivery of the original recipients of the message.
-The \fail\ command causes all the original recipients to be failed, and a
-bounce message to be created. The \freeze\ 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.
+.item "BOOL smtp@_batched@_input"
+This variable is TRUE for BSMTP input.
-The \freeze\ 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.
+.item "int store@_pool"
+The contents of this variable control which pool of memory is used for new
+requests. See section ~~SECTmemhanloc for details.
-.index log||\fail\ command log line
-.index \fail\||log line, reducing
-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 \"@<@<"\ and contains \"@>@>"\ 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:
-.display asis
-fail "<<filter test 1>>Your message is rejected \
- because it contains attachments that we are \
- not prepared to receive."
-.endd
+.enditems
-.index loop||caused by \fail\
-Take great care with the \fail\ 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 \fail\ command
-again (causing a mail loop) unless steps are taken to prevent this. Testing the
-\error@_message\ condition is one way to prevent this. You could use, for
-example
-.display asis
-if $message_body contains "this is spam" and not error_message
- then fail text "spam is not wanted here" endif
-.endd
-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.
-The interpretation of a system filter file ceases after a
-\defer\,
-\freeze\, or \fail\ 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
-.display asis
-mail ...
-freeze
-.endd
-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.
+.section Structure of header lines
+The \header@_line\ structure contains the members listed below.
+You can add additional header lines by calling the \*header@_add()*\ function
+(see below). You can cause header lines to be ignored (deleted) by setting
+their type to $*$.
+.startitems
-.section Adding and removing headers in a system filter
-.index header lines||adding in system filter
-.index header lines||removing in system filter
-.index filter||header lines, adding/removing
-Two filter commands that are available only in system filters are:
-.display asis
-headers add <<string>>
-headers remove <<string>>
-.endd
-The argument for the \headers add\ is a string which 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.
+.item "struct header@_line *next"
+A pointer to the next header line, or NULL for the last line.
-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. For that reason, it is usual to make the
-\headers add\ command conditional on \first@_delivery\.
+.item "int type"
+A code identifying certain headers that Exim recognizes. The codes are printing
+characters, and are documented in chapter ~~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, ::Envelope-sender:: header lines.) Effectively,
+$*$ means `deleted'.
-.em
-You can use `@\n' within the string, followed by white space, to specify
-continued header lines. More than one header may be added in one command by
-including `@\n' within the string without any following white space. For
-example:
-.display asis
-headers add "X-header-1: ....\n \
- continuation of X-header-1 ...\n\
- X-header-2: ...."
-.endd
-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.
+.item "int slen"
+The number of characters in the header line, including the terminating and any
+internal newlines.
-Header lines that are added by a system filter are visible to users' filter
-files and to all routers and transports.
-.nem
+.item "uschar *text"
+A pointer to the text of the header. It always ends with a newline, followed by
+a zero byte. Internal newlines are preserved.
-The argument for \headers remove\ 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 ::Envelope-To:: and
-::Return-Path::) cannot be removed by this means.
-If there is more than one header with the same name, they are all removed.
+.enditems
-.section Setting an errors address in a system filter
-.index envelope sender
-In a system filter, if a \deliver\ command is followed by
-.display
-errors@_to <<some address>>
-.endd
-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
-.display asis
-unseen deliver monitor@spying.example errors_to root@local.example
-.endd
-to take a copy which would not be sent back to the normal error reporting
-address if its delivery failed.
+.section Structure of recipient items
+The \recipient@_item\ structure contains these members:
-.section Per-address filtering
-.rset SECTperaddfil "~~chapter.~~section"
-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 \$local@_part$\ and \$domain$\ 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:
-.display asis
-central_filter:
-.newline
-.em
- check_local_user
-.newline
-.nem
- driver = redirect
- domains = +local_domains
- file = /central/filters/$local_part
- no_verify
- allow_filter
- allow_freeze
-.endd
-.em
-The filter is run in a separate process under its own uid. Therefore, either
-\check@_local@_user\ must be set (as above), in which case the filter is run as
-the local user, or the \user\ option must be used to specify which user to use.
-If both are set, \user\ overrides.
-.nem
+.startitems
-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.
+.item "uschar *address"
+This is a pointer to the recipient address as it was received.
+.item "int pno"
+This is used in later Exim processing when top level addresses are created
+by the \one@_time\ option. It is not relevant at the time \*local@_scan()*\ is
+run and
+must always contain -1 at this stage.
+.item "uschar *errors@_to"
+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 \errors@_to\ generic
+router option.)
+If a \*local@_scan()*\ function sets an \errors@_to\ field to an unqualified
+address, Exim qualifies it using the domain from \qualify@_recipient\.
+When \*local@_scan()*\ is called, the \errors@_to\ field is NULL for all
+recipients.
+.enditems
+.section Available Exim functions
+.index \*local@_scan()*\ function||available Exim functions
+The header \(local@_scan.h)\ gives you access to a number of Exim functions.
+These are the only ones that are guaranteed to be maintained from release to
+release:
-.
-.
-.
-.
-. ============================================================================
-.chapter Customizing bounce and warning messages
-.set runningfoot "customizing messages"
-.rset CHAPemsgcust "~~chapter"
-When a message fails to be delivered, or remains on 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.
+.startitems
-The ::From:: and ::To:: header lines are automatically generated; you can cause
-a ::Reply-To:: line to be added by setting the \errors@_reply@_to\ option. Exim
-also adds the line
-.display asis
-Auto-Submitted: auto-generated
-.endd
-to all warning and bounce messages,
+.item "pid@_t child@_open(uschar **argv, uschar **envp, int newumask, int *infdptr, int *outfdptr, BOOL make@_leader)"
+This function creates a child process that runs the command specified by
+\argv\. The environment for the process is specified by \envp\, which can be
+NULL if no environment variables are to be passed. A new umask is supplied for
+the process in \newumask\.
-.section Customizing bounce messages
-.index customizing||bounce message
-.index bounce message||customizing
-If \bounce@_message@_text\ is set, its contents are included in the default
-message immediately after `This message was created automatically by mail
-delivery software.' The string is not expanded. It is not used if
-\bounce@_message@_file\ is set.
+Pipes to the standard input and output of the new process are set up
+and returned to the caller via the \infdptr\ and \outfdptr\ arguments. The
+standard error is cloned to the standard output. If there are any file
+descriptors `in the way' in the new process, they are closed. If the final
+argument is TRUE, the new process is made into a process group leader.
-When \bounce@_message@_file\ 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.
+The function returns the pid of the new process, or -1 if things go wrong.
-Each item of text that is read from the file is expanded, and there are two
-expansion variables which can be of use here: \$bounce@_recipient$\ is set to
-the recipient of an error message while it is being created, and
-\$return@_size@_limit$\ contains the value of the \return@_size@_limit\ option,
-rounded to a whole number.
-The items must appear in the file in the following order:
+.item "int child@_close(pid@_t pid, int timeout)"
+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:
.numberpars $.
-The first item is included in the headers, and should include at least a
-::Subject:: header. Exim does not check the syntax of these headers.
-.nextp
-The second item forms the start of the error message. After it, Exim lists the
-failing addresses with their error messages.
+>= 0
+
+The process terminated by a normal exit and the value is the process ending
+status.
.nextp
-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.
+< 0 and > --256
+
+The process was terminated by a signal and the value is the negation of the
+signal number.
.nextp
-The fourth item is used to introduce the copy of the message that is returned
-as part of the error report.
-.nextp
-The fifth item is added after the fourth one if the returned message is
-truncated because it is bigger than \return@_size@_limit\.
+--256
+
+The process timed out.
.nextp
-The sixth item is added after the copy of the original message.
-.endp
-The default state (\bounce@_message@_file\ unset) is equivalent to the
-following file, in which the sixth item is empty. The ::Subject:: line has been
-split into two here in order to fit it on the page:
-.if ~~sys.fancy
-.display flow asis
-.fontgroup 0
-.font 54
-.else
-.rule
-.display flow asis
-.linelength 80em
-.indent 0
-.fi
-Subject: Mail delivery failed
- ${if eq{$sender_address}{$bounce_recipient}{: returning message to sender}}
-****
-This message was created automatically by mail delivery software.
+--257
-A message ${if eq{$sender_address}{$bounce_recipient}{that you sent }{sent by
+The was some other error in wait(); \errno\ is still set.
+.endp
- <$sender_address>
-}}could not be delivered to all of its recipients.
-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
------- $return_size_limit or so are included here.
-****
+.item "pid@_t child@_open@_exim(int *fd)"
+This function provide you with a means of submitting a new message to
+Exim. (Of course, you can also call \(/usr/sbin/sendmail)\ yourself if you
+want, but this packages it all up for you.) The function creates a pipe,
+forks a subprocess that is running
+.display asis
+exim -t -oem -oi -f <>
.endd
-.if !~~sys.fancy
-.rule
-.fi
+and returns to you (via the \"int *"\ 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 ::To::, ::Cc::, and/or ::Bcc:: header lines.
-.section Customizing warning messages
-.rset SECTcustwarn "~~chapter.~~section"
-.index customizing||warning message
-.index warning of delay||customizing the message
-The option
-\warn@_message@_file\
-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:
-.numberpars $.
-The first item is included in the headers, and should include at least a
-::Subject:: header. Exim does not check the syntax of these headers.
-.nextp
-The second item forms the start of the warning message. After it, Exim lists
-the delayed addresses.
-.nextp
-The third item then ends the message.
-.endp
-The default state is equivalent to the following file, except that the line
-starting `A message' has been split here, in order to fit it on the page:
-.if ~~sys.fancy
-.display asis
-.fontgroup 0
-.font 54
-.else
-.rule
-.display asis
-.linelength 80em
-.indent 0
-.fi
-.newline
-Subject: Warning: message $message_id delayed $warn_message_delay
-****
-This message was created automatically by mail delivery software.
+When you have finished, call \*child@_close()*\ 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.
-A message ${if eq{$sender_address}{$warn_message_recipients}
- {that you sent }{sent by
+.item "void debug@_printf(char *, ...)"
+This is Exim's debugging function, with arguments as for \*(printf()*\. The
+output is written to the standard error stream. If no debugging is selected,
+calls to \*debug@_printf()*\ have no effect. Normally, you should make calls
+conditional on the \"local@_scan"\ debug selector by coding like this:
+.display asis
+if ((debug_selector & D_local_scan) != 0)
+ debug_printf("xxx", ...);
+.endd
- <$sender_address>
+.item "uschar *expand@_string(uschar *string)"
+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 \expand@_string@_message\ 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 \*store@_get()*\. See section
+~~SECTmemhanloc below for a discussion of memory handling.
-}}has not been delivered to all of its recipients after
-more than $warn_message_delay on the queue on $primary_hostname.
-.newline
+.item "void header@_add(int type, char *format, ...)"
+.em
+This function allows you to an add additional header line at the end of the
+existing ones.
+.nem
+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 \*sprintf()*\. You may include internal newlines if you want, and you must
+ensure that the string ends with a newline.
-The message identifier is: $message_id
-The subject of the message is: $h_subject
-The date of the message is: $h_date
+.em
+.item "void header@_add@_at@_position(BOOL after, uschar *name, BOOL topnot, int type, char *$nh{format}, ...)"
+This function adds a new header line at a specified point in the header
+chain. The header itself is specified as for \*header@_add()*\.
-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.
+If \name\ is NULL, the new header is added at the end of the chain if \after\
+is true, or at the start if \after\ is false. If \name\ 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 \after\ is false. If \after\
+is true, the new header is added after the found header and any adjacent
+subsequent ones with the same name (even if marked `deleted'). If no matching
+non-deleted header is found, the \topnot\ 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 ::Received:: headers, or at the top if there are no
+::Received:: headers, you could use
+.display asis
+header_add_at_position(TRUE, US"Received", TRUE,
+ ' ', "X-xxx: ...");
.endd
-.if !~~sys.fancy
-.rule
-.fi
-except that in the default state the subject and date lines are omitted if no
-appropriate headers exist. During the expansion of this file,
-\$warn@_message@_delay$\
-is set to the delay time in one of the forms `<<n>> minutes'
-or `<<n>> hours', and
-\$warn@_message@_recipients$\
-contains a list of recipients for the warning message. There may be more than
-one if there are multiple addresses with different \errors@_to\ settings on the
-routers that handled them.
+Normally, there is always at least one non-deleted ::Received:: header, but
+there may not be if \received@_header@_text\ expands to an empty string.
+.item "void header@_remove(int occurrence, uschar *name)"
+This function removes header lines. If \occurrence\ 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.
-.
-.
-.
-. ============================================================================
-.chapter Some common configuration requirements
-.set runningfoot "common configuration requirements"
-.rset CHAPcomconreq "~~chapter"
-This chapter discusses some configuration requirements that seem to be fairly
-common. More examples and discussion can be found in the Exim book.
+.item "BOOL header@_testname(header@_line *hdr, uschar *name, int length, BOOL notdel)"
+This function tests whether the given header has the given name. It is not just
+a string comparison, because whitespace is permitted between the name and the
+colon. If the \notdel\ argument is true, a false return is forced for all
+`deleted' headers; otherwise they are not treated specially. For example:
+.display asis
+if (header_testname(h, US"X-Spam", 6, TRUE)) ...
+.endd
+.nem
-.section Sending mail to a smart host
-.index smart host||example router
-If you want to send all mail for non-local domains to a `smart host', you
-should replace the default \%dnslookup%\ router with a router which does the
-routing explicitly:
-.display asis
-send_to_smart_host:
- driver = manualroute
- route_list = !+local_domains smart.host.name
- transport = remote_smtp
+.item "uschar *lss@_b64encode(uschar *cleartext, int length)"
+.index base64 encoding||functions for \*local@_scan()*\ use
+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 \*store@_get()*\. It is
+zero-terminated.
+
+.item "int lss@_b64decode(uschar *codetext, uschar **cleartext)"
+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.
+
+.item "int lss@_match@_domain(uschar *domain, uschar *list)"
+This function checks for a match in a domain list. Domains are always
+matched caselessly. The return value is one of the following:
+.display
+OK $rm{match succeeded}
+FAIL $rm{match failed}
+DEFER $rm{match deferred}
.endd
-You can use the smart host's IP address instead of the name if you wish.
+DEFER is usually caused by some kind of lookup defer, such as the
+inability to contact a database.
+.item "int lss@_match@_local@_part(uschar *localpart, uschar *list, BOOL caseless)"
+This function checks for a match in a local part list. The third argument
+controls case-sensitivity. The return values are as for
+\*lss@_match@_domain()*\.
-.section Using Exim to handle mailing lists
-.rset SECTmailinglists "~~chapter.~~section"
-.index mailing lists
-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.
+.item "int lss@_match@_address(uschar *address, uschar *list, BOOL caseless)"
+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 \*lss@_match@_domain()*\.
-The \%redirect%\ 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 \domains\ router option can be used to run these
-lists in a separate domain from normal mail. For example:
+.item "int lss@_match@_host(uschar *host@_name, uschar *host@_address, uschar *list)"
+This function checks for a match in a host list. The most common usage is
+expected to be
.display asis
-lists:
- driver = redirect
- domains = lists.example
- file = /usr/lists/$local_part
- forbid_pipe
- forbid_file
- errors_to = $local_part-request@lists.example
- no_more
+lss_match_host(sender_host_name, sender_host_address, ...)
.endd
-This router is skipped for domains other than \*lists.example*\. 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 \no@_more\ is set, no subsequent
-routers are tried, and so the whole delivery fails.
+An empty address field matches an empty item in the host list. If the
+host name is NULL, the name corresponding to \$sender@_host@_address$\ is
+automatically looked up if a host name is required to match an item in the
+list. The return values are as for \*lss@_match@_domain()*\, but in addition,
+\*lss@_match@_host()*\ returns ERROR in the case when it had to look up a host
+name, but the lookup failed.
-The \forbid@_pipe\ and \forbid@_file\ options prevent a local part from being
-expanded into a file name or a pipe delivery, which is usually inappropriate in
-a mailing list.
+.item "void log@_write(unsigned int selector, int which, char *format, ...)"
+This function writes to Exim's log files. The first argument should be zero (it
+is concerned with \log@_selector\). The second argument can be \"LOG@_MAIN"\ or
+\"LOG@_REJECT"\ or
+\"LOG@_PANIC"\ or the inclusive `or' 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.
-.index \errors@_to\
-The \errors@_to\ 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.
-For example, using the configuration above, mail sent to
-\*dicts@@lists.example*\ is passed on to those addresses contained in
-\(/usr/lists/dicts)\, with error reports directed to
-\*dicts-request@@lists.example*\, provided that this address can be verified.
-There could be a file called \(/usr/lists/dicts-request)\ containing
-the address(es) of this particular list's manager(s), but other approaches,
-such as setting up an earlier router (possibly using the \local@_part@_prefix\
-or \local@_part@_suffix\ options) to handle addresses of the form \owner-xxx\
-or \xxx-request\, are also possible.
+.item "void receive@_add@_recipient(uschar *address, int pno)"
+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 \qualify@_recipient\ domain. The second argument must always be -1.
+This function does not allow you to specify a private \errors@_to\ address (as
+described with the structure of \recipient@_item\ 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:
+.display asis
+receive_add_recipient(US"monitor@mydom.example", -1);
+recipients_list[recipients_count-1].errors_to =
+ US"postmaster@mydom.example";
+.endd
-.section Syntax errors in mailing lists
-.index mailing lists||syntax errors in
-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.
+.em
+.item "BOOL receive@_remove@_recipient(uschar *recipient)"
+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.
+.nem
-If the \skip@_syntax@_errors\ option is set, the \%redirect%\ router just skips
-entries that fail to parse, noting the incident in the log. If in addition
-\syntax@_errors@_to\ is set to a verifiable address, a message is sent to it
-whenever a broken address is skipped. It is usually appropriate to set
-\syntax@_errors@_to\ to the same address as \errors@_to\.
+.item "uschar *rfc2047@_decode(uschar *string, BOOL lencheck, uschar *target, int zeroval, int *lenptr, uschar **error)"
+This function decodes strings that are encoded according to RFC 2047. Typically
+these are the contents of header lines. First, each encoded `word' 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 \*iconv()*\ 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.
-.section Re-expansion of mailing lists
-.index mailing lists||re-expansion of
-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.
+The first argument is the string to be decoded. If \lencheck\ is TRUE, the
+maximum MIME word length is enforced. The third argument is the target
+encoding, or NULL if no translation is wanted.
-If this behaviour is felt to be undesirable, the \one@_time\ option can be set
-on the \%redirect%\ 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
-`top level' addresses, and the parent address that generated them is marked
-`delivered'. 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.
+.index binary zero||in RFC 2047 decoding
+If a binary zero is encountered in the decoded string, it is replaced by the
+contents of the \zeroval\ argument. For use with Exim headers, the value must
+not be 0 because header lines are handled as zero-terminated strings.
-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
-\all@_parents\ selector is set, but for mailing lists there is normally only
-one level of expansion anyway.
+The function returns the result of processing the string, zero-terminated; if
+\lenptr\ is not NULL, the length of the result is set in the variable to which
+it points. When \zeroval\ is 0, \lenptr\ should not be NULL.
+If an error is encountered, the function returns NULL and uses the \error\
+argument to return an error message. The variable pointed to by \error\ 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.
-.section Closed mailing lists
-.index mailing lists||closed
-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
-\senders\ option to restrict the router that handles the list.
-The following example uses the same file as a list of recipients and as a list
-of permitted senders. It requires three routers:
-.display asis
-lists_request:
- driver = redirect
- domains = lists.example
- local_part_suffix = -request
- file = /usr/lists/$local_part$local_part_suffix
- no_more
+.item "int smtp@_fflush(void)"
+This function is used in conjunction with \*smtp@_printf()*\, as described
+below.
-lists_post:
- driver = redirect
- domains = lists.example
- senders = ${if exists {/usr/lists/$local_part}\
- {lsearch;/usr/lists/$local_part}{*}}
- file = /usr/lists/$local_part
- forbid_pipe
- forbid_file
- errors_to = $local_part-request@lists.example
- no_more
+.item "void smtp@_printf(char *, ...)"
+The arguments of this function are like \*printf()*\; 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 \smtp@_input\ is TRUE and \smtp@_batched@_input\ is
+FALSE. If you want to test for an incoming message from another host (as
+opposed to a local process that used the \-bs-\ command line option), you can
+test the value of \sender@_host@_address\, which is non-NULL when a remote host
+is involved.
-lists_closed:
- driver = redirect
- domains = lists.example
- allow_fail
- data = :fail: $local_part@lists.example is a closed mailing list
+If an SMTP TLS connection is established, \*smtp@_printf()*\ uses the TLS
+output function, so it can be used for all forms of SMTP connection.
+
+Strings that are written by \*smtp@_printf()*\ from within \*local@_scan()*\
+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:
+.display asis
+smtp_printf("550-this is some extra info\r\n");
+return LOCAL_SCAN_REJECT;
.endd
-All three routers have the same \domains\ setting, so for any other domains,
-they are all skipped. The first router runs only if the local part ends in
-\@-request\. It handles messages to the list manager(s) by means of an open
-mailing list.
+Note that you can also create multi-line responses by including newlines in
+the data returned via the \return@_text\ argument. The added value of using
+\*smtp@_printf()*\ is that, for instance, you could introduce delays between
+multiple output lines.
-The second router runs only if the \senders\ 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 \senders\ is $*$, which matches all senders. This
-means that the router runs, but because there is no list, declines, and
-\no@_more\ ensures that no further routers are run. The address fails with an
-`unrouteable address' error.
+The \*smtp@_printf()*\ function does not return any error indication, because it
+does not automatically flush 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 \*smtp@_fflush()*\, which has no
+arguments. It flushes the output stream, and returns a non-zero value if there
+is an error.
-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.
+.item "void *store@_get(int)"
+This function accesses Exim's internal store (memory) manager. It gets a new
+chunk of memory whose size is given by the argument. Exim bombs out if it ever
+runs out of memory. See the next section for a discussion of memory handling.
+.item "void *store@_get@_perm(int)"
+This function is like \*store@_get()*\, but it always gets memory from the
+permanent pool. See the next section for a discussion of memory handling.
+.item "uschar *string@_copy(uschar *string)"
+.item "uschar *string@_copyn(uschar *string, int length)" 0
+.item "uschar *string@_sprintf(char *format, ...)" 0
+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.
-.section Virtual domains
-.rset SECTvirtualdomains "~~chapter.~~section"
-.index virtual domains
-.index domain||virtual
-The phrase \*virtual domain*\ is unfortunately used with two rather different
-meanings:
-.numberpars $.
-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 `vanity' domains.
-.nextp
-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.
-.endp
-The first usage is probably more common, and does seem more `virtual' 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 \%dsearch%\ lookup type is useful here, leading
-to a router of this form:
-.display asis
-virtual:
- driver = redirect
- domains = dsearch;/etc/mail/virtual
- data = ${lookup{$local_part}lsearch{/etc/mail/virtual/$domain}}
- no_more
-.endd
-The \domains\ option specifies that the router is to be skipped, unless there
-is a file in the \(/etc/mail/virtual)\ directory whose name is the same as the
-domain that is being processed. When the router runs, it looks up the local
-part in the file to find a new address (or list of addresses). The \no@_more\
-setting ensures that if the lookup fails (leading to \data\ being an empty
-string), Exim gives up on the address without trying any subsequent routers.
+.enditems
-This one router can handle all the virtual domains because the alias file names
-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.
-The other kind of `virtual' 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:
-.display asis
-my_domains:
- driver = accept
- domains = dsearch;/etc/mail/domains
- local_parts = lsearch;/etc/mail/domains/$domain
- transport = my_mailboxes
-.endd
-The address is accepted if there is a file for the domain, and the local part
-can be found in the file. The \domains\ option is used to check for the file's
-existence because \domains\ is tested before the \local@_parts\ option (see
-section ~~SECTrouprecon). You can't use \require@_files\, because that option
-is tested after \local@_parts\. The transport is as follows:
-.display asis
-my_mailboxes:
- driver = appendfile
- file = /var/mail/$domain/$local_part
- user = mail
-.endd
-This uses a directory of mailboxes for each domain. The \user\ setting is
-required, to specify which uid is to be used for writing to the mailboxes.
-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.
+.section More about Exim's memory handling
+.rset SECTmemhanloc "~~chapter.~~section"
+.index \*local@_scan()*\ function||memory handling
+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.
+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.
-.section Multiple user mailboxes
-.rset SECTmulbox "~~chapter.~~section"
-.index multiple mailboxes
-.index mailbox||multiple
-.index local part||prefix
-.index local part||suffix
-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
-\local@_part@_prefix\ and \local@_part@_suffix\ can be used for this. For
-example, consider this router:
-.display asis
-userforward:
- driver = redirect
- check_local_user
- file = $home/.forward
- local_part_suffix = -*
- local_part_suffix_optional
- allow_filter
-.endd
-It runs a user's \(.forward)\ file for all local parts of the form
-\*username-$*$*\. Within the filter file the user can distinguish different
-cases by testing the variable \$local@_part@_suffix$\. For example:
+If you want to allocate memory that remains available for subsequent messages
+in the same SMTP connection, you should set
.display asis
-if $local_part_suffix contains -special then
- save /home/$local_part/Mail/special
-endif
+store_pool = POOL_PERM
.endd
-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
-\local@_part@_suffix\ option is made, they presumably fail. Thus, users have
-control over which suffixes are valid.
+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 \store@_pool\ or
+set it explicitly to \\POOL@_MAIN\\.
-Alternatively, a suffix can be used to trigger the use of a different
-\(.forward)\ file -- which is the way a similar facility is implemented in
-another MTA:
-.display asis
-userforward:
- driver = redirect
- check_local_user
- file = $home/.forward$local_part_suffix
- local_part_suffix = -*
- local_part_suffix_optional
- allow_filter
-.endd
-If there is no suffix, \(.forward)\ is used; if the suffix is \*-special*\, for
-example, \(.forward-special)\ 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
-\(.forward)\ file to use as a default.
-
-
-.section Simplified vacation processing
-.index vacation processing
-The traditional way of running the \*vacation*\ program is for a user to set up
-a pipe command in a \(.forward)\ file
-(see section ~~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:
-.numberpars $.
-A local part prefix such as `vacation-' can be specified on a router which
-can cause the message to be delivered directly to the \*vacation*\ program, or
-alternatively can use Exim's \%autoreply%\ transport. The contents of a user's
-\(.forward)\ file are then much simpler. For example:
-.display asis
-spqr, vacation-spqr
-.endd
-.nextp
-The \require@_files\ 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 \unseen\ 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, \(.vacation)\, containing a vacation
-message.
-.endp
-Another advantage of both these methods is that they both work even when the
-use of arbitrary pipes by users is locked out.
+The pool setting applies to all functions that get dynamic memory, including
+\*expand@_string()*\, \*store@_get()*\, and the \*string@_xxx()*\ functions.
+There is also a convenience function called \*store__get__perm()*\ that gets a
+block of memory from the permanent pool while preserving the value of
+\store@_pool\.
-.section Taking copies of mail
-.index message||copying every
-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.
-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, $it{inter alia}, to implement automatic
-notification of delivery by sites that insist on doing such things.
-.section Intermittently connected hosts
-.index intermittently connected hosts
-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.
+.
+.
+.
+.
+. ============================================================================
+.chapter System-wide message filtering
+.set runningfoot "system filtering"
+.rset CHAPsystemfilter "~~chapter"
+.index filter||system filter
+.index filtering all mail
+.index system filter
+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 $it{system filter}.
-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.
+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 \deliver\
+commands in a system router provide new envelope recipient addresses.
+The system filter must be an Exim filter. It cannot be a Sieve filter.
-.section Exim on the upstream server host
-It is tempting to arrange for incoming mail for the intermittently connected
-host to remain on 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.
+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 \first@_delivery\ condition in an \if\ command in the filter to prevent
+it happening on retries.
-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, `mailstore', 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.
+\**Warning**\: Because the system filter runs just once, variables that are
+specific to individual recipient addresses, such as \$local@_part$\ and
+\$domain$\, are not set, and the `personal' 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 \%redirect%\ router, as
+described in section ~~SECTperaddfil below.
-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:
-.display
-cheshire.wonderland.fict.example * F,5d,24h
+.section Specifying a system filter
+.index uid (user id)||system filter
+.index gid (group id)||system filter
+The name of the file that contains the system filter must be specified by
+setting \system@_filter\. If you want the filter to run under a uid and gid
+other than root, you must also set \system@_filter@_user\ and
+\system@_filter@_group\ as appropriate. For example:
+.display asis
+system_filter = /etc/mail/exim.filter
+system_filter_user = exim
.endd
-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 \-M-\ or \-R-\
-options, or by using the \\ETRN\\ SMTP command (see section ~~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.
+If a system filter generates any deliveries directly to files or pipes (via the
+\save\ or \pipe\ commands), transports to handle these deliveries must be
+specified by setting \system@_filter@_file@_transport\ and
+\system@_filter@_pipe@_transport\, respectively. Similarly,
+\system@_filter@_reply@_transport\ must be set to handle any messages generated
+by the \reply\ command.
-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 \retry__include__ip__address\ on the \%smtp%\ transport.
-Since this has disadvantages for permanently connected hosts, it is best to
-arrange a separate transport for the intermittently connected ones.
+.section Testing a system filter
+You can run simple tests of a system filter in the same way as for a user
+filter, but you should use \-bF-\ rather than \-bf-\, so that features that
+are permitted only in system filters are recognized.
+.em
+If you want to test the combined effect of a system filter and a user filter,
+you can use both \-bF-\ and \-bf-\ on the same command line.
+.nem
+.section Contents of a system filter
+The language used to specify system filters is the same as for users' filter
+files. It is described in the separate end-user document \*Exim's interface to
+mail filtering*\. 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 \-bf-\,
+they cause errors.
-.section Exim on the intermittently connected client host
-The value of \smtp@_accept@_queue@_per@_connection\ 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.
+.index frozen messages||manual thaw, testing in filter
+There are two special conditions which, though available in users' filter
+files, are designed for use in system filters. The condition \first@_delivery\
+is true only for the first attempt at delivering a message, and
+\manually@_thawed\ 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 \auto__thaw\ setting does not.
-.index SMTP||passed connection
-.index SMTP||multiple deliveries
-.index multiple SMTP deliveries
-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
-\-qq-\ instead of \-q-\. 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.
+\**Warning**\: If a system filter uses the \first@_delivery\ condition to
+specify an `unseen' (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.
+When a system filter finishes running, the values of the variables \$n0$\ --
+\$n9$\ are copied into \$sn0$\ -- \$sn9$\ and are thereby made available to
+users' filter files. Thus a system filter can, for example, set up `scores' to
+which users' filter files can refer.
+.section Additional variable for system filters
+The expansion variable \$recipients$\, 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.
-.
-.
-.
-.
-. ============================================================================
-.chapter SMTP processing
-.set runningfoot "smtp processing"
-.rset CHAPSMTP ~~chapter
-.index SMTP||processing details
-.index LMTP||processing details
-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:
-.numberpars $.
-SMTP over TCP/IP (Exim daemon or \*inetd*\);
-.nextp
-SMTP over the standard input and output (the \-bs-\ option);
-.nextp
-Batched SMTP on the standard input (the \-bS-\ option).
-.endp
-For mail delivery, the following are available:
-.numberpars $.
-SMTP over TCP/IP (the \%smtp%\ transport);
-.nextp
-LMTP over TCP/IP (the \%smtp%\ transport with the \protocol\ option set to
-`lmtp');
-.nextp
-LMTP over a pipe to a process running in the local host (the \%lmtp%\
-transport);
-.nextp
-Batched SMTP to a file or pipe (the \%appendfile%\ and \%pipe%\ transports with
-the \use@_bsmtp\ option set).
-.endp
-\*Batched SMTP*\ 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.
+.section Defer, freeze, and fail commands for system filters
+.index freezing messages
+.index message||freezing
+.index message||forced failure
+.index \fail\||in system filter
+.index \freeze\ in system filter
+.index \defer\ in system filter
+There are three extra commands (\defer\, \freeze\ and \fail\) which are always
+available in system filters, but are not normally enabled in users' filters.
+(See the \allow@_defer\,
+\allow@_freeze\ and \allow@_fail\ options for the \%redirect%\ router.) These
+commands can optionally be followed by the word \text\ and a string containing
+an error message, for example:
+.display asis
+fail text "this message looks like spam to me"
+.endd
+The keyword \text\ is optional if the next character is a double quote.
+The \defer\ command defers delivery of the original recipients of the message.
+The \fail\ command causes all the original recipients to be failed, and a
+bounce message to be created. The \freeze\ 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.
-.section Outgoing SMTP and LMTP over TCP/IP
-.rset SECToutSMTPTCP "~~chapter.~~section"
-.index SMTP||outgoing over TCP/IP
-.index outgoing SMTP over TCP/IP
+The \freeze\ 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.
+
+.index log||\fail\ command log line
+.index \fail\||log line, reducing
+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 \"@<@<"\ and contains \"@>@>"\ 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:
+.display asis
+fail "<<filter test 1>>Your message is rejected \
+ because it contains attachments that we are \
+ not prepared to receive."
+.endd
+
+.index loop||caused by \fail\
+Take great care with the \fail\ 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 \fail\ command
+again (causing a mail loop) unless steps are taken to prevent this. Testing the
+\error@_message\ condition is one way to prevent this. You could use, for
+example
+.display asis
+if $message_body contains "this is spam" and not error_message
+ then fail text "spam is not wanted here" endif
+.endd
+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.
+
+The interpretation of a system filter file ceases after a
+\defer\,
+\freeze\, or \fail\ 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
+.display asis
+mail ...
+freeze
+.endd
+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.
+
+
+.section Adding and removing headers in a system filter
+.rset SECTaddremheasys "~~chapter.~~section"
+.index header lines||adding, in system filter
+.index header lines||removing, in system filter
+.index filter||header lines, adding/removing
+Two filter commands that are available only in system filters are:
+.display
+headers add <<string>>
+headers remove <<string>>
+.endd
+The argument for the \headers add\ 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.
+
+You can use `@\n' within the string, followed by white space, to specify
+continued header lines. More than one header may be added in one command by
+including `@\n' within the string without any following white space. For
+example:
+.display asis
+headers add "X-header-1: ....\n \
+ continuation of X-header-1 ...\n\
+ X-header-2: ...."
+.endd
+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.
+
+The argument for \headers remove\ 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 ::Envelope-To:: and
+::Return-Path::) cannot be removed by this means. If there is more than one
+header with the same name, they are all removed.
+
+.em
+The \headers\ 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.
+
+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 ~~SECTheadersaddrem).
+
+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 `deleted' so that they are not transported with the
+message. For this reason, it is usual to make the \headers\ command conditional
+on \first@_delivery\ so that the set of header lines is not modified more than
+once.
+
+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:
+.display asis
+headers add "Old-Subject: $h_subject:"
+headers remove "Subject"
+headers add "Subject: new subject (was: $h_old-subject:)"
+headers remove "Old-Subject"
+.endd
+.nem
+
+
+
+.section Setting an errors address in a system filter
+.index envelope sender
+In a system filter, if a \deliver\ command is followed by
+.display
+errors@_to <<some address>>
+.endd
+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
+.display asis
+unseen deliver monitor@spying.example errors_to root@local.example
+.endd
+to take a copy which would not be sent back to the normal error reporting
+address if its delivery failed.
+
+
+.section Per-address filtering
+.rset SECTperaddfil "~~chapter.~~section"
+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 \$local@_part$\ and \$domain$\ 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:
+.display asis
+central_filter:
+.newline
+ check_local_user
+.newline
+ driver = redirect
+ domains = +local_domains
+ file = /central/filters/$local_part
+ no_verify
+ allow_filter
+ allow_freeze
+.endd
+The filter is run in a separate process under its own uid. Therefore, either
+\check@_local@_user\ must be set (as above), in which case the filter is run as
+the local user, or the \user\ option must be used to specify which user to use.
+If both are set, \user\ overrides.
+
+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.
+
+
+
+
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter Message processing
+.set runningfoot "message processing"
+.rset CHAPmsgproc "~~chapter"
+.index message||general processing
+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.
+
+Some of the automatic processing takes place by default only for
+`locally-originated' 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 `local SMTP' case that is set up
+by the \-bs-\ command line option.
+
+\**Note**\: 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.
+.em
+If you want the loopback interface to be treated specially, you must ensure
+that there are appropriate entries in your ACLs.
+.nem
+
+
+.section Submission mode for non-local messages
+.rset SECTsubmodnon "~~chapter.~~section"
+.index message||submission
+.index submission mode
+.em
+Processing that happens automatically for locally-originated messages can also
+be requested for other messages. The term `submission mode' is used to describe
+this state. Submisssion mode is set by the modifier
+.display asis
+control = submission
+.endd
+in a \\MAIL\\, \\RCPT\\, or pre-data ACL for an incoming SMTP message (see
+sections ~~SECTACLmodi and ~~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:
+.display asis
+warn hosts = 127.0.0.1
+ control = submission
+.endd
+There are some options that can be used when setting submission mode. A slash
+is used to separate options. For example:
+.display asis
+control = submission/sender_retain
+.endd
+Specifying \sender@_retain\ has the effect of setting \local@_sender@_retain\
+true and \local@_from@_check\ false for the current incoming message. The first
+of these allows an existing ::Sender:: header in the message to remain, and the
+second suppresses the check to ensure that ::From:: matches the authenticated
+sender. With this setting, Exim still fixes up messages by adding ::Date:: and
+::Message-ID:: header lines if they are missing, but makes no attempt to check
+sender authenticity in header lines.
+
+A submission mode setting may also specify a domain to be used when generating
+a ::From:: or ::Sender:: header. For example:
+.display asis
+control = submission/domain=some.domain
+.endd
+The domain may be empty. How this value is used is described in sections
+~~SECTthefrohea and ~~SECTthesenhea.
+.nem
+
+
+
+.section Line endings
+.rset SECTlineendings "~~chapter.~~section"
+.index line endings
+.index carriage return
+.index linefeed
+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.
+
+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:
+.numberpars $.
+LF not preceded by CR is treated as a line ending.
+.nextp
+CR is treated as a line ending; if it is immediately followed by LF, the LF
+is ignored.
+.nextp
+The sequence `CR, dot, CR' does not terminate an incoming SMTP message,
+nor a local message in the state where a line containing only a dot is a
+terminator.
+.nextp
+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.
+.nextp
+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.
+.endp
+
+
+
+.section Unqualified addresses
+.index unqualified addresses
+.index address||qualification
+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.
+
+Exim has two options that separately control which hosts may send unqualified
+sender or receipient addresses in SMTP commands, namely
+\sender__unqualified__hosts\ and \recipient__unqualified__hosts\. In both
+cases, if an unqualified address is accepted, it is qualified by adding the
+value of \qualify__domain\ or \qualify__recipient\, as appropriate.
+.index \qualify@_domain\
+.index \qualify@_recipient\
+
+.em
+Unqualified addresses in header lines are automatically qualified for messages
+that are locally originated, unless the \-bnq-\ 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
+\sender__unqualified__hosts\ and \recipient__unqualified__hosts\,
+.nem
+
+
+.section The UUCP From line
+.index `From' line
+.index UUCP||`From' line
+.index sender||address
+.index \uucp@_from@_pattern\
+.index \uucp@_from@_sender\
+.index envelope sender
+.index Sendmail compatibility||`From' line
+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
+`From'. Examples of two common formats are:
+.display asis
+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
+.endd
+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
+\ignore@_fromline@_hosts\ or the \-bs-\ option was used for a local message and
+\ignore@_fromline@_local\ is set. The recognition is controlled by a regular
+expression that is defined by the \uucp@_from@_pattern\ option, whose default
+value matches the two common cases shown above and puts the address that
+follows `From' into \$1$\.
+
+.index numerical variables (\$1$\, \$2$\, etc)||in `From ' line handling
+When the caller of Exim for a non-SMTP message that contains a `From' line is a
+trusted user, the message's sender address is constructed by expanding the
+contents of \uucp@_sender@_address\, whose default value is `@$1'. This is then
+parsed as an RFC 2822 address. If there is no domain, the local part is
+qualified with \qualify@_domain\ unless it is the empty string. However, if the
+command line \-f-\ option is used, it overrides the `From' line.
+
+If the caller of Exim is not trusted, the `From' line is recognized, but the
+sender address is not changed. This is also the case for incoming SMTP messages
+that are permitted to contain `From' lines.
+
+Only one `From' 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 `From' line is present in an incoming
+SMTP message from a source that is not permitted to send them.
+
+
+.section Resent- header lines
+.index \Resent@-\ header lines
+RFC 2822 makes provision for sets of header lines starting with the string
+\"Resent-"\ to be added to a message when it is resent by the original
+recipient to somebody else. These headers are ::Resent-Date::, ::Resent-From::,
+::Resent-Sender::, ::Resent-To::, ::Resent-Cc::, ::Resent-Bcc:: and
+::Resent-Message-ID::. The RFC says:
+
+\*Resent fields are strictly informational. They MUST NOT be used in the normal
+processing of replies or other such automatic actions on messages.*\
+
+This leaves things a bit vague as far as other processing actions such as
+address rewriting are concerned. Exim treats \Resent@-\ header lines as
+follows:
+.numberpars $.
+A ::Resent-From:: line that just contains the login id of the submitting user
+is automatically rewritten in the same way as ::From:: (see below).
+.nextp
+If there's a rewriting rule for a particular header line, it is also applied to
+\Resent@-\ header lines of the same type. For example, a rule that rewrites
+::From:: also rewrites ::Resent-From::.
+.nextp
+For local messages, if ::Sender:: is removed on input, ::Resent-Sender:: is also
+removed.
+.nextp
+For a locally-submitted message,
+if there are any \Resent@-\ header lines but no ::Resent-Date::,
+::Resent-From::, or ::Resent-Message-Id::, they are added as necessary. It is
+the contents of ::Resent-Message-Id:: (rather than ::Message-Id::) which are
+included in log lines in this case.
+.nextp
+The logic for adding ::Sender:: is duplicated for ::Resent-Sender:: when any
+\Resent@-\ header lines are present.
+.endp
+
+
+.section The Auto-Submitted: header line
+Whenever Exim generates a bounce or a delay warning message, it includes the
+header line
+.display asis
+Auto-Submitted: auto-generated
+.endd
+
+
+.section The Bcc: header line
+.index ::Bcc:: header line
+If Exim is called with the \-t-\ option, to take recipient addresses from a
+message's header, it removes any ::Bcc:: header line that may exist (after
+extracting its addresses). If \-t-\ is not present on the command line, any
+existing ::Bcc:: is not removed.
+
+.section The Date: header line
+.index ::Date:: header line
+If a locally-generated
+or submission-mode
+message has no ::Date:: header line, Exim adds one, using the current date and
+time.
+
+.section The Delivery-date: header line
+.index ::Delivery-date:: header line
+.index \delivery@_date@_remove\
+::Delivery-date:: 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 \delivery@_date@_add\ transport option.) They should not be present
+in messages in transit. If the \delivery@_date@_remove\ configuration option is
+set (the default), Exim removes ::Delivery-date:: header lines from incoming
+messages.
+
+.section The Envelope-to: header line
+.index ::Envelope-to:: header line
+.index \envelope@_to@_remove\
+::Envelope-to:: 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 \envelope@_to@_add\ transport option.) They should not be present in
+messages in transit. If the \envelope@_to@_remove\ configuration option is set
+(the default), Exim removes ::Envelope-to:: header lines from incoming
+messages.
+
+.section The From: header line
+.rset SECTthefrohea "~~chapter.~~section"
+.index ::From:: header line
+.index Sendmail compatibility||`From' line
+.index message||submission
+.index submission mode
+If a submission-mode message does not contain a ::From:: header line, Exim adds
+one if either of the following conditions is true:
+.numberpars $.
+The envelope sender address is not empty (that is, this is not a bounce
+message). The added header line copies the envelope sender address.
+.nextp
+The SMTP session is authenticated and \$authenticated@_id$\ is not empty.
+.em
+.numberpars alpha
+If no domain is specified by the submission control, the local part is
+\$authenticated@_id$\ and the domain is \$qualify@_domain$\.
+.nextp
+If a non-empty domain is specified by the submission control, the local part is
+\$authenticated@_id$\, and the the domain is the specified domain.
+.nextp
+If an empty domain is specified by the submission control,
+\$authenticated@_id$\ is assumed to be the complete address.
+.endp
+.nem
+.endp
+A non-empty envelope sender takes precedence.
+
+If a locally-generated incoming message does not contain a ::From:: header
+line, 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
+~~SECTconstr. They are obtained from the password data by calling
+\*getpwuid()*\ (but see the \unknown@_login\ configuration option). The address
+is qualified with \qualify@_domain\.
+
+For compatibility with Sendmail, if an incoming, non-SMTP message has a
+::From:: 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 ~~SECTconstr.
+
+.section The Message-ID: header line
+.index ::Message-ID:: header line
+.index message||submission
+If a locally-generated or submission-mode incoming message does not contain a
+::Message-ID:: or ::Resent-Message-ID:: header line, Exim adds one to the
+message. If there are any ::Resent-:: headers in the message, it creates
+::Resent-Message-ID::. 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
+.index \message@_id@_header@_text\
+\message@_id@_header@_text\ and/or \message__id__header__domain\ options.
+
+
+.section The Received: header line
+.index ::Received:: header line
+A ::Received:: header line is added at the start of every message. The contents
+are defined by the \received@_header@_text\ configuration option, and Exim
+automatically adds a semicolon and a timestamp to the configured string.
+
+The ::Received:: header is generated as soon as the message's header lines have
+been received. At this stage, the timestamp in the ::Received:: 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 \*local@_scan()*\ function.
+
+Once a message is accepted, the timestamp in the ::Received:: 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.
+
+
+.section The Return-path: header line
+.index ::Return-path:: header line
+.index \return@_path@_remove\
+::Return-path:: header lines are defined as something an MTA may insert when
+it does the final delivery of messages. (See the generic \return@_path@_add\
+transport option.) Therefore, they should not be present in messages in
+transit. If the \return@_path@_remove\ configuration option is set (the
+default), Exim removes ::Return-path:: header lines from incoming messages.
+
+
+.section The Sender: header line
+.rset SECTthesenhea "~~chapter.~~section"
+.index ::Sender:: header line
+.index message||submission
+For a locally-originated message from an untrusted user, Exim may remove an
+existing ::Sender:: header line, and it may add a new one. You can modify these
+actions by setting \local@_sender@_retain\ true or \local@_from@_check\ false.
+
+When a local message is received from an untrusted user and
+\local@_from@_check\ is true (the default), a check is made to see if the
+address given in the ::From:: 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 \qualify@_domain\ as the domain. Prefixes and suffixes for the
+local part can be permitted by setting \local@_from@_prefix\ and
+\local@_from@_suffix\ appropriately. If ::From:: does not contain the correct
+sender, a ::Sender:: line is added to the message.
+
+If you set \local@_from@_check\ false, this checking does not occur. However,
+the removal of an existing ::Sender:: line still happens, unless you also set
+\local@_sender@_retain\ to be true. It is not possible to set both of these
+options true at the same time.
+
+.em
+.index submission mode
+By default, no processing of ::Sender:: 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 \sender@_retain\ is
+not specified on the submission control, the following processing takes place:
+
+First, any existing ::Sender:: lines are removed. Then, if the SMTP session is
+authenticated, and \$authenticated@_id$\ is not empty, a sender address is
+created as follows:
+.numberpars $.
+If no domain is specified by the submission control, the local part is
+\$authenticated@_id$\ and the domain is \$qualify@_domain$\.
+.nextp
+If a non-empty domain is specified by the submission control, the local part is
+\$authenticated@_id$\, and the the domain is the specified domain.
+.nextp
+If an empty domain is specified by the submission control,
+\$authenticated@_id$\ is assumed to be the complete address.
+.endp
+This address is compared with the address in the ::From:: header line. If they
+are different, a ::Sender:: header line containing the created address is
+added. Prefixes and suffixes for the local part in ::From:: can be permitted by
+setting \local@_from@_prefix\ and \local@_from@_suffix\ appropriately.
+.nem
+
+
+.section Adding and removing header lines in routers and transports
+.index header lines||adding, in router or transport
+.index header lines||removing, in router or transport
+.rset SECTheadersaddrem "~~chapter.~~section"
+.em
+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 ~~SECTaddremheasys contains details about
+modifying headers in a system filter.
+
+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.
+
+For both routers and transports, the result of expanding a \headers@_add\
+option must be in the form of one or more RFC 2822 header lines, separated by
+newlines (coded as `@\n'). For example:
+.display asis
+headers_add = X-added-header: added by $primary_hostname\n\
+ X-added-second: another added header line
+.endd
+Exim does not check the syntax of these added header lines.
+
+The result of expanding \headers@_remove\ 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:
+.display asis
+headers_remove = return-receipt-to:acknowledge-to
+.endd
+
+When \headers@_add\ or \headers@_remove\ is specified on a router, its value is
+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.
+.index \unseen\ option
+However, this does not apply to multiple routers that result from the use of
+the \unseen\ option. Any header modifications that were specified by the
+`unseen' router or its predecessors apply only to the `unseen' delivery.
+
+Addresses that end up with different \headers@_add\ or \headers@_remove\
+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.
+
+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 \headers@_remove\ options in routers, and it also
+consults the transport's own \headers@_remove\ 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.
+
+After the remaining original header lines have been written, new header
+lines that were specified by routers' \headers@_add\ 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 \headers@_add\ option.
+
+This way of handling header line modifications in routers and transports has
+the following consequences:
+.numberpars $.
+The original set of header lines, possibly modified by the system filter,
+remains `visible', in the sense that the \$header@_$\\*xxx*\ variables refer to
+it, at all times.
+.nextp
+Header lines that are added by a router's
+\headers@_add\ option are not accessible by means of the \$header@_$\\*xxx*\
+expansion syntax in subsequent routers or the transport.
+.nextp
+Conversely, header lines that are specified for removal by \headers@_remove\ in
+a router remain visible to subsequent routers and the transport.
+.nextp
+Headers added to an address by \headers@_add\ in a router cannot be removed by
+a later router or by a transport.
+.nextp
+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:
+.display asis
+headers_remove = subject
+headers_add = Subject: new subject (was: $h_subject:)
+.endd
+.endp
+
+\**Warning**\: The \headers@_add\ and \headers@_remove\ options cannot be used
+for a \%redirect%\ router that has the \one@_time\ option set.
+.nem
+
+
+
+.section Constructed addresses
+.rset SECTconstr "~~chapter.~~section"
+.index address||constructed
+.index constructed address
+When Exim constructs a sender address for a locally-generated message, it uses
+the form
+.display
+<<user name>> <$$<<login>>@@<<qualify@_domain>>$$>
+.endd
+For example:
+.display asis
+Zaphod Beeblebrox <zaphod@end.univ.example>
+.endd
+The user name is obtained from the \-F-\ command line option if set, or
+otherwise by looking up the calling user by \*getpwuid()*\ and extracting the
+`gecos' field from the password entry. If the `gecos' 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
+\gecos@_name\ option for a way to tailor the handling of the `gecos' field. The
+\unknown@_username\ option can be used to specify user names in cases when
+there is no password file entry.
+
+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 \headers@_charset\ option specifies the name of the encoding
+that is used (the characters are assumed to be in this encoding).
+The setting of \print@_topbitchars\ controls whether characters with the top
+bit set (that is, with codes greater than 127) count as printing characters or
+not.
+
+
+.section Case of local parts
+.index case of local parts
+.index local part||case of
+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 \caseful@_local@_part\ generic
+router option.
+
+.index mixed-case login names
+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:
+.display asis
+correct_case:
+ driver = redirect
+ domains = +local_domains
+ data = ${lookup{$local_part}cdb\
+ {/etc/usercased.cdb}{$value}fail}\
+ @$domain
+.endd
+For this router, the local part is forced to lower case by the default action
+(\caseful@_local@_part\ 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 \caseful@_local@_part\
+on any subsequent routers which process your domains, they will operate on
+local parts with the correct case in a case-sensitive manner.
+
+
+.section Dots in local parts
+.index dot||in local part
+.index local part||dots in
+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.
+
+
+.section Rewriting addresses
+.index rewriting||addresses
+Rewriting of sender and recipient addresses, and addresses in headers, can
+happen automatically, or as the result of configuration options, as described
+in chapter ~~CHAPrewrite. The headers that may be affected by this are ::Bcc::,
+::Cc::, ::From::, ::Reply-To::, ::Sender::, and ::To::.
+
+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
+.display asis
+To: hare@teaparty
+.endd
+might get rewritten as
+.display asis
+To: hare@teaparty.wonderland.fict.example
+.endd
+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.
+
+Strictly, one should not do $it{any} 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.
+
+
+.
+.
+.
+.
+. ============================================================================
+.chapter SMTP processing
+.set runningfoot "smtp processing"
+.rset CHAPSMTP ~~chapter
+.index SMTP||processing details
+.index LMTP||processing details
+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:
+.numberpars $.
+SMTP over TCP/IP (Exim daemon or \*inetd*\);
+.nextp
+SMTP over the standard input and output (the \-bs-\ option);
+.nextp
+Batched SMTP on the standard input (the \-bS-\ option).
+.endp
+For mail delivery, the following are available:
+.numberpars $.
+SMTP over TCP/IP (the \%smtp%\ transport);
+.nextp
+LMTP over TCP/IP (the \%smtp%\ transport with the \protocol\ option set to
+`lmtp');
+.nextp
+LMTP over a pipe to a process running in the local host (the \%lmtp%\
+transport);
+.nextp
+Batched SMTP to a file or pipe (the \%appendfile%\ and \%pipe%\ transports with
+the \use@_bsmtp\ option set).
+.endp
+\*Batched SMTP*\ 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.
+
+
+.section Outgoing SMTP and LMTP over TCP/IP
+.rset SECToutSMTPTCP "~~chapter.~~section"
+.index SMTP||outgoing over TCP/IP
+.index outgoing SMTP over TCP/IP
.index LMTP||over TCP/IP
.index outgoing LMTP over TCP/IP
.index \\EHLO\\
.section Syntax and protocol errors in SMTP commands
.index SMTP||syntax errors
.index SMTP||protocol errors
-A syntax error is detected if an SMTP command is recognized, but there is
+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
-\smtp@_max@_synprot@_errors\ such commands during a single SMTP connection, it
-drops the connection after sending the error response to the last command. The
-default value for \smtp__max__synprot__errors\ is 3. This is a defence against
+sequencing such as \\RCPT\\ before \\MAIL\\. If Exim receives more than
+\smtp@_max@_synprot@_errors\ such commands during a single SMTP connection, it
+drops the connection after sending the error response to the last command. The
+default value for \smtp__max__synprot__errors\ is 3. This is a defence against
broken clients that loop sending bad commands (yes, it has been seen).
You can control which hosts are subject to the limit set by
\smtp@_accept@_max@_nonmail\ by setting
-\smtp@_accept@_max@_nonmail@_hosts\. The default value is \"$*$"\, which makes
+\smtp@_accept@_max@_nonmail@_hosts\. The default value is \"$*$"\, 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.
-
.
.
.
.
. ============================================================================
-.chapter Message processing
-.set runningfoot "message processing"
-.rset CHAPmsgproc "~~chapter"
-.index message||general processing
-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.
-
-Some of the automatic processing takes place
-.em
-by default
-.nem
-only for `locally-originated' 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 `local SMTP' case
-that is set up by the \-bs-\ command line option. \**Note**\: 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.
-
-.em
-.index message||submission
-Processing that happens automatically for locally-originated messages can also
-be requested for other messages. This is done by obeying the modifier
-.display asis
-control = submission
-.endd
-in one of the ACLs that are run for an incoming message (see section
-~~SECTACLmodi). 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). In the descriptions below, the term
-`submission mode' is used to describe this state.
+.chapter Customizing bounce and warning messages
+.set runningfoot "customizing messages"
+.rset CHAPemsgcust "~~chapter"
+When a message fails to be delivered, or remains on 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.
-When a ::From:: or ::Sender:: header is generated in submission mode, the value
-of \qualify@_domain\ is used by default. However, it is possible to specify
-another domain by a setting such as
+The ::From:: and ::To:: header lines are automatically generated; you can cause
+a ::Reply-To:: line to be added by setting the \errors@_reply@_to\ option. Exim
+also adds the line
.display asis
-control = submission/domain=some.other.domain
+Auto-Submitted: auto-generated
.endd
-.nem
+to all warning and bounce messages,
+.section Customizing bounce messages
+.index customizing||bounce message
+.index bounce message||customizing
+If \bounce@_message@_text\ is set, its contents are included in the default
+message immediately after `This message was created automatically by mail
+delivery software.' The string is not expanded. It is not used if
+\bounce@_message@_file\ is set.
+When \bounce@_message@_file\ 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.
-.section Line endings
-.rset SECTlineendings "~~chapter.~~section"
-.index line endings
-.index carriage return
-.index linefeed
-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.
+Each item of text that is read from the file is expanded, and there are two
+expansion variables which can be of use here: \$bounce@_recipient$\ is set to
+the recipient of an error message while it is being created, and
+\$return@_size@_limit$\ contains the value of the \return@_size@_limit\ option,
+rounded to a whole number.
-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:
+The items must appear in the file in the following order:
.numberpars $.
-LF not preceded by CR is treated as a line ending.
+The first item is included in the headers, and should include at least a
+::Subject:: header. Exim does not check the syntax of these headers.
.nextp
-CR is treated as a line ending; if it is immediately followed by LF, the LF
-is ignored.
+The second item forms the start of the error message. After it, Exim lists the
+failing addresses with their error messages.
.nextp
-The sequence `CR, dot, CR' does not terminate an incoming SMTP message,
-nor a local message in the state where a line containing only a dot is a
-terminator.
+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.
.nextp
-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.
+The fourth item is used to introduce the copy of the message that is returned
+as part of the error report.
.nextp
-.em
-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.
-.nem
+The fifth item is added after the fourth one if the returned message is
+truncated because it is bigger than \return@_size@_limit\.
+.nextp
+The sixth item is added after the copy of the original message.
.endp
+The default state (\bounce@_message@_file\ unset) is equivalent to the
+following file, in which the sixth item is empty. The ::Subject:: line has been
+split into two here in order to fit it on the page:
+.if ~~sys.fancy
+.display flow asis
+.fontgroup 0
+.font 54
+.else
+.rule
+.display flow asis
+.linelength 80em
+.indent 0
+.fi
+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.
+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
+------ $return_size_limit or so are included here.
+****
+.endd
+.if !~~sys.fancy
+.rule
+.fi
+
+.section Customizing warning messages
+.rset SECTcustwarn "~~chapter.~~section"
+.index customizing||warning message
+.index warning of delay||customizing the message
+The option
+\warn@_message@_file\
+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:
+.numberpars $.
+The first item is included in the headers, and should include at least a
+::Subject:: header. Exim does not check the syntax of these headers.
+.nextp
+The second item forms the start of the warning message. After it, Exim lists
+the delayed addresses.
+.nextp
+The third item then ends the message.
+.endp
+The default state is equivalent to the following file, except that the line
+starting `A message' has been split here, in order to fit it on the page:
+.if ~~sys.fancy
+.display asis
+.fontgroup 0
+.font 54
+.else
+.rule
+.display asis
+.linelength 80em
+.indent 0
+.fi
+.newline
+Subject: Warning: message $message_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 on the queue on $primary_hostname.
+.newline
+
+The message identifier is: $message_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.
+.endd
+.if !~~sys.fancy
+.rule
+.fi
+except that in the default state the subject and date lines are omitted if no
+appropriate headers exist. During the expansion of this file,
+\$warn@_message@_delay$\
+is set to the delay time in one of the forms `<<n>> minutes'
+or `<<n>> hours', and
+\$warn@_message@_recipients$\
+contains a list of recipients for the warning message. There may be more than
+one if there are multiple addresses with different \errors@_to\ settings on the
+routers that handled them.
-.section Unqualified addresses
-.index unqualified addresses
-.index address||qualification
-By default, Exim expects every 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.
-Exim has two options that separately control which hosts may send unqualified
-sender or receipient addresses in SMTP commands, namely
-\sender__unqualified__hosts\ and \recipient__unqualified__hosts\. In both
-cases, if an unqualified address is accepted, it is qualified by adding the
-value of \qualify__domain\ or \qualify__recipient\, as appropriate.
-.index \qualify@_domain\
-.index \qualify@_recipient\
-.section The UUCP From line
-.index `From' line
-.index UUCP||`From' line
-.index sender||address
-.index \uucp@_from@_pattern\
-.index \uucp@_from@_sender\
-.index envelope sender
-.index Sendmail compatibility||`From' line
-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
-`From'. Examples of two common formats are:
+.
+.
+.
+. ============================================================================
+.chapter Some common configuration requirements
+.set runningfoot "common configuration requirements"
+.rset CHAPcomconreq "~~chapter"
+This chapter discusses some configuration requirements that seem to be fairly
+common. More examples and discussion can be found in the Exim book.
+
+
+.section Sending mail to a smart host
+.index smart host||example router
+If you want to send all mail for non-local domains to a `smart host', you
+should replace the default \%dnslookup%\ router with a router which does the
+routing explicitly:
.display asis
-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
+send_to_smart_host:
+ driver = manualroute
+ route_list = !+local_domains smart.host.name
+ transport = remote_smtp
.endd
-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
-\ignore@_fromline@_hosts\ or the \-bs-\ option was used for a local message and
-\ignore@_fromline@_local\ is set. The recognition is controlled by a regular
-expression that is defined by the \uucp@_from@_pattern\ option, whose default
-value matches the two common cases shown above and puts the address that
-follows `From' into \$1$\.
+You can use the smart host's IP address instead of the name if you wish.
+.em
+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 \mua@_wrapper\ option (see chapter
+~~CHAPnonqueueing).
+.nem
-.index numerical variables (\$1$\, \$2$\, etc)||in `From ' line handling
-When the caller of Exim for a non-SMTP message that contains a `From' line is a
-trusted user, the message's sender address is constructed by expanding the
-contents of \uucp@_sender@_address\, whose default value is `@$1'. This is then
-parsed as an RFC 2822 address. If there is no domain, the local part is
-qualified with \qualify@_domain\ unless it is the empty string. However, if the
-command line \-f-\ option is used, it overrides the `From' line.
-If the caller of Exim is not trusted, the `From' line is recognized, but the
-sender address is not changed. This is also the case for incoming SMTP messages
-that are permitted to contain `From' lines.
+.section Using Exim to handle mailing lists
+.rset SECTmailinglists "~~chapter.~~section"
+.index mailing lists
+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.
-Only one `From' 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 `From' line is present in an incoming
-SMTP message from a source that is not permitted to send them.
+The \%redirect%\ 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 \domains\ router option can be used to run these
+lists in a separate domain from normal mail. For example:
+.display asis
+lists:
+ driver = redirect
+ domains = lists.example
+ file = /usr/lists/$local_part
+ forbid_pipe
+ forbid_file
+ errors_to = $local_part-request@lists.example
+ no_more
+.endd
+This router is skipped for domains other than \*lists.example*\. 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 \no@_more\ is set, no subsequent
+routers are tried, and so the whole delivery fails.
+The \forbid@_pipe\ and \forbid@_file\ options prevent a local part from being
+expanded into a file name or a pipe delivery, which is usually inappropriate in
+a mailing list.
-.section Resent- header lines
-.index \Resent@-\ header lines
-RFC 2822 makes provision for sets of header lines starting with the string
-\"Resent-"\ to be added to a message when it is resent by the original
-recipient to somebody else. These headers are ::Resent-Date::, ::Resent-From::,
-::Resent-Sender::, ::Resent-To::, ::Resent-Cc::, ::Resent-Bcc:: and
-::Resent-Message-ID::. The RFC says:
+.index \errors@_to\
+The \errors@_to\ 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.
-\*Resent fields are strictly informational. They MUST NOT be used in the normal
-processing of replies or other such automatic actions on messages.*\
+For example, using the configuration above, mail sent to
+\*dicts@@lists.example*\ is passed on to those addresses contained in
+\(/usr/lists/dicts)\, with error reports directed to
+\*dicts-request@@lists.example*\, provided that this address can be verified.
+There could be a file called \(/usr/lists/dicts-request)\ containing
+the address(es) of this particular list's manager(s), but other approaches,
+such as setting up an earlier router (possibly using the \local@_part@_prefix\
+or \local@_part@_suffix\ options) to handle addresses of the form \owner-xxx\
+or \xxx-request\, are also possible.
-This leaves things a bit vague as far as other processing actions such as
-address rewriting are concerned. Exim treats \Resent@-\ header lines as
-follows:
-.numberpars $.
-A ::Resent-From:: line that just contains the login id of the submitting user
-is automatically rewritten in the same way as ::From:: (see below).
-.nextp
-If there's a rewriting rule for a particular header line, it is also applied to
-\Resent@-\ header lines of the same type. For example, a rule that rewrites
-::From:: also rewrites ::Resent-From::.
-.nextp
-For local messages, if ::Sender:: is removed on input, ::Resent-Sender:: is also
-removed.
-.nextp
-For a locally-submitted message,
-if there are any \Resent@-\ header lines but no ::Resent-Date::,
-::Resent-From::, or ::Resent-Message-Id::, they are added as necessary. It is
-the contents of ::Resent-Message-Id:: (rather than ::Message-Id::) which are
-included in log lines in this case.
-.nextp
-The logic for adding ::Sender:: is duplicated for ::Resent-Sender:: when any
-\Resent@-\ header lines are present.
-.endp
+.section Syntax errors in mailing lists
+.index mailing lists||syntax errors in
+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.
-.section The Auto-Submitted: header line
-Whenever Exim generates a bounce or a delay warning message, it includes the
-header line
-.display asis
-Auto-Submitted: auto-generated
-.endd
+If the \skip@_syntax@_errors\ option is set, the \%redirect%\ router just skips
+entries that fail to parse, noting the incident in the log. If in addition
+\syntax@_errors@_to\ is set to a verifiable address, a message is sent to it
+whenever a broken address is skipped. It is usually appropriate to set
+\syntax@_errors@_to\ to the same address as \errors@_to\.
-.section The Bcc: header line
-.index ::Bcc:: header line
-If Exim is called with the \-t-\ option, to take recipient addresses from a
-message's header, it removes any ::Bcc:: header line that may exist (after
-extracting its addresses). If \-t-\ is not present on the command line, any
-existing ::Bcc:: is not removed.
+.section Re-expansion of mailing lists
+.index mailing lists||re-expansion of
+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.
-.section The Date: header line
-.index ::Date:: header line
-If a locally-generated
-.em
-or submission-mode
-.nem
-message has no ::Date:: header line, Exim adds one, using the current date and
-time.
+If this behaviour is felt to be undesirable, the \one@_time\ option can be set
+on the \%redirect%\ 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
+`top level' addresses, and the parent address that generated them is marked
+`delivered'. 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.
-.section The Delivery-date: header line
-.index ::Delivery-date:: header line
-.index \delivery@_date@_remove\
-::Delivery-date:: 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 \delivery@_date@_add\ transport option.) They should not be present
-in messages in transit. If the \delivery@_date@_remove\ configuration option is
-set (the default), Exim removes ::Delivery-date:: header lines from incoming
-messages.
+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
+\all@_parents\ selector is set, but for mailing lists there is normally only
+one level of expansion anyway.
-.section The Envelope-to: header line
-.index ::Envelope-to:: header line
-.index \envelope@_to@_remove\
-::Envelope-to:: 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 \envelope@_to@_add\ transport option.) They should not be present in
-messages in transit. If the \envelope@_to@_remove\ configuration option is set
-(the default), Exim removes ::Envelope-to:: header lines from incoming
-messages.
-.section The From: header line
-.index ::From:: header line
-.index Sendmail compatibility||`From' line
-.em
-If a submission-mode message does not contain a ::From:: header line, Exim adds
-one if either of the following conditions is true:
-.numberpars alpha
-The envelope sender address is not empty (that is, this is not a bounce
-message); the added header line copies the envelope sender address.
-.nextp
-The SMTP session is authenticated and \$authenticated@_id$\ is not empty; the
-added header's local part is \$authenticated@_id$\ and the domain is
-the domain specified on the submission control, or \$qualify@_domain$\ if that
-is not set.
-.endp
-A non-empty envelope sender takes precedence.
-.nem
+.section Closed mailing lists
+.index mailing lists||closed
+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
+\senders\ option to restrict the router that handles the list.
-If a locally-generated incoming message does not contain a ::From:: header
-line, 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
-~~SECTconstr. They are obtained from the password data by calling
-\*getpwuid()*\ (but see the \unknown@_login\ configuration option). The address
-is qualified with \qualify@_domain\.
+The following example uses the same file as a list of recipients and as a list
+of permitted senders. It requires three routers:
+.display asis
+lists_request:
+ driver = redirect
+ domains = lists.example
+ local_part_suffix = -request
+ file = /usr/lists/$local_part$local_part_suffix
+ no_more
-For compatibility with Sendmail, if an incoming, non-SMTP message has a
-::From:: 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 ~~SECTconstr.
+lists_post:
+ driver = redirect
+ domains = lists.example
+ senders = ${if exists {/usr/lists/$local_part}\
+ {lsearch;/usr/lists/$local_part}{*}}
+ file = /usr/lists/$local_part
+ forbid_pipe
+ forbid_file
+ errors_to = $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
+.endd
+All three routers have the same \domains\ setting, so for any other domains,
+they are all skipped. The first router runs only if the local part ends in
+\@-request\. It handles messages to the list manager(s) by means of an open
+mailing list.
-.section The Message-ID: header line
-.index ::Message-ID:: header line
-If a locally-generated
-.em
-or submission-mode
-.nem
-incoming message does not contain a ::Message-ID:: or ::Resent-Message-ID::
-header line, Exim adds one to the message. If there are any ::Resent-:: headers
-in the message, it creates ::Resent-Message-ID::. 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
-.index \message@_id@_header@_text\
-\message@_id@_header@_text\ and/or \message__id__header__domain\ options.
+The second router runs only if the \senders\ 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 \senders\ is $*$, which matches all senders. This
+means that the router runs, but because there is no list, declines, and
+\no@_more\ ensures that no further routers are run. The address fails with an
+`unrouteable address' error.
+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.
-.section The Received: header line
-.index ::Received:: header line
-A ::Received:: header line is added at the start of every message. The contents
-are defined by the \received@_header@_text\ configuration option, and Exim
-automatically adds a semicolon and a timestamp to the configured string.
-.em
-The ::Received:: header is generated as soon as the message's header lines have
-been received. At this stage, the timestamp in the ::Received:: 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 \*local@_scan()*\ function.
-Once a message is accepted, the timestamp in the ::Received:: 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.
-.nem
+.section Virtual domains
+.rset SECTvirtualdomains "~~chapter.~~section"
+.index virtual domains
+.index domain||virtual
+The phrase \*virtual domain*\ is unfortunately used with two rather different
+meanings:
+.numberpars $.
+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 `vanity' domains.
+.nextp
+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.
+.endp
+The first usage is probably more common, and does seem more `virtual' 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 \%dsearch%\ lookup type is useful here, leading
+to a router of this form:
+.display asis
+virtual:
+ driver = redirect
+ domains = dsearch;/etc/mail/virtual
+ data = ${lookup{$local_part}lsearch{/etc/mail/virtual/$domain}}
+ no_more
+.endd
+The \domains\ option specifies that the router is to be skipped, unless there
+is a file in the \(/etc/mail/virtual)\ directory whose name is the same as the
+domain that is being processed. When the router runs, it looks up the local
+part in the file to find a new address (or list of addresses). The \no@_more\
+setting ensures that if the lookup fails (leading to \data\ being an empty
+string), Exim gives up on the address without trying any subsequent routers.
+This one router can handle all the virtual domains because the alias file names
+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.
-.section The Return-path: header line
-.index ::Return-path:: header line
-.index \return@_path@_remove\
-::Return-path:: header lines are defined as something an MTA may insert when
-it does the final delivery of messages. (See the generic \return@_path@_add\
-transport option.) Therefore, they should not be present in messages in
-transit. If the \return@_path@_remove\ configuration option is set (the
-default), Exim removes ::Return-path:: header lines from incoming messages.
+The other kind of `virtual' 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:
+.display asis
+my_domains:
+ driver = accept
+ domains = dsearch;/etc/mail/domains
+ local_parts = lsearch;/etc/mail/domains/$domain
+ transport = my_mailboxes
+.endd
+The address is accepted if there is a file for the domain, and the local part
+can be found in the file. The \domains\ option is used to check for the file's
+existence because \domains\ is tested before the \local@_parts\ option (see
+section ~~SECTrouprecon). You can't use \require@_files\, because that option
+is tested after \local@_parts\. The transport is as follows:
+.display asis
+my_mailboxes:
+ driver = appendfile
+ file = /var/mail/$domain/$local_part
+ user = mail
+.endd
+This uses a directory of mailboxes for each domain. The \user\ setting is
+required, to specify which uid is to be used for writing to the mailboxes.
+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.
-.section The Sender: header line
-.rset SECTthesenhea "~~chapter.~~section"
-.index ::Sender:: header line
-For a locally-originated message from an untrusted user, Exim may remove an
-existing ::Sender:: header line, and it may add a new one. You can modify these
-actions by setting \local@_sender@_retain\ true or \local@_from@_check\ false.
-When a local message is received from an untrusted user and
-\local@_from@_check\ is true (the default), a check is made to see if the
-address given in the ::From:: 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 \qualify@_domain\ as the domain. Prefixes and suffixes for the
-local part can be permitted by setting \local@_from@_prefix\ and
-\local@_from@_suffix\ appropriately. If ::From:: does not contain the correct
-sender, a ::Sender:: line is added to the message.
+.section Multiple user mailboxes
+.rset SECTmulbox "~~chapter.~~section"
+.index multiple mailboxes
+.index mailbox||multiple
+.index local part||prefix
+.index local part||suffix
+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
+\local@_part@_prefix\ and \local@_part@_suffix\ can be used for this. For
+example, consider this router:
+.display asis
+userforward:
+ driver = redirect
+ check_local_user
+ file = $home/.forward
+ local_part_suffix = -*
+ local_part_suffix_optional
+ allow_filter
+.endd
+It runs a user's \(.forward)\ file for all local parts of the form
+\*username-$*$*\. Within the filter file the user can distinguish different
+cases by testing the variable \$local@_part@_suffix$\. For example:
+.display asis
+if $local_part_suffix contains -special then
+ save /home/$local_part/Mail/special
+endif
+.endd
+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
+\local@_part@_suffix\ option is made, they presumably fail. Thus, users have
+control over which suffixes are valid.
-If you set \local@_from@_check\ false, this checking does not occur. However,
-the removal of an existing ::Sender:: line still happens, unless you also set
-\local@_sender@_retain\ to be true. It is not possible to set both of these
-options true at the same time.
+Alternatively, a suffix can be used to trigger the use of a different
+\(.forward)\ file -- which is the way a similar facility is implemented in
+another MTA:
+.display asis
+userforward:
+ driver = redirect
+ check_local_user
+ file = $home/.forward$local_part_suffix
+ local_part_suffix = -*
+ local_part_suffix_optional
+ allow_filter
+.endd
+If there is no suffix, \(.forward)\ is used; if the suffix is \*-special*\, for
+example, \(.forward-special)\ 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
+\(.forward)\ file to use as a default.
-.em
-By default, no processing of ::Sender:: header lines is done for messages
-received by TCP/IP or for messages submitted by trusted users. However, when a
-message is received over TCP/IP in submission mode, ::Sender:: header lines are
-always removed. If the SMTP session is authenticated, and \$authenticated@_id$\
-is not empty, a sender address is created with \$authenticated@_id$\ as the
-local part and either the domain specified in the submission control or, if
-that is not specified, \$qualify@_domain$\ as the domain. This is compared with
-the address in the ::From:: header line. If they are different, a ::Sender::
-header line is added. Prefixes and suffixes for the local part in ::From:: can
-be permitted by setting \local@_from@_prefix\ and \local@_from@_suffix\
-appropriately.
-.nem
+.section Simplified vacation processing
+.index vacation processing
+The traditional way of running the \*vacation*\ program is for a user to set up
+a pipe command in a \(.forward)\ file
+(see section ~~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:
+.numberpars $.
+A local part prefix such as `vacation-' can be specified on a router which
+can cause the message to be delivered directly to the \*vacation*\ program, or
+alternatively can use Exim's \%autoreply%\ transport. The contents of a user's
+\(.forward)\ file are then much simpler. For example:
+.display asis
+spqr, vacation-spqr
+.endd
+.nextp
+The \require@_files\ 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 \unseen\ 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, \(.vacation)\, containing a vacation
+message.
+.endp
+Another advantage of both these methods is that they both work even when the
+use of arbitrary pipes by users is locked out.
-.section Adding and removing header lines
-.index header lines||adding
-.index header lines||removing
-.rset SECTheadersaddrem "~~chapter.~~section"
-When a message is delivered, the addition and removal of header lines can be
-specified on any of the routers and transports, and also in the system filter.
-Changes specified in the system filter affect all deliveries of a message.
-Header changes specified on a router affect all addresses handled by that
-router, and also any new addresses it generates. If an address passes through
-several routers, the changes are cumulative. When a message is processed by a
-transport, the message's original set of header lines is output, except for
-those named in any \headers@_remove\ options that the address has encountered
-as it was processed, and any in the transport's own \headers@_remove\ option.
-Then the new header lines from \headers@_add\ options are output.
+.section Taking copies of mail
+.index message||copying every
+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.
+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, $it{inter alia}, to implement automatic
+notification of delivery by sites that insist on doing such things.
-.section Constructed addresses
-.rset SECTconstr "~~chapter.~~section"
-.index address||constructed
-.index constructed address
-When Exim constructs a sender address for a locally-generated message, it uses
-the form
-.display
-<<user name>> <$$<<login>>@@<<qualify@_domain>>$$>
-.endd
-For example:
-.display asis
-Zaphod Beeblebrox <zaphod@end.univ.example>
-.endd
-The user name is obtained from the \-F-\ command line option if set, or
-otherwise by looking up the calling user by \*getpwuid()*\ and extracting the
-`gecos' field from the password entry. If the `gecos' 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
-\gecos@_name\ option for a way to tailor the handling of the `gecos' field. The
-\unknown@_username\ option can be used to specify user names in cases when
-there is no password file entry.
-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 \headers@_charset\ option specifies the name of the encoding
-that is used (the characters are assumed to be in this encoding).
-The setting of \print@_topbitchars\ controls whether characters with the top
-bit set (that is, with codes greater than 127) count as printing characters or
-not.
+.section Intermittently connected hosts
+.index intermittently connected hosts
+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.
+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.
-.section Case of local parts
-.index case of local parts
-.index local part||case of
-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 \caseful@_local@_part\ generic
-router option.
+.section Exim on the upstream server host
+It is tempting to arrange for incoming mail for the intermittently connected
+host to remain on 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.
-.index mixed-case login names
-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:
-.display asis
-correct_case:
- driver = redirect
- domains = +local_domains
- data = ${lookup{$local_part}cdb\
- {/etc/usercased.cdb}{$value}fail}\
- @$domain
-.endd
-For this router, the local part is forced to lower case by the default action
-(\caseful@_local@_part\ 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 \caseful@_local@_part\
-on any subsequent routers which process your domains, they will operate on
-local parts with the correct case in a case-sensitive manner.
+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, `mailstore', 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.
+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:
+.display
+cheshire.wonderland.fict.example * F,5d,24h
+.endd
+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 \-M-\ or \-R-\
+options, or by using the \\ETRN\\ SMTP command (see section ~~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.
-.section Dots in local parts
-.index dot||in local part
-.index local part||dots in
-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.
+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 \retry__include__ip__address\ on the \%smtp%\ transport.
+Since this has disadvantages for permanently connected hosts, it is best to
+arrange a separate transport for the intermittently connected ones.
-.section Rewriting addresses
-.index rewriting||addresses
-Rewriting of sender and recipient addresses, and addresses in headers, can
-happen automatically, or as the result of configuration options, as described
-in chapter ~~CHAPrewrite. The headers that may be affected by this are ::Bcc::,
-::Cc::, ::From::, ::Reply-To::, ::Sender::, and ::To::.
+.section Exim on the intermittently connected client host
+The value of \smtp@_accept@_queue@_per@_connection\ 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.
-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
-.display asis
-To: hare@teaparty
-.endd
-might get rewritten as
-.display asis
-To: hare@teaparty.wonderland.fict.example
-.endd
-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.
+.index SMTP||passed connection
+.index SMTP||multiple deliveries
+.index multiple SMTP deliveries
+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
+\-qq-\ instead of \-q-\. 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.
-Strictly, one should not do $it{any} 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.
+.
+.
+.
+.
+. ============================================================================
+.chapter Using Exim as a non-queueing client
+.set runningfoot "non-queueing client"
+.rset CHAPnonqueueing "~~chapter"
+.index client, non-queueing
+.index smart host||queueing, suppressing
+.em
+On a personal computer, it is a common requirement for all
+email to be sent to a `smart host'. 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
+\(/usr/sbin/sendmail)\. Furthermore, utility programs such as \*cron*\ submit
+messages this way.
+
+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.
+
+There is therefore a requirement for something that can provide the
+\(/usr/sbin/sendmail)\ 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.
+
+There are a number of applications (for example, there is one called \*ssmtp*\)
+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.
+
+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.
+
+.index \mua@_wrapper\
+There is a Boolean global option called \mua@_wrapper\, defaulting false.
+Setting \mua@_wrapper\ true causes Exim to run in a special mode where it
+assumes that it is being used to `wrap' a command-line MUA in the manner
+just described. As well as setting \mua@_wrapper\, 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.
+
+When run in MUA wrapping mode, the behaviour of Exim changes in the
+following ways:
+.numberpars alpha
+A daemon cannot be run, nor will Exim accept incoming messages from \*inetd*\.
+In other words, the only way to submit messages is via the command line.
+.nextp
+Each message is synchonously delivered as soon as it is received (\-odi-\ is
+assumed). All queueing options (\queue@_only\, \queue@_smtp@_domains\,
+\control\ 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.
+.nextp
+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.
+.nextp
+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.
+.nextp
+Because no queueing is allowed, all failures are treated as permanent; there is
+no distinction between 4\*xx*\ and 5\*xx*\ 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.
+.nextp
+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.
+.nextp
+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.
+.nextp
+No retry data is maintained, and any retry rules are ignored.
+.nextp
+A number of Exim options are overridden: \deliver@_drop@_privilege\ is forced
+true, \max@_rcpt\ in the smtp transport is forced to `unlimited',
+\remote@_max@_parallel\ is forced to one, and fallback hosts are ignored.
+.endp
+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 \*exim*\ instead of setuid
+to \*root*\. See section ~~SECTrunexiwitpri for a general discussion about the
+advantages and disadvantages of running without root privilege.
+.nem
.nextp
.index reject log
The reject log records information from messages that are rejected as a result
-of a configuration option (that is, for policy reasons).
-.em
+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
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 \write@_rejectlog\ false.
-.nem
.nextp
.index panic log
.index system log
.display asis
2001-09-16 16:09:47 SMTP connection from [127.0.0.1] closed by QUIT
.endd
-By default, the timestamps are in the local timezone. There are two
+By default, the timestamps are in the local timezone. There are two
ways of changing this:
.numberpars $.
You can set the \timezone\ option to a different time zone; in particular, if
.endd
the timestamps will be in UTC (aka GMT).
.nextp
-If you set \log@_timezone\ true, the time zone is added to the timestamp, for
+If you set \log@_timezone\ true, the time zone is added to the timestamp, for
example:
.display asis
2003-04-25 11:17:07 +0100 Start queue run: pid=12762
.display asis
log_file_path = $spool_directory/log/%slog
.endd
-If you do not specify anything at build time or run time, that is where the
+If you do not specify anything at build time or run time, that is where the
logs are written.
A log file path may also contain \"%D"\ if datestamped log file names are in
`facility' is set to \\LOG@_MAIL\\, and the program name to `exim'
by default, but you can change these by setting the \syslog@_facility\ and
\syslog@_processname\ options, respectively. If Exim was compiled with
-\\SYSLOG@_LOG@_PID\\ set in \(Local/Makefile)\ (this is the default in
+\\SYSLOG@_LOG@_PID\\ set in \(Local/Makefile)\ (this is the default in
\(src/EDITME)\), then, on systems that permit it (all except ULTRIX), the
\\LOG@_PID\\ flag is set so that the \*syslog()*\ call adds the pid as well as
the time and host name to each line.
.nextp
\*paniclog*\ is mapped to \\LOG@_ALERT\\
.endp
-Many log lines are written to both \*mainlog*\ and \*rejectlog*\, and some are
+Many log lines are written to both \*mainlog*\ and \*rejectlog*\, and some are
written to both \*mainlog*\ and \*paniclog*\, so there will be duplicates if
-these are routed by syslog to the same place. You can suppress this duplication
+these are routed by syslog to the same place. You can suppress this duplication
by setting \syslog@_duplication\ false.
Exim's log lines can sometimes be very long, and some of its \*rejectlog*\
entries contain multiple lines when headers are included. To cope with both
these cases, entries written to syslog are split into separate \*syslog()*\
-calls at each internal newline, and also after a maximum of
+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
.display asis
SYSLOG_LONG_LINES=yes
.endd
-in \(Local/Makefile)\ before building Exim. That stops Exim from splitting long
+in \(Local/Makefile)\ before building Exim. That stops Exim from splitting long
lines, but it still splits at internal newlines in \*reject*\ log entries.
To make it easy to re-assemble split lines later, each component of a split
.index authentication||logging
.index \\AUTH\\||logging
For all messages, the P field specifies the protocol used to receive the
-message. This is set to `asmtp' for messages received from hosts which have
-authenticated themselves using the SMTP \\AUTH\\ command. 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
-\server@_set@_id\ option, this is logged too, separated by a colon from the
-authenticator name.
+message. This is set to
+.em
+`esmtpa'
+.nem
+for messages received from hosts that have authenticated themselves using the
+SMTP \\AUTH\\ command. 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 \server@_set@_id\ option, this is logged too,
+separated by a colon from the authenticator name.
The id field records the existing message id, if present.
.index size||of message
1995-12-19 16:20:23 0tRiQz-0002Q5-00 ** jim@trek99.example
<jim@trek99.example>: unknown mail domain
.endd
-If a delivery fails at transport time, the router and transport are shown, and
+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:
.display asis
.indent 0
2002-07-11 07:14:17 17SXDU-000189-00 ** ace400@pb.example R=dnslookup
.newline
-.em
T=remote_smtp: SMTP error from remote mailer after pipelined
.newline
-.nem
- RCPT TO:<ace400@pb.example>: host pbmail3.py.example
- [192.168.63.111]: 553 5.3.0 <ace400@pb.example>...
+ RCPT TO:<ace400@pb.example>: host pbmail3.py.example
+ [192.168.63.111]: 553 5.3.0 <ace400@pb.example>...
Addressee unknown
.endd
-.em
-The word `pipelined' indicates that the SMTP \\PIPELINING\\ extension was being
-used. See \hosts@_avoid@_esmtp\ in the \%smtp%\ transport for a way of
+The word `pipelined' indicates that the SMTP \\PIPELINING\\ extension was being
+used. See \hosts@_avoid@_esmtp\ in the \%smtp%\ transport for a way of
disabling \\PIPELINING\\.
-.nem
The log lines for all forms of delivery failure are flagged with \"**"\.
.tabs 8
A $t $rm{authenticator name (and optional id)}
C $t $rm{SMTP confirmation on delivery}
-.newline
-.em
CV $t $rm{certificate verification status}
DN $t $rm{distinguished name from peer certificate}
-DT $t $rm{time taken for a delivery}
.newline
+.em
+DT $t $rm{on \"=>"\ lines: time taken for a delivery}
.nem
+.newline
F $t $rm{sender address (on delivery lines)}
H $t $rm{host name and IP address}
-.newline
-.em
I $t $rm{local interface used}
-.newline
-.nem
id $t $rm{message id for incoming message}
P $t $rm{on \"<="\ lines: protocol used}
.newline
.em
- $t $rm{on \"=>"\ lines: return path}
-QT $t $rm{time spent on queue}
-.newline
+ $t $rm{on \"=>"\ and \"**"\ lines: return path}
+QT $t $rm{on \"=>"\ lines: time spent on queue so far}
+ $t $rm{on `Completed' lines: time spent on queue}
.nem
+.newline
R $t $rm{on \"<="\ lines: reference for local bounce}
- $t $rm{on \"=>"\ lines: router name}
+.newline
+.em
+ $t $rm{on \"=>"\ \"**"\ and \"=="\ lines: router name}
+.nem
+.newline
S $t $rm{size of message}
ST $t $rm{shadow transport name}
T $t $rm{on \"<="\ lines: message subject (topic)}
- $t $rm{on \"=>"\ lines: transport name}
+.newline
+.em
+ $t $rm{on \"=>"\ \"**"\ and \"=="\ lines: transport name}
+.nem
+.newline
U $t $rm{local user or RFC 1413 identity}
X $t $rm{TLS cipher suite}
.endd
\*exiwhat*\ utility script can be used to find out what Exim processes are
doing.
.nextp
-.em
.index error||ignored
-\*error ignored*\##There are several circumstances that give rise to this
+\*error ignored*\##There are several circumstances that give rise to this
message:
.numberpars " "
-Exim failed to deliver a bounce message whose age was greater than
+Exim failed to deliver a bounce message whose age was greater than
\ignore__bounce__errors__after\. The bounce was discarded.
.nextp
-A filter file set up a delivery using the `noerror' option, and the delivery
+A filter file set up a delivery using the `noerror' option, and the delivery
failed. The delivery was discarded.
.nextp
-A delivery set up by a router configured with
+A delivery set up by a router configured with
.display asis
errors_to = <>
.endd
failed. The delivery was discarded.
-.endp
-.nem
+.endp
.endp
all@_parents $t $rm{all parents in => lines}
arguments $t $rm{command line arguments}
*connection@_reject $t $rm{connection rejections}
-*delay@_delivery $t $rm{immediate delivery delayed (message queued)}
-.newline
-.em
+*delay@_delivery $t $rm{immediate delivery delayed}
deliver@_time $t $rm{time taken to perform delivery}
-.newline
-.nem
delivery@_size $t $rm{add S=nnn to => lines}
*dnslist@_defer $t $rm{defers of DNS list (aka RBL) lookups}
*etrn $t $rm{ETRN commands}
*host@_lookup@_failed $t $rm{as it says}
-.newline
-.em
ident@_timeout $t $rm{timeout for ident connection}
-.newline
-.nem
incoming@_interface $t $rm{incoming interface on <= lines}
incoming@_port $t $rm{incoming port on <= lines}
*lost@_incoming@_connection $t $rm{as it says (includes timeouts)}
-.newline
-.em
outgoing@_port $t $rm{add remote port to => lines}
-.newline
-.nem
*queue@_run $t $rm{start and end queue runs}
.newline
-.em
- queue@_time $t $rm{time on queue}
-.newline
+.em
+ queue@_time $t $rm{time on queue for one recipient}
+ queue@_time@_overall $t $rm{time on queue for whole message}
.nem
+.newline
received@_recipients $t $rm{recipients on <= lines}
received@_sender $t $rm{sender on <= lines}
*rejected@_header $t $rm{header contents on reject log}
*retry@_defer $t $rm{`retry time not reached'}
-.newline
-.em
return@_path@_on@_delivery $t $rm{put return path on => and ** lines}
-.newline
-.nem
sender@_on@_delivery $t $rm{add sender to => lines}
*size@_reject $t $rm{rejection because too big}
-*skip@_delivery $t $rm{`message is frozen', `spool file is locked'}
-.newline
-.em
+*skip@_delivery $t $rm{delivery skipped in a queue run}
smtp@_confirmation $t $rm{SMTP confirmation on => lines}
-.newline
-.nem
smtp@_connection $t $rm{SMTP connections}
smtp@_incomplete@_transaction $t $rm{incomplete SMTP transactions}
smtp@_protocol@_error $t $rm{SMTP protocol errors}
smtp@_syntax@_error $t $rm{SMTP syntax errors}
subject $t $rm{contents of ::Subject:: on <= lines}
-.newline
-.em
tls@_certificate@_verified $t $rm{certificate verification status}
-.newline
-.nem
*tls@_cipher $t $rm{TLS cipher suite on <= and => lines}
tls@_peerdn $t $rm{TLS peer DN on <= and => lines}
.index rewriting||logging
\address@_rewrite\: This applies both to global rewrites and per-transport
rewrites,
-.em
-but not to rewrites in filters run as an unprivileged user (because such users
+but not to rewrites in filters run as an unprivileged user (because such users
cannot access the log).
-.nem
.nextp
.index log||full parentage
\all@_parents\: Normally only the original and final addresses are logged on
preceded by the current working directory.
This is a debugging feature, added to make it easier to find out how certain
MUAs call \(/usr/sbin/sendmail)\. The logging does not happen if Exim has given
-up root privilege because it was called with the \-C-\ or \-D-\ options.
-Arguments that are empty or that contain whitespace are quoted. Non-printing
+up root privilege because it was called with the \-C-\ or \-D-\ options.
+Arguments that are empty or that contain whitespace 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
messages were received on one connection. Logging does not occur if no delivery
process is started because \queue@_only\ is set or \-odq-\ was used.
.nextp
-.em
.index log||delivery duration
\deliver@_time\: For each delivery, the amount of real time it has taken to
perform the actual delivery is logged as DT=<<time>>, for example, \"DT=1s"\.
-.nem
.nextp
.index log||message size on delivery
.index size||of message
log line is written. This logging does not apply to direct DNS lookups when
routing email addresses, but it does apply to `byname' lookups.
.nextp
-.em
.index log||ident timeout
.index RFC 1413||logging timeout
\ident@_timeout\: A log line is written whenever an attempt to connect to a
client's ident port times out.
-.nem
.nextp
.index log||incoming interface
.index interface||logging
\incoming@_interface\: The interface on which a message was received is added
to the `<=' line as an IP address in square brackets, tagged by I= and followed
by a colon and the port number.
-.em
The local interface and port are also added to other SMTP log
lines, for example `SMTP connection from', and to rejection lines.
-.nem
.nextp
.index log||incoming remote port
.index port||logging remote
\lost@_incoming@_connection\: A log line is written when an incoming SMTP
connection is unexpectedly dropped.
.nextp
-.em
.index log||outgoing remote port
.index port||logging outgoint remote
.index TCP/IP||logging ougtoing remote port
containing => tags) following the IP address. This option is not included in
the default setting, because for most ordinary configurations, the remote port
number is always 25 (the SMTP port).
-.nem
.nextp
.index log||queue run
.index queue runner||logging
\queue@_run\: The start and end of every queue run are logged.
.nextp
-.em
.index log||queue time
\queue@_time\: The amount of time the message has been in the queue on the
-local host is logged as QT=<<time>>, for example, \"QT=3m45s"\. The clock
-starts when Exim starts to receive the message, so it includes reception time
-as well as the delivery time of the current address.
+local host is logged as QT=<<time>>
+.em
+on delivery (\"=>"\) lines, for example, \"QT=3m45s"\. 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.
+.nem
+
+.nextp
+.em
+\queue@_time@_overall\: The amount of time the message has been in the queue on
+the local host is logged as QT=<<time>> on `Completed' lines, for
+example, \"QT=3m45s"\. The clock starts when Exim starts to receive the
+message, so it includes reception time as well as the total delivery time.
.nem
.nextp
.index log||recipients
attempt.
.nextp
.index log||return path
-.em
-\return@_path@_on@_delivery\: The return path that is being transmitted with
+\return@_path@_on@_delivery\: The return path that is being transmitted with
the message is included in delivery and bounce lines, using the tag P=.
+.em
+This is omitted if no delivery actually happens, for example, if routing fails,
+or if delivery is to \(/dev/null)\ or to \":blackhole:"\.
.nem
.nextp
.index log||sender on delivery
\sender@_on@_delivery\: The message's sender address is added to every delivery
and bounce line, tagged by F= (for `from').
-.em
-This is the original sender that was received with the message; it is not
+This is the original sender that was received with the message; it is not
necessarily the same as the outgoing return path.
-.nem
.nextp
.index log||size rejection
\size@_reject\: A log line is written whenever a message is rejected because it
\skip@_delivery\: 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.
+.em
+.index `spool file is locked'
+The message that is written is `spool file is locked'.
+.nem
.nextp
.index log||smtp confirmation
.index SMTP||logging confirmation
.index log||SMTP connections
.index SMTP||logging connections
\smtp@_connection\: A log line is written whenever an SMTP connection is
-established or closed. (By contrast, \lost@_incoming@_connection\ applies only
-when the closure is unexpected.) This applies to connections from local
-processes that use \-bs-\ 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 this
-selector is set or not, but otherwise nothing is written at the start and end
-of connections unless this selector is enabled.
+established or closed,
+.em
+unless the connection is from a host that matches \hosts@_connection@_nolog\.
+.nem
+(In contrast, \lost__incoming__connection\ applies only when the closure is
+unexpected.) This applies to connections from local processes that use \-bs-\
+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.
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
+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.
.nextp
.index log||SMTP transaction, incomplete
.index SMTP||logging protocol error
\smtp@_protocol@_error\: A log line is written for every SMTP protocol error
encountered.
-.em
-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
+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 `expected' errors (for example, \\RCPT\\ received
after rejecting \\MAIL\\) as protocol errors.
-.nem
.nextp
.index SMTP||logging syntax errors
.index SMTP||syntax errors, logging
.index subject, logging
\subject\: The subject of the message is added to the arrival log line,
preceded by `T=' (T for `topic', since S is already used for `size').
-Any MIME `words' in the subject are decoded. The \print@_topbitchars\ option
-specifies whether characters with values greater than 127 should be logged
+Any MIME `words' in the subject are decoded. The \print@_topbitchars\ option
+specifies whether characters with values greater than 127 should be logged
unchanged, or whether they should be rendered as escape sequences.
.nextp
.index log||certificate verification
-.em
\tls@_certificate@_verified\: An extra item is added to <= and => log lines
when TLS is in use. The item is \"CV=yes"\ if the peer's certificate was
verified, and \"CV=no"\ if not.
-.nem
.nextp
.index log||TLS cipher
.index TLS||logging cipher
.section Message log
.index message||log file for
-.index log||message log, description of
+.index log||message log, description of
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
.index \(msglog)\ directory
unless \preserve__message__logs\ is set, but this should be used only with
great care because they can fill up your disk very quickly.
-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
+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
\message@_logs\ option false.
.display rm
.tabs 22
~~SECTfinoutwha \*exiwhat*\ $t $rm{list what Exim processes are doing}
-.newline
~~SECTgreptheque \*exiqgrep*\ $t $rm{grep the queue}
-.newline
~~SECTsumtheque \*exiqsumm*\ $t $rm{summarize the queue}
~~SECTextspeinf \*exigrep*\ $t $rm{search the main log}
-.newline
-.em
~~SECTexipick \*exipick*\ $t $rm{select messages on various criteria}
-.newline
-.nem
~~SECTcyclogfil \*exicyclog*\ $t $rm{cycle (rotate) log files}
~~SECTmailstat \*eximstats*\ $t $rm{extract statistics from the log}
~~SECTcheckaccess \*exim@_checkaccess*\ $t $rm{check address acceptance from given IP}
a line describing what it is doing to the file \(exim-process.info)\ in the
Exim spool directory. The \*exiwhat*\ 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 \*exiwhat*\ successfully you have to have sufficient privilege to
+second to allow the Exim processes to react before displaying the results. In
+order to run \*exiwhat*\ successfully you have to have sufficient privilege to
send the signal to the Exim processes, so it is normally run as root.
-Unfortunately, the \*ps*\ command which \*exiwhat*\ uses to find Exim processes
+.em
+\**Warning**\: 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.
+.nem
+
+Unfortunately, the \*ps*\ command that \*exiwhat*\ 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 \*exiwhat*\ works. If it
.display asis
exim -bpu
.endd
-to obtain a queue listing with undelivered recipients only, and then greps the
-output to select messages that match given criteria. The following selection
+to obtain a queue listing with undelivered recipients only, and then greps the
+output to select messages that match given criteria. The following selection
options are available:
.startoptions
.option f <<regex>>
-Match the sender address. The field that is tested is enclosed in angle
-brackets, so you can test for bounce messages with
+Match the sender address. The field that is tested is enclosed in angle
+brackets, so you can test for bounce messages with
.display asis
exiqgrep -f '^<>$'
.endd
.option r <<regex>>
-Match a recipient address. The field that is tested is not enclosed in angle
+Match a recipient address. The field that is tested is not enclosed in angle
brackets.
.option s <<regex>>
.display asis
3 2322 74m 66m msn.com.example
.endd
-Each line lists the number of
+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
+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.
A summary line is output at the end. By default the output is sorted on the
match the pattern. Thus, \*exigrep*\ can extract complete log entries for a
given message, or all mail for a given user, or for a given host, for example.
-.em
If a matching log line is not associated with a specific message, it is always
included in \*exigrep*\'s output.
-.nem
The usage is:
.display asis
exigrep [-l] [-t<n>] <pattern> [<log file>] ...
.endd
-The \-t-\ argument specifies a number of seconds. It adds an additional
-condition for message selection. Messages that are complete are shown only if
+The \-t-\ 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 <<n>> seconds on the queue.
The \-l-\ flag means `literal', that is, treat all characters in the
file whose name ends in \\COMPRESS@_SUFFIX\\ through \*zcat*\ as it searches
it.
-.em
.section Selecting messages by various criteria (exipick)
.rset SECTexipick "~~chapter.~~section"
.index \*exipick*\
.display asis
exipick --help
.endd
-.nem
.section Cycling log files (exicyclog)
.index cycling logs
.index \*exicyclog*\
The \*exicyclog*\ script can be used to cycle (rotate) \*mainlog*\ and
-\*rejectlog*\ 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
-~~SECTdatlogfil).
-Some operating systems have their own standard mechanisms for log cycling, and
-these can be used instead of \*exicyclog*\ if preferred.
-
-Each time \*exicyclog*\ is run the file names get `shuffled down' by one. If the
-main log file name is \(mainlog)\ (the default) then when \*exicyclog*\ is run
-\(mainlog)\ becomes \(mainlog.01)\, the previous \(mainlog.01)\ becomes
+\*rejectlog*\ 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
+~~SECTdatlogfil). Some operating systems have their own standard mechanisms for
+log cycling, and these can be used instead of \*exicyclog*\ if preferred.
+
+Each time \*exicyclog*\ is run the file names get `shuffled down' by one. If
+the main log file name is \(mainlog)\ (the default) then when \*exicyclog*\ is
+run \(mainlog)\ becomes \(mainlog.01)\, the previous \(mainlog.01)\ becomes
\(mainlog.02)\ and so on, up to a limit which is set in the script, and which
-defaults to 10. Reject logs are handled similarly.
+defaults to 10.
+.em
+Log files whose numbers exceed the limit are discarded.
+.nem
+Reject logs are handled similarly.
+
+.em
+If the limit is greater than 99, the script uses 3-digit numbers such as
+\(mainlog.001)\, \(mainlog.002)\, etc. If you change from a number less than 99
+to one that is greater, or \*vice versa*\, you will have to fix the names of
+any existing log files.
+.nem
If no \(mainlog)\ file exists, the script does nothing. Files that `drop off'
the end are deleted. All files with numbers greater than 01 are compressed,
.index \*eximstats*\
A Perl script called \*eximstats*\ is provided for extracting statistical
information from log files. The output is either plain text, or HTML.
-Exim log files are also suported by the \*Lire*\ system produced by the
+Exim log files are also suported by the \*Lire*\ system produced by the
LogReport Foundation (\?http://www.logreport.org?\).
The \*eximstats*\ script has been hacked about quite a bit over time. The
\-byhost-\ and/or \-bydomain-\.
.option byemaildomain
-The `league tables' are computed on the basis of the sender's email domain
+The `league tables' are computed on the basis of the sender's email domain
instead of the sending and receiving hosts. This option may be combined with
\-byhost-\, \-bydomain-\, or \-byemail-\.
.option merge
This option causes \*eximstats*\ to merge old reports into a combined report.
-When this option is used, the input files must be outputs from previous calls
+When this option is used, the input files must be outputs from previous calls
to \*eximstats*\, not raw log files. For example, you could produce a set of
daily reports and a weekly report by commands such as
.display asis
Suppress the statistics about delivery by transport.
.option nt/<<pattern>>/
-Suppress the statistics about delivery by any transport whose name matches the
-pattern. If you are using one transport to send all messages to a scanning
-mechanism before doing the real delivery, this feature can be used to omit that
+Suppress the statistics about delivery by any transport whose name matches the
+pattern. If you are using one transport to send all messages to a scanning
+mechanism before doing the real delivery, this feature can be used to omit that
transport from your normal statistics (on the grounds that it is of no
interest).
.display asis
-pattern 'Refused connections' '/refused connection/'
.endd
-This option can be specified multiple times.
+This option can be specified multiple times.
.option q0
Suppress information about times messages spend on the queue.
mandatory arguments.
Because the \exim@_checkaccess\ uses \-bh-\, it does not perform callouts while
-running its checks. You can run checks that include callouts by using \-bhc-\,
+running its checks. You can run checks that include callouts by using \-bhc-\,
but this is not yet available in a `packaged' form.
suffers a message-specific error (see section ~~SECToutSMTPerr). \*exinext*\ is
not particularly efficient, but then it isn't expected to be run very often.
-.em
The \*exinext*\ utility calls Exim to find out information such as the location
of the spool directory. The utility has \-C-\ and \-D-\ options, which are
passed on to the \*exim*\ 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.
-.nem
\*wait-*\<<transport name>>: databases of information about messages waiting
for remote hosts
.nextp
-.em
\*callout*\: the callout cache
-.nem
.nextp
-\*misc*\: other hints data
+\*misc*\: other hints data
.endp
-.em
The \*misc*\ database is used for
.numberpars alpha
Serializing \\ETRN\\ runs (when \smtp@_etrn@_serialize\ is set)
.nextp
-Serializing delivery to a specific host (when \serialize@_hosts\ is set in an
+Serializing delivery to a specific host (when \serialize@_hosts\ is set in an
\%smtp%\ transport)
.endp
-.nem
+
+.section exim@_dumpdb
.index \*exim@_dumpdb*\
The entire contents of a database are written to the standard output by the
\*exim@_dumpdb*\ program, which has no options or arguments other than the
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 \no@_retry@_include@_ip@_address\ is set on the \%smtp%\
-transport).
-.em
-If the remote port is not the standard one (port 25), it is added to the IP
-address.
-.nem
-Then there follows an error code, an additional error code, and a
-textual description of the error.
+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.
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
may be routed to several alternative hosts, and Exim makes no effort to keep
cross-references.
+
+.section exim@_tidydb
.index \*exim@_tidydb*\
The \*exim@_tidydb*\ utility program is used to tidy up the contents of the
hints databases. If run with no options, it removes all records from a database
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
\*wait-*\$it{xxx} records, and if this leaves any records empty, they are
-deleted. For the \*retry*\ database, records whose keys are non-existent message
-ids are removed. The \*exim@_tidydb*\ utility outputs comments on the standard
-output whenever it removes information from the database.
+deleted. For the \*retry*\ database, records whose keys are non-existent
+message ids are removed. The \*exim@_tidydb*\ utility outputs comments on the
+standard output whenever it removes information from the database.
-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.
-It is therefore suggested that \*exim@_tidydb*\ be run periodically on all the
-hints databases, but at a quiet time of day, because it requires a database to
-be locked (and therefore inaccessible to Exim) while it does its work.
+.em
+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.
+
+It is important, therefore, to run \*exim@_tidydb*\ 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.
+
+\**Warning**\: If you never run \*exim@_tidydb*\, the space used by the hints
+databases is likely to keep on increasing.
+.nem
+
+.section exim@_fixdb
.index \*exim@_fixdb*\
The \*exim@_fixdb*\ program is a utility for interactively modifying databases.
Its main use is for testing Exim, but it might also be occasionally useful for
Use \*fcntl()*\ locking on the open mailbox.
.option flock
-Use \*flock()*\ locking on the open mailbox, provided the operating system
+Use \*flock()*\ locking on the open mailbox, provided the operating system
supports it.
.option interval
.endoptions
-If none of \-fcntl-\,
+If none of \-fcntl-\,
\-flock-\,
\-lockfile-\ or \-mbx-\ are given, the default is to create a lock file and
also to use \*fcntl()*\ locking on the mailbox, which is the same as Exim's
-default. The use of
-\-flock-\
+default. The use of
+\-flock-\
or \-fcntl-\ requires that the file be writeable; the use of
\-lockfile-\ requires that the directory containing the file be writeable.
Locking by lock file does not last for ever; Exim assumes that a lock file is
expired if it is more than 30 minutes old.
-The \-mbx-\ option can be used with either or both of \-fcntl-\ or \-flock-\.
+The \-mbx-\ option can be used with either or both of \-fcntl-\ or \-flock-\.
It assumes \-fcntl-\ by default.
MBX locking causes a shared lock to be taken out on the open mailbox, and an
exclusive lock on the file \(/tmp/.$it{n}.$it{m})\ where $it{n} and $it{m} are
.section The log display
.index log||tail of, in monitor
The second section of the window is an area in which a display of the tail of
-the main log is maintained.
+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 \log@_timezone\ is set, the timezone.
The log tail is not available when the only destination for logging data is
the \-D-\ option is used to define macro values for the configuration, and the
calling process is not running as root or the Exim user, the uid and gid are
changed to those of the calling process.
-However, if \\ALT@_CONFIG@_ROOT@_ONLY\\ is defined in \(Local/Makefile)\, only
-root callers may use \-C-\ and \-D-\ without losing privilege, and if
+However, if \\ALT@_CONFIG@_ROOT@_ONLY\\ is defined in \(Local/Makefile)\, only
+root callers may use \-C-\ and \-D-\ without losing privilege, and if
\\DISABLE@_D@_OPTION\\ is set, the \-D-\ option may not be used at all.
.nextp
.index \-be-\ option
process or a process for testing address routing (started with \-bt-\), 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
+testing address verification
.index \-bv-\ option
.index \-bh-\ option
(the \-bv-\ option) and testing incoming message policy controls (the \-bh-\
.section Running Exim without privilege
+.rset SECTrunexiwitpri "~~chapter.~~section"
.index privilege, running without
.index unprivileged running
.index root privilege||running without
been received. Such a re-invocation is a waste of resources because it has no
effect.
-If restarting the daemon is not an issue (for example, if \*inetd*\ is being
-used instead of a daemon), having the binary setuid to the Exim user seems a
-clean approach, but there is one complication:
+If restarting the daemon is not an issue (for example, if
+.em
+\mua@_wrapper\ is set, or
+.nem
+\*inetd*\ is being used instead of a daemon), having the binary setuid to the
+Exim user seems a clean approach, but there is one complication:
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.
However, there are no restrictions on remote deliveries. If you are running a
gateway host that does no local deliveries, setting \deliver@_drop@_privilege\
gives more security at essentially no cost.
+.em
+If you are using the \mua@_wrapper\ facility (see chapter ~~CHAPnonqueueing),
+\deliver@_drop@_privilege\ is forced to be true.
+.nem
.section Delivering to local files
is insurance against disk crashes where the directory is lost but the files
themselves are recoverable.
-.em
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:
.nextp
If the message is in MIME format, you must take care not to break it.
.nextp
-If the message is cryptographically signed, any change will invalidate the
+If the message is cryptographically signed, any change will invalidate the
signature.
.endp
-.nem
Files whose names end with -J may also be seen in the \(input)\ directory (or
its subdirectories when \split@_spool@_directory\ is set). These are journal
There follow a number of lines starting with a hyphen. These can appear in any
order, and are omitted when not relevant:
.numberpars $.
-.em
-\-acl <<number>> <<length>>-\: A line of this form is present for every ACL
-variable that is not empty. The number identifies the variable; the
-\acl@_c\*x*\$$\ variables are numbered 0--9 and the \acl@_m\*x*\$$\ variables
-are numbered 10--19. The length is the length of the data string for the
+\-acl <<number>> <<length>>-\: A line of this form is present for every ACL
+variable that is not empty. The number identifies the variable; the
+\acl@_c\*x*\$$\ variables are numbered 0--9 and the \acl@_m\*x*\$$\ 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.
.nextp
-\-allow@_unqualified@_recipient-\: 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 \-bnq-\ and remote messages from hosts that match
+.em
+\-active@_hostname <<hostname>>-\: This is present if, when the message was
+received over SMTP, the value of \$smtp@_active@_hostname$\ was different to
+the value of \$primary@_hostname$\.
+.nem
+.nextp
+\-allow@_unqualified@_recipient-\: 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 \-bnq-\ and remote messages from hosts that match
\recipient@_unqualified@_hosts\ set this flag.
.nextp
-\-allow@_unqualified@_sender-\: 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 \-bnq-\ and remote messages from hosts that match
+\-allow@_unqualified@_sender-\: 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 \-bnq-\ and remote messages from hosts that match
\sender@_unqualified@_hosts\ set this flag.
-.nem
.nextp
\-auth@_id <<text>>-\: The id information for a message received on an
authenticated SMTP connection -- the value of the \$authenticated@_id$\
\-body@_linecount <<number>>-\: This records the number of lines in the body of
the message, and is always present.
.nextp
+.em
+\-body@_zerocount <<number>>-\: This records the number of binary zero bytes in
+the body of the message, and is present if the number is greater than zero.
+.nem
+.nextp
\-deliver@_firsttime-\: 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.
.nextp
untrusted local caller (used to ensure that the caller is displayed in queue
listings).
.nextp
-\-tls@_certificate@_verified-\: A TLS certificate was received from the client
+.em
+\-spam@_score@_int-\: If a message was scanned by SpamAssassin, this is
+present. It records the value of \$spam@_score@_int$\.
+.nem
+.nextp
+\-tls@_certificate@_verified-\: A TLS certificate was received from the client
that sent this message, and the certificate was verified by the server.
.nextp
\-tls@_cipher <<cipher name>>-\: When the message was received over an