diff options
Diffstat (limited to 'doc/doc-src')
-rw-r--r-- | doc/doc-src/FAQ.src | 7015 | ||||
-rw-r--r-- | doc/doc-src/filter.src | 1644 | ||||
-rw-r--r-- | doc/doc-src/markup.sg | 86 | ||||
-rw-r--r-- | doc/doc-src/spec.src | 27935 |
4 files changed, 36680 insertions, 0 deletions
diff --git a/doc/doc-src/FAQ.src b/doc/doc-src/FAQ.src new file mode 100644 index 000000000..9ad5cf94d --- /dev/null +++ b/doc/doc-src/FAQ.src @@ -0,0 +1,7015 @@ +## $Cambridge: exim/doc/doc-src/FAQ.src,v 1.1 2004/10/07 15:04:35 ph10 Exp $ +## +## This file is processed by Perl scripts to produce an ASCII and an HTML +## version. Lines starting with ## are omitted. The markup used with paragraphs +## is as follows: +## +## Markup User for HTML Text +## ------------------------------------------------------ +## \...\ option fixed-pitch "quoted" +## \$...$\ variable $italic $plain +## \*...*\ titles, quotes italic "quoted" +## \(...)\ file name italic plain +## \[...]\ replaceable <italic> <plain> +## \?...?\ URL URL plain +## \^...^\ Unix command italic plain +## \%...%\ Exim driver bold "quoted" +## \^^.^^\ C function bold plain +## ::...:: header name italic: plain: +## //...// domain italic plain +## \/.../\ local part italic plain +## \"..."\ literal fixed-pitch "quoted" +## \\...\\ SMTP, build small caps caps +## \**...**\ warn, item bold plain +## \-...-\ cmd option -italic -plain +## \# hard space space +## +## ``...'' quoted string “...” "..." +## +## @\ is used when a real backslash is required +## +## In addition, sequences of not blank lines that start with ==> are displayed +## in fixed-pitch with no further interpretation. A line containing only [[br]] +## is removed from the text version, but turned into <br> in the HTML version. +## +## The starts of sections and of questions and answers are automatically +## detected by the scripts. +## +## +THE EXIM FAQ +------------ + +This is the FAQ for the Exim Mail Transfer Agent. Many thanks to the many +people who provided the original information. This file would be amazingly +cluttered if I tried to list them all. Suggestions for corrections, +improvements, and additions are always welcome. + +This version of the FAQ applies to Exim 4.00 and later releases. It has been +extensively revised, and material that was relevant only to earlier releases +has been removed. As this caused some whole sections to disappear, I've taken +the opportunity to re-arrange the sections and renumber everything except the +configuration samples. + +References of the form Cnnn, Fnnn, Lnnn, and Snnn are to the sample +configuration, filter, \^^local_scan()^^\, and ``useful script'' files. These +are hyperlinked from the HTML version of this FAQ. They can also be found in +the separately distributed directory called \(config.samples)\. The primary +location is + +\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/config.samples.tar.gz?\ +\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4/config.samples.tar.bz2?\ + +There are brief descriptions of these files at the end of this document. + +Philip Hazel +Last update: 31-March-2004 + + +The FAQ is divided into the following sections: + + 0. General Debugging + 1. Building and Installing + 2. Routing in general + 3. Routing to remote hosts + 4. Routing for local delivery + 5. Filtering + 6. Delivery + 7. Policy controls + 8. Rewriting addresses + 9. Headers + 10. Performance + 11. Majordomo + 12. Fetchmail + 13. Perl + 14. Dial-up and ISDN + 15. UUCP + 16. Modifying message bodies + 17. Encryption (TLS/SSL) + 20. Millennium + 50. Miscellaneous + 91. Mac OS X + 92. FreeBSD + 93. HP-UX + 94. BSDI + 95. IRIX + 96. Linux + 97. Sun sytems + 98. Configuration cookbook + 99. List of sample configurations + + + +0. GENERAL DEBUGGING + +Q0001: Exim is crashing. What is wrong? + +A0001: Exim should never crash. The author is always keen to know about + crashes, so that they can be diagnosed and fixed. However, before you + start sending me email, please check that you are running the latest + release of Exim, in case the problem has already been fixed. The + techniques described below can also be useful in trying to pin down + exactly which circumstances caused the crash and what Exim was trying to + do at the time. If the crash is reproducable (by a particular message, + say) keep a copy of that message. + + +Q0002: Exim is not working. What is wrong? How can I check what it is doing? + +A0002: Exactly how is it not working? Check the more specific questions in the + other sections of this FAQ. Some general techniques for debugging are: + + (1) Look for information in Exim's log files. These are in the \(log)\ + directory in Exim's spool directory, unless you have configured a + different path for them. Serious operational problems are reported + in paniclog. + + (2) If the problem involves the delivery of one or more messages, try + forcing a delivery with the \-M-\ option and also set the \-d-\ + option, to cause Exim to output debugging information. For example: + +==> exim -d -M 0z6CXU-0005RR-00 + + The output is written to the standard error stream. You need to have + admin privileges to use \-M-\ and \-d-\. + + (3) If the problem involves incoming SMTP mail, try using the \-bh-\ + option to simulate an incoming connection from a specific host, + for example: + +==> exim -bh 10.9.8.7 + + This goes through the motions of an SMTP session, without actually + accepting a message. Information about various policy checks is + output. You will need to know how to pretend to be an SMTP client. + + (4) If the problem involves lack of recognition or incorrect handling + of local addresses, try using the \-bt-\ option with debugging turned + on, to see how Exim is handling the address. For example, + +==> exim -d -bt z6abc + + shows you how it would handle the local part \"z6abc"\. + + +Q0003: What does the error \*Child process of address_pipe transport returned + 69 from command xxx*\ mean? + +A0003: It means that when a transport called \%address_pipe%\ was run to pass an + email message by means of a pipe to another process running the command + xxx, the return code from that command was 69, which indicates some kind + of error (the success return code is 0). + + The most common meaning of exit code 69 is ``unavailable'', and this often + means that when Exim tried to run the command \(xxx)\, it failed. One + cause of this might be incorrect permissions on the file containing the + command. See also Q0026. + + +Q0004: My virtual domain setup isn't working. How can I debug it? + +A0004: You can use an exim command with \-d-\ to get it to show you how it is + processing addresses. You don't actually need to send a message; use the + \-bt-\ option like this: + +==> exim -d -bt localpart@virtualhost + + This will show you which routers it is using. If the problem appears + to be with the expansion of an option setting, you can use the + \debug_print\ option on a router to get Exim to output the expanded + string values as it goes along. + + +Q0005: Why is Exim not rejecting incoming messages addressed to non-existent + users at SMTP time? + +A0005: This is controlled by the ACL that is run for each incoming RCPT + command. It is defined by the \acl_smtp_rcpt\ option. You can check this + part of your configuration by using the \-bh-\ option to run a simulated + SMTP session, during which Exim will tell you what things it is + checking. + + +Q0006: I've put an entry for \"*.my.domain"\ in a DBM lookup file, but it isn't + getting recognized. + +A0006: You need to request ``partial matching'' by setting the search type to + \partial-dbm\ in order for this to work. + + +Q0007: I've put the entry \"*@domain.com"\ in a lookup database, but it isn't + working. The expansion I'm using is: + +==> ${lookup{${lc:$sender_address}}dbm{/the/file} ... + +A0007: As no sender address will ever be //*@domain.com// this will indeed have + no effect as it stands. You need to tell Exim that you want it to look + for defaults after the normal lookup has failed. In this case, change the + search type from \"dbm"\ to \"dbm*@"\. See the section on \*Default values in + single-key lookups*\ in the chapter entitled \*File and database + lookups*\ in the Exim manual. + + +Q0008: If I run \"./exim -d -bt user@domain"\ all seems well, but when I send + a message from my User Agent, it does not arrive at its destination. + +A0008: Try sending a message directly to Exim by typing this: + +==> exim -v user@domain + <some message, could be empty> + . + + If the message gets delivered to a remote host, but never arrives at its + final destination, then the problem is at the remote host. If, however, + the message gets through correctly, then the problem may be between your + User Agent and Exim. Try setting Exim's \log_selector\ option to include + \"+arguments"\, to see with which arguments the UA is calling Exim. + + +Q0009: What does \*no immediate delivery: too many messages received in one SMTP + connection*\ mean? + +A0009: An SMTP client may send any number of messages down a single SMTP + connection to a server. Initially, an Exim server starts up a delivery + process as soon as a message is received. However, in order not to start + up too many processes when lots of messages are arriving (typically + after a period of downtime), it stops doing immediate delivery after a + certain number of messages have arrived down the same connection. The + threshold is set by \smtp_accept_queue_per_connection\, and the default + value is 10. On large systems, the value should be increased. If you are + running a dial-in host and expecting to get all your mail down a single + SMTP connection, then you can disable the limit altogether by setting + the value to zero. + + +Q0010: Exim puts \*for \[address]\*\ in the ::Received:: headers of some, but not all, + messages. Is this a bug? + +A0010: No. It is deliberate. Exim inserts a ``for'' phrase only if the incoming + message has precisely one recipient. If there is more than one + recipient, nothing is inserted. The reason for this is that not all + recipients appear in the ::To:: or ::Cc:: headers, and it is considered a + breach of privacy to expose such recipients to the others. A common + case is when a message has come from a mailing list. + + +Q0011: Instead of \^exim_dbmbuild^\, I'm using a homegrown program to build DBM + (or cdb) files, but Exim doesn't seem to be able to use them. + +A0011: Exim expects there to be a binary zero value on the end of each key used + in a DBM file if you use the \"dbm"\ lookup type, but not for the \"dbmnz"\ + lookup type or for the keys of a cdb file. Check that you haven't + slipped up in this regard. + + +Q0012: Exim is unable to route to any remote domains. It doesn't seen to be + able to access the DNS. + +A0012: Try running \"exim -d+resolver -bt \[remote address]\"\. The \-d-\ + options turns on debugging output, and the addition of \"+resolver"\ + will make it show the resolver queries it is building and the results of + its DNS queries. If it appears unable to contact any name servers, check + the contents and permissions of \(/etc/resolv.conf)\. + + +Q0013: What does the error message \*transport system_aliases: cannot find + transport driver "redirect" in line 92*\ mean? + +A0013: \%redirect%\ is a router, not a transport. You have put a configuration + for a router into the transports section of the configuration file. + + +Q0014: Exim is timing out after receiving and responding to the DATA command + from one particular host, and yet the client host also claims to be + timing out. This seems to affect only certain messages. + +A0014: This kind of problem can have many different causes. + + (1) This problem has been seen with a network that was dropping all + packets over a certain size, which mean that the first part of the SMTP + transaction worked, but when the body of a large message started + flowing, the main data bits never got through the network. See also + Q0017. + + (2) This can also happen if a host has a broken TCP stack and won't + reassemble fragmented datagrams. + + (3) A very few ISDN lines have been seen which failed when certain data + patterns were sent through them, and replacing the routers at both end + of the link did not fix things. One of them was triggered by more than 4 + X's in a row in the data. + + +Q0015: What does the message \*Socket bind() to port 25 for address (any) + failed: address already in use*\ mean? + +A0015: You are trying to run an Exim daemon when there is one already running - + or maybe some other MTA is running, or perhaps you have an SMTP line in + \(/etc/inetd.conf)\ which is causing \(inetd)\ to listen on port 25. + + +Q0016: I've set \"verify = header_syntax"\ in my ACL, but this causes Exim to + complain about header lines like \"To: Work: Jim <jims@email>, + Home: Bob <bobs@email>"\ which look all right to me. Is this a bug? + +A0016: No. Header lines such as ::From::, ::To::, etc., which contain addresses, are + structured, and have to be in a specific format which is defined in RFC + 2822. Unquoted colons are not allowed in the ``phrase'' part of an email + address (they are OK in other headers such as ::Subject::). The correct + form for that header is + +==> To: "Work: Jim" <jims@email>, "Home: Bob" <bobs@email> + + You will sometimes see unquoted colons in ::To:: and ::Cc:: headers, but only + in connection with name lists (called ``groups''), for example: + +==> To: My friends: X <x@y.x>, Y <y@w.z>;, + My enemies: A <a@b.c>, B <b@c.d>; + + Each list must be terminated by a semicolon, as shown. + + +Q0017: Whenever Exim tries to deliver a specific message to a particular + server, it fails, giving the error \*Remote end closed connection after + data*\ or \*Broken pipe*\ or a timeout. What's going on? + +A0017: \*Broken pipe*\ is the error you get on some OS when the remote host just + drops the connection. The alternative is \*connection reset by peer*\. + There are many potential causes. Here are some of them (see also Q0068): + + (1) There are some firewalls that fall over on binary zero characters + in email. Have a look, e.g. with \"hexdump -c mymail | tail"\ to see if + your mail contains any binary zero characters. + + (2) There are broken SMTP servers around that just drop the connection + after the data has been sent if they don't like the message for some + reason (e.g. it is too big) instead of sending a 5xx error code. Have + you tried sending a small message to the same address? + + It has been reported that some releases of Novell servers running NIMS + are unable to handle lines longer than 1024 characters, and just close + the connection. This is an example of this behaviour. + + (3) If the problem occurs right at the start of the mail, then it could + be a network problem with mishandling of large packets. Many emails are + small and thus appear to propagate correctly, but big emails will + generate big IP datagrams. + + There have been problems when something in the middle of the network + mishandles large packets due to IP tunnelling. In a tunnelled link, your + IP datagrams gets wrapped in a larger datagram and sent over a network. + This is how virtual private networks (VPNs), and some ISP transit + circuits work. Since the datagrams going over the tunnel require a + larger packet size, the tunnel needs a bigger maximum transfer unit + (MTU) in the network handling the tunnelled packets. However, MTUs + are often fixed, so the tunnel will try to fragment the packets. + + If the systems outside the tunnel are using path MTU discovery, (most + Sun Sparc Solaris machines do by default), and set the DF (don't + fragment) bit because they don't send packets larger than their \(local)\ + MTU, then ICMP control messages will be sent by the routers at the + ends of the tunnel to tell them to reduce their MTU, since the tunnel + can't fragment the data, and has to throw it away. If this mechanism + stops working, e.g. a firewall blocks ICMP, then your host never + knows it has hit the maximum path MTU, but it has received no ACK on + the packet either, so it continues to resend the same packet and the + connection stalls, eventually timing out. + + You can test the link using pings of large packets and see what works: + +==> ping -s host 2048 + + Try reducing the MTU on the sending host: + +==> ifconfig le0 mtu 1300 + + Alternatively, you can reduce the size of the buffer Exim uses for SMTP + output by putting something like + +==> DELIVER_OUT_BUFFER_SIZE=512 + + in your \(Local/Makefile)\ and rebuilding Exim (the default is 8192). + While this should not in principle have any effect on the size of + packets sent, in practice it does seem to have an effect on some OS. + + You can also try disabling path MTU discovery on the sending host. On + Linux, try: + +==> echo 1 >/proc/sys/net/ipv4/ip_no_pmtu_disc + + For a general discussion and information about other operating systems, see + \?http://www.netheaven.com/pmtu.html?\. If disabling path MTU discovery + fixes the problem, try to find the broken or misconfigured + router/firewall that swallows the ICMP-unreachable packets. Increasing + timeouts on the receiving host will not work around the problem. + + +Q0018: Why do messages not get delivered down the same connection when I do + something like: \"exim -v -R @aol.com"\? For other domains, I do this and + I see the appropriate \*waiting for passed connections to get used*\ + messages. + +A0018: Recall that Exim does not keep separate queues for each domain, but + operates in a distributed fashion. Messages get into its `waiting for + host x' hints database only when a delivery has been tried, and has had + a temporary error. Here are some possibilities: + + (1) The messages to \(aol.com)\ got put in your queue, but no previous + delivery attempt occured before you did the \-R-\. This might have been + because of your settings of \queue_only_load\, \smtp_accept_queue\, or any + other option that caused no immediate delivery attempt on arrival. If + this is the case, you can try using \-qqR-\ instead of \-R-\. + + (2) You have set \connection_max_messages\ on the smtp transport, and + that limit was reached. This would show as a sequence of messages + down one connection, then another sequence down a new connection, etc. + + (3) Exim tried to pass on the SMTP connection to another message, but + that message was in the process of being delivered to \(aol.com)\ by some + other process (typically, a normal queue runner). This will break the + sequence, though the other delivery should pass its connection on to + other messages if there are any. + + (4) The folk at \(aol.com)\ changed the MX records so the host names have + changed - or a new host has been added. I don't know how likely this is. + + (5) Exim is not performing as it should in this regard, for some reason. + Next time you have mail queued up for \(aol.com)\, try running + +==> exim_dumpdb /var/spool/exim wait-remote_smtp + + to see if those messages are listed among those waiting for the relevant + \(aol.com)\ hosts. + + +Q0019: There seems to be a problem in the string expansion code: it doesn't + recognize references to headers such as \"${h_to}"\. + +A0019: The only valid syntax for header references is (for example) \"$h_to:"\ + because header names are permitted by RFC 2822 to contain a very wide + range of characters. A colon (or white space) is required as the + terminator. + + +Q0020: Why do connections to my machine's SMTP port take a long time to respond + with the banner, when connections to other ports respond instantly? The + delay is sometimes as long as 30 seconds. + +A0020: These kinds of delay are usually caused by some kind of network problem + that affects outgoing calls made by Exim at the start of an incoming + connection. Configuration options that cause outgoing calls are: + + (1) \rfc1413_hosts\ and \rfc1413_query_timeout\ (for \*ident*\ calls). + Firewalls sometimes block ident connections so that they time out, + instead of refusing them immediately. This can cause this problem. + See Q5023 for a discussion of the usefulness of \*ident*\. + + (2) The \host_lookup\ option, the \host_reject_connection\ option, or a + condition in the ACL that runs at connection time requires the + remote host's name to be looked up from its IP address. Sometimes + these DNS lookups time out. You can get this effect with ACL + statements like this: + +==> deny hosts = *.x.example + + If at all possible, you should use IP addresses instead of host + names in blocking lists in order to to avoid this problem. + + You can use the \-bh-\ option to get more information about what is + happening at the start of a connection. However, note that the \-bh-\ + option does not provide a complete simulation. In particular, no + \*ident*\ checks are done, so it won't show up a delay problem that is + related to (1) above. + + +Q0021: What does \*failed to create child process to send failure message*\ mean? + This is a busy mail server with \smtp_accept_max\ set to 500, but this + problem started to occur at about 300 incoming connections. + +A0021: Some message delivery failed, and when Exim wanted to send a bounce + message, it was unable to create a process in which to do so. Probably + the limit on the maximum number of simultaneously active processes has + been reached. Most OS have some means of increasing this limit, and in + some operating systems there is also a limit per uid which can be + varied. + + +Q0022: What does \*No transport set by system filter*\ in a log line mean? + +A0022: Your system filter contains a \"pipe"\ or \"save"\ or \"mail"\ command, + but you have not set the corresponding option which specifies which + transport is to be used. You need to set whichever of + \system_filter_pipe_transport\, \system_filter_file_transport\ or + \system_filter_reply_transport\ is relevant. + + +Q0023: Why is Exim refusing to relay, saying \*failed to find host name from IP + address*\ when I have the sender's IP address in an ACL condition? My + configuration contains this ACL statement: + +==> accept hosts = lsearch;/etc/mail/relaydomains:192.168.96.0/24 + +A0023: When checking a host list, the items are tested in left-to-right + order. The first item in your list is a lookup on the incoming host's + name, so Exim has to determine the name from the incoming IP address in + order to perform the test. If it can't find the host name, it can't do + the check, so it gives up. You would have discovered what was going + on if you had run a test such as + +==> exim -bh 192.168.96.131 + + The solution is to put all explicit IP addresses first in the list. + Alternatively, you can split the ACL statement into two like this: + +==> accept hosts = lsearch;/etc/mail/relaydomains + accept hosts = 192.168.96.0/24 + + If the host lookup fails, the first \"accept"\ fails, but then the + second one is considered. + + +Q0024: When I run \"exim -bd -q10m"\ I get \*PANIC LOG: exec of exim -q failed*\. + +A0024: This probably means that Exim doesn't know its own path so it can't + re-exec itself to do the first queue run. Check the output of + +==> exim -bP exim_path + + +Q0025: I can't seem to get a pipe command to run when I include a \"${if"\ + expansion in it. This fails: + +==> command = perl -T /usr/local/rt/bin/rtmux.pl \ + rt-mailgate helpdesk \ + ${if eq {$local_part}{rt} {correspond}{action}} + +A0025: You need some internal quoting in there. Exim expands each individual + argument separately. Because you have (necessarily) got spaces in your + \"${if"\ item, you have to quote that argument. Try + +==> command = perl -T /usr/local/rt/bin/rtmux.pl \ + rt-mailgate helpdesk \ + "${if eq {$local_part}{rt} {correspond}{action}}" + + \**Warning:**\ If command starts with an item that requires quoting, + you cannot just put it in quotes, because a leading quote means that the + entire option setting is being quoted. What you have to do is to quote + the entire value, and use internally escaped quotes for the ones you + really want. For example: + +==> command = "\"${if ....}\" arg1 arg2" + + Any backslashes in the expansion items will have to be doubled to stop + them being interpreted by the string reader. + + +Q0026: I'm trying to get Exim to connect an alias to a pipe, but it always + gives error code 69, with the comment \*(could mean service or program + unavailable)*\. + +A0026: If your alias entry looks like this: + +==> alias: |"/some/command some parameters" + + change it to look like this: + +==> alias: "|/some/command some parameters" + + +Q0027: What does the error \*Spool file is locked*\ mean? + +A0027: This is not an error. All it means is that when an Exim delivery + process (probably started by a queue runner process) looked at a message + in order to start delivering it, it found that another Exim process was + already busy delivering it. On a busy system this is quite a common + occurrence. If you set \"-skip_delivery"\ in the \log_selector\ option, + these messages are omitted from the log. + + The only time when this message might indicate a problem is if it is + repeated for the same message for a very long time. That would suggest + that the process that is delivering the message has somehow got stuck. + + +Q0028: Exim is reporting IP addresses as 0.0.0.0 or 255.255.255.255 instead of + their correct values. What's going on? + +A0028: You are using a version of Exim built with gcc on an IRIX box. + See Q9502. + + +Q0029: I can't seem to figure out why PAM support doesn't work correctly. + +A0029: There is a problem using PAM with shadow passwords when the calling + program is not running as \/root/\. Exim is normally running as the + Exim user when authenticating a remote host. See this posting for one + way round the problem: + + \?http://www.exim.org/mailman/htdig/exim-users/Week-of-Mon-20010917/030371.html?\ + + Another solution can be found at \?http://www.e-admin.de/pam_exim/?\. + + PAM 0.72 allows authorization as non-\/root/\, using setuid helper programs. + Furthermore, in \(/etc/pam.d/exim)\ you can explicitelly specify that + this authorization (using setuid helpers) is only permitted for certain + users and groups. + + +Q0030: I'm trying to use a query-style lookup for hosts that are allowed to + relay, but it is giving really weird errors. + +A0030: Does your query contain a colon character? Remember that host lists are + colon-separated, so you need to double any colons in the query. This + applies even if the query is defined as a macro. + + +Q0031: Exim is rejecting connections from hosts that have more than one IP + address, for no apparent reason. + +A0031: You are using Solaris 7 or earlier, and have \"nis dns files"\ in + \(/etc/nsswitch.conf)\. Change this to \"dns nis files"\ to avoid hitting Sun + bug 1154236 (a bad interaction between NIS and the DNS). + + +Q0032: Exim is failing to find the MySQL library, even though is it present + within \\LD_LIBRARY_PATH\\. I'm getting this error: + +==> /usr/local/bin/exim: fatal: libmysqlclient.so.6: open failed: + No such file or directory + +A0032: Exim is suid, and \\LD_LIBRARY_PATH\\ is ignored for suid binaries on a + Solaris (and other?) systems. What you should be doing is adding + \"-R/local/lib/mysql"\ to the same place in the compilation that you added + \"-L/local/lib/mysql"\. This tells the binary where to look without + needing a path variable. + + +Q0033: What does the error \*lookup of host "xx.xx.xx" failed in yyy router*\ + mean? + +A0033: You configured a \%manualroute%\ router to send the message to xx.xx.xx. When + it tried to look up the IP address for that host, the lookup failed + with a permanent error. As this is a manual routing, this is a + considered to be a serious error which the postmaster needs to know + about (maybe you have a typo in your file), and there is little point + in keeping on trying. So it freezes the message. + + (1) Don't set up routes to non-existent hosts. + + (2) If you must set up routes to non-existent hosts, and don't want + freezing, set the \host_find_failed\ option on the router to do something + other than freeze. + + +Q0034: Exim works fine on one host, but when I copied the binary to another + identical host, it stopped working (it could not resolve DNS names). + +A0034: Is the new host running exactly the same operating system? Most + importantly, are the versions of the dynamically loaded libraries + (files with names like \(libsocket.so.1)\) the same on both systems? If not, + that is probably the cause of the problem. Either arrange for the + libraries to be the same, or rebuild Exim from source on the new host. + + +Q0035: I set a \"hosts"\ condition in an ACL to do a lookup in a file of IP + addresses, but it doesn't work. + +A0035: Did you remember to put \"net-"\ at the start of the the search type? If + you set something like this: + +==> accept hosts = lsearch;/some/file + + Exim searches the file for the host name, not the IP address. You need + to set + +==> accept hosts = net-lsearch;/some/file + + to make it use the IP address as the key to the lookup. + + +Q0036: Why do I get the error \*Permission denied: creating lock file hitching + post*\ when Exim tries to do a local delivery? + +A0036: Your configuration specifies that local mailboxes are all held in + single directory, via configuration lines like these (taken from the + default configuration): + +==> local_delivery: + driver = appendfile + file = /var/mail/$local_part + + and the permissions on the directory probably look like this: + +==> drwxrwxr-x 3 root mail 512 Jul 9 13:48 /var/mail/ + + Using the default configuration, Exim runs as the local user when doing + a local delivery, and it uses a lock file to prevent any other process + from updating the mailbox while it is writing to it. With those + permissions the delivery process, running as the user, is unable to + create a lock file in the \(/var/mail(\ directory. There are two solutions + to this problem: + + (1) Set the \"write"\ and \"sticky bit"\ permissions on the directory, so + that it looks like this: + +==> drwxrwxrwt 3 root mail 512 Jul 9 13:48 /var/mail/ + + The \"w"\ allows any user to create new files in the directory, but + the \"t"\ bit means that only the creator of a file is able to remove + it. This is the same setting as is normally used with the \(/tmp)\ + directory. + + (2) Arrange to run the local_delivery transport under a specific group + by changing the configuration to read + +==> local_delivery: + driver = appendfile + file = /var/mail/${local_part} + group = mail + + The delivery process still runs under the user's uid, but with the + group set to \"mail"\. The group permission on the directory allows + the process to create and remove the lock file. + + The choice between (1) and (2) is up to the administrator. If the + second solution is used, users can empty their mailboxes by updating + them, but cannot delete them. + + If your problem involves mail to \/root/\, see also Q0507. + + +Q0037: I am experiencing mailbox locking problems with Sun's \"mailtool"\ used + over a network. + +A0037: See Q9705 in the Sun-specific section below. + + +Q0038: What does the error message \*error in forward file (filtering not + enabled): missing or malformed local part*\ mean? + +A0038: If you are trying to use an Exim filter, you have forgotten to enable + the facility, which is disabled by default. In the \%redirect%\ router + (in the Exim run time configuration file) you need to set + +==> allow_filter = true + + to allow a \(.forward)\ file to be used as an Exim filter. If you are not + trying to use an Exim filter, then you have put a malformed address in + the \(.forward)\ file. + + +Q0039: I have installed Exim, but now I can't mail to \/root/\ any more. Why is + this? + +A0039: Most people set up \/root/\ as an alias for the manager of the host. If + you haven't done this, Exim will attempt to deliver to \/root/\ as if it + were a normal user. This isn't really a good idea because the delivery + process would run as \/root/\. Exim has a trigger guard in the option + +==> never_users = root + + in the default configuration file. This prevents it from running as \/root/\ + when doing any deliveries. If you really want to run local deliveries as + \/root/\, remove this line, but it would be better to create an alias for + \/root/\ instead. + + +Q0040: How can I stop undeliverable bounce messages (e.g. to routeable, but + undeliverable, spammer senders) from clogging up the queue for days? + +A0040: If at all possible, you should try to avoid getting into this situation + in the first place, for example, by verifying recipients so that you + do not accept undeliverable messages that lead to these bounces. + You can, however, configure Exim to discard failing bounce messages + early. Just set \ignore_bounce_errors_after\ to specify a (short) time + to keep them for. + + +Q0041: What does the message \*unable to set gid=ddd or uid=ddd (euid=ddd): + local delivery to ... transport=ttt*\ mean? + +A0041: Have you remembered to make Exim setuid \/root/\? It needs root privilege if + it is to do any local deliveries, because it does them ``as the user''. + Note also that the partition from which Exim is running (where the + binary is installed) must not have the \nosuid\ mount option set. You + can check this by looking at its \(/etc/fstab)\ entry (or \(/etc/vfstab)\, + depending on your OS). + + +Q0042: My ISP's mail server is rejecting bounce messages from Exim, complaining + that they have no sender. The SMTP trace does indeed show that the + sender address is \"<>"\. Why is the Sender on the bounce message empty? + +A0042: Because the RFCs say it must be. Your ISP is at fault. Send them this + extract from RFC 2821 section 6.1 (\*Reliable Delivery and Replies by + Email*\): + + If there is a delivery failure after acceptance of a message, the + receiver-SMTP MUST formulate and mail a notification message. This + notification MUST be sent using a null (\"<>"\) reverse path in the + envelope. The recipient of this notification MUST be the address + from the envelope return path (or the ::Return-Path:: header line). + However, if this address is null (\"<>"\), the receiver-SMTP MUST NOT + send a notification. + + The reason that bounce messages have no sender is so that they + themselves cannot provoke further bounces, as this could lead to a + unending exchange of undeliverable messages. + + +Q0043: What does the error \*Unable to get interface configuration: 22 Invalid + argument*\ mean? + +A0043: This is an error that occurs when Exim is trying to find out the all the + IP addresses on all of the local host's interfaces. If you have lots of + virtual interfaces, this can occur if there are more than around 250 of + them. The solution is to set the option \local_interfaces\ to list just + those IP addresses that you want to use for making and receiving SMTP + connections. + + +Q0044: What does the error \*Failed to create spool file*\ mean? + +A0044: Exim has been unable to create a file in its spool area in which to + store an incoming message. This is most likely to be either a + permissions problem in the file hierarchy, or a problem with the uid + under which Exim is running, though it could be something more drastic + such as your disk being full. + + If you are running Exim with an alternate configuration file using a + command such as \"exim -C altconfig..."\, remember that the use of -C + takes away Exim's root privilege. + + Check that you have defined the spool directory correctly by running + +==> exim -bP spool_directory + + and examining the output. Check the mode of this directory. It should + look like this, assuming you are running Exim as user \/exim/\: + +==> drwxr-x--- 6 exim exim 512 Jul 16 12:29 /var/spool/exim + + If there are any subdirectories already in existence, they should have + the same permissions, owner, and group. Check also that you haven't got + incorrect permissions on superior directories (for example, \(/var/spool)\). + Check that you have set up the Exim binary to be setuid \/root/\. It should + look like this: + +==> -rwsr-xr-x 1 root xxx 502780 Jul 16 14:16 exim + + Note that it is not just the owner that must be \/root/\, but also the third + permission must be \"s"\ rather than \"x"\. + + +Q0045: I see entries in the log that mention two different IP addresses for the + same connection. Why is this? For example: + +==> H=tip-mp8-ncs-13.stanford.edu ([36.173.0.189]) [36.173.0.156] + +A0045: The actual IP address from which the call came is the final one. + Whenever there's something in parentheses in a host name, it is what the + host quoted as the domain part of an SMTP HELO or EHLO command. So in + this case, the client, despite being 36.173.0.156, issued the command + +==> EHLO [36.173.0.189] + + when it sent your server the message. This is, of course, very + misleading. + + +Q0046: A short time after I start Exim I see a defunct zombie process. What + is causing this? + +A0046: Your system must be lightly loaded as far as mail is concerned. The + daemon sets off a queue runner process when it is started, but it only + tidies up completed child processes when it wakes up for some other + reason. When there's nothing much going on, you occasionally see + defunct processes like this waiting to be dealt with. This is + perfectly normal. + + +Q0047: On a reboot, or a restart of the mail system, I see the message \*Mailer + daemons: exim abandoned: unknown, malformed, or incomplete option + -bz sendmail*\. What does this mean? + +A0047: \-bz-\ is a Sendmail option requesting it to create a `configuration freeze + file'. Exim has no such concept and so does not support the option. You + probably have a line like + +==> /usr/lib/sendmail -bz + + in some start-up script (e.g. \(/etc/init.d/mail)\) immedately before + +==> /usr/lib/sendmail -bd -q15m + + The first of these lines should be commented out. + + +Q0048: Whenever exim restarts it takes up to 3-5 minutes to start responding on + the SMTP port. Why is this? + +A0048: Something else is hanging onto port 25 and not releasing it. One place + to look is \(/etc/inetd.conf)\ in case for any reason an SMTP stream is + configured there. + + +Q0049: What does the log message \*no immediate delivery: more than 10 messages + received in one connection*\ mean? + +A0049: A remote MTA sent a number of messages in a single SMTP session. Exim + limits the number of immediate delivery processes it creates as a + result of a single SMTP connection, in order to avoid creating a zillion + processes on systems that can have many incoming connections. If you are + dialing in to collect mail from your ISP, you should probably set + \smtp_accept_queue_per_connection\ to some number larger than 10, or + arrange to start a queue runner for local delivery (using \-ql-\) + immediately after collecting the mail. + + +Q0050: I am getting complaints from a customer who uses my Exim server for + relaying that they are being blocked with a \*Too many connections*\ + error. + +A0050: See \smtp_accept_max\, \smep_accept_max_per_host\ and \smtp_accept_reserve\. + + +Q0051: When I try \"exim -bf"\ to test a system filter, I received the following + error message: \*Filter error: unavailable filtering command "fail" near + line 8 of filter file*\. + +A0051: Use the \-bF-\ option to test system filters. This gives you access to the + freeze and fail actions. + + +Q0052: What does \*ridiculously long message header*\ in an error report mean? + +A0052: There has to be some limit to the length of a message's header lines, + because otherwise a malefactor could open an SMTP channel to your host, + start a message, and then just send characters continuously until your + host ran out of memory. (Exim stores all the header lines in main + memory while processing a message). For this reason a limit is imposed + on the total amount of memory that can be used for header lines. The + default is 1MB, but this can be changed by setting \\HEADER_MAXSIZE\\ in + \(Local/Makefile)\ before building Exim. Exceeding the limit provokes + the ``ridiculous'' error message. + + +Q0053: Exim on my host responds to a connection with \"220 *****..."\ and + won't understand \\EHLO\\ commands. + +A0053: This is the sign of a Cisco Pix ``Mailguard'' sitting in front of your + MTA. Pix breaks ESMTP and only does SMTP. It is a nuisance when you have + a secure MTA running on your box. Something like ``no fixup protocol + smtp 25'' in the Pix configuration is needed. It may be possible to do + this by logging into the Pix (using \^telnet^\ or \^ssh^\) and typing + \"no fixup smtp"\ to its console. (You may need to use other commands + before or after to set up configuration mode and to activate a changed + configuration. Consult your Pix documentation or expert.) See also + Q0078. + + +Q0054: I'm getting an Exim configuration error \*unknown rewrite flag + character (m) in line 386*\ but I haven't used any flags on my rewriting + rules. + +A0054: You have probably forgotten to quote a replacement string that contains + white space. + + +Q0055: What does the error \*Failed to open wait-remote_smtp database: Invalid + argument*\ mean? + +A0055: This is something that happens if you have existing DBM hints files when + you install a new version of Exim that is compiled to use a different or + upgraded DBM library. The simplest thing to try is + +==> rm /var/spool/exim/db/* + + This removes all the hints files. Exim will start afresh and build new + ones. If the symptom recurs, it suggests there is some problem with your + DBM library. + + +Q0056: We are using Exim to send mail from our web server. However, whenever a + user sends an email it gets sent with the return path (envelope sender) + //apache@server_name.com// because the PHP script is running as + \/apache/\. + +A0056: You need to include \/apache/\ in the \trusted_users\ configuration option. + Only trusted users are permitted to specify senders when mail is passed + to Exim via the command line. + + +Q0057: We've got people complaining about attachments that don't show up + as attachments, but are included in the body of the message. + +A0057: These symptoms can be seen when some software passes a CRLF line + terminated message via the command line to an MTA that expects lines to + be terminated by LF only, and so preserves the CRs as data. If you can + identify the software that is doing this, try setting the \-dropcr-\ + option on the command it uses to call Exim. Alternatively, you can set + \drop_cr\ in the configuration file, but then that will apply to all + input. + + +Q0058: What does the error \*failed to open DB file \(/var/spool/exim/db/retry)\: + File exists*\ mean? + +A0058: This error is most often caused when a hints file that was written with + one version of the Berkeley DB library is read by another version. + Sometimes this can happen if you change from a binary version of Exim to + a locally compiled version. Or it can happen if you compile and install + a new version of Exim after changing Berkeley DB versions. You can find + out which version your Exim is using by running: + +==> ldd /usr/sbin/exim + + The solution to the problem is to delete all the files in the + \(/var/spool/exim/db)\ directory, and let Exim recreate them. + + +Q0059: When my Outlook Express 6.0 client sends a STARTTLS command to begin a + TLS session, Exim doesn't seem to receive it. The Outlook log shows + this: + +==> SMTP: 14:19:27 [tx] STARTTLS + SMTP: 14:19:27 [rx] 500 Unsupported command. + + but the Exim debugging output shows this: + +==> SMTP<< EHLO xxxx + SMTP>> 250-yyyy Hello xxxx [nnn.nnn.nnn.nnn] + 250-SIZE 52428800 + 250-PIPELINING + 250-AUTH CRAM-MD5 PLAIN LOGIN + 250-STARTTLS + 250 HELP + SMTP<< QUIT + +A0059: Turn off scanning of outgoing email in Norton Antivirus. If you aren't + running Norton Antivirus, see if you are running some other kind of SMTP + proxying, either on the client or on a firewall between the client and + server. ``Unsupported command'' is not an Exim message. + + +Q0060: Why am I getting the error \*failed to expand \"/data/lists/lists/${lc"\ + for require_files: \"${lc"\ is not a known operator*\ for this setting: + +==> require_files = MAILMAN_HOME/lists/${lc:$local_part}/config.db + +A0060: The value of \"require_files"\ is a \*list*\ in which each item is + separately expanded. You need either to double the colon, or switch to + a different list separator. + + +Q0061: What does the error \*Too many ``Received'' headers - suspected mail + loop*\ mean? + +A0061: Whenever a message passes through an MTA, a ::Received:: header gets + added. Exim counts the number of these headers in incoming messages. If + there are more than the value of \received_headers_max\ (default 30), + Exim assumes there is some kind of mail routing loop occurring. For + example, host A passes the message to host B, which immediately passes + it back to host A. Check the ::Received:: headers and the mail logs to + determine exactly what is going on. + + One common cause of this problem is users with accounts on both systems + who set up each one to forward to the other, thinking that will cause + copies of all messages to be delivered on both of them. + + +Q0062: When I try to start an Exim daemon it crashes. I ran a debugger and + discovered that the crash is happening in the function \^^getservbyname()^^\. + What's going on? + +A0062: What have you got in the file \(/etc/nsswitch.conf)\? If it contains this + line: + +==> services: db files + + try removing the \"db"\. (Your system is trying to look in some kind of + database before searching the file \(/etc/services)\.) + + +Q0063: When I try to start an Exim daemon, nothing happens. There is no + process, and nothing is written to the Exim log. + +A0063: Check to see if anything is written to \(syslog)\. This problem can be + caused by a permission problem that stops Exim from writing to its log + files, especially if you've specified that they should be written + somewhere other than under Exim's spool directory. You could also try + running the daemon with debugging turned on. + + +Q0064: When I run \"exim -d test@domain"\ it delivers fine, but when I send a + message from the \^mail^\ command, I get \*User unknown*\ and the mail + is saved in \(dead.letter)\. + +A0064: It looks as if Exim isn't being called by \^mail^\; instead it is + calling some other program (probably Sendmail). Try running the command + +==> /usr/sbin/sendmail -bV + + (If you get \*No such file or directory*\ or \*Command not found*\ you + are running Solaris or IRIX. Try again with \(/usr/lib/sendmail)\.) The + output should be something like this: + +==> Exim version 4.05 #1 built 13-Jun-2002 10:27:15 + Copyright (c) University of Cambridge 2002 + + If you don't see this, your Exim installation isn't fully operational. + If you are running FreeBSD, see Q9201. For other systems, see Q0114. + + +Q0065: When (as \/root/\) I use -C to run Exim with an alternate configuration + file, it gives an error about being unable to create a spool file when + trying to run an \%autoreply%\ transport. Why is this? + +A0065: When Exim is called with -C, it passes on -C to any instances of itself + that it calls (so that the whole sequence uses the same config file). If + it's running as \/exim/\ when it does this, all is well. However, if it + happens as a consequence of a non-privileged user running \%autoreply%\, + the called Exim gives up its root privilege. Then it can't write to the + spool. + + This means that you can't use -C (even as \/root/\) to run an instance of + Exim that is going to try to run \%autoreply%\ from a process that is + neither \/root/\ nor \/exim/\. Because of the architecture of Exim (using + re-execs to regain privilege), there isn't any way round this + restriction. Therefore, the only way you can make this scenario work is + to run the \%autoreply%\ transport as \/exim/\ (that is, the user that + owns the Exim spool files). This may be satisfactory for autoreplies + that are essentially system-generated, but of course is no good for + autoreplies from unprivileged users, where you want the \%autoreply%\ + transport to be run as the user. To get that to work with an alternate + configuration, you'll have to use two Exim binaries, with different + configuration file names in each. See S001 for a script that patches + the configuration name in an Exim binary. + + +Q0066: What does the message \*unable to set gid=xxx or uid=xxx*\ mean? + +A0066: This message is given when an Exim process is unable to change uid or + gid when it needs to, because it does not have root privilege. This is a + serious problem that prevents Exim from carrying on with what it is + doing. The two most common situations where Exim needs to change uid/gid + are doing local deliveries and processing users' filter files. There are + two common causes of this error: + + (1) You have forgotten to make the exim binary setuid to \/root/\. This + means that it can never change uid/gid in any situation. Also, the + setuid binary must reside on a disk partition that does not have the + \"nosuid"\ mount option set. + + (2) The exim binary is setuid, but you have configured Exim so that, + while trying to verify an address at SMTP time, it runs a router + that needs to change uid/gid. Because Exim runs as \/exim/\ and not + \/root/\ while receiving messages, the router is unable to change + uid and therefore it cannot operate. The usual example of this is a + \%redirect%\ router for users' filter files. + + Setting the \user\ or \check_local_user\ options on a \redirect\ + router causes this to happen (except in the special case when the + redirection list is provided by the \data\ option and does not + contain \":include:"\). + + The solution is to set \no_verify\ on the router that is causing the + problem. This means that it is skipped when an address is being + verified. In ``normal'' configurations where the router is indeed + handling users' filter files, this is quite acceptable, because you + do not usually need to process a filter file in order to verify that + the local part is valid. See, for example, the \%userforward%\ + router in the default configuration. + + +Q0067: What does the error \*too many unrecognized commands*\ mean? + +A0067: There have been instances of network abuse involving mail sent out by + web servers. In most cases, unrecognizable commands are sent as part of + the SMTP session. A real MTA never sends out such invalid commands. Exim + allows a few unrecognized commands in a session to permit humans who are + testing to make a few typos (it responds with a 5xx error). However, if + Exim receives too many such commands, it assumes that it is dealing with + an abuse of some kind, and so it drops the connection. + + +Q0068: Exim times out when trying to connect to some hosts, though those hosts + are known to be up and running. What's the problem? + +A0068: There could be a number of reasons for this (see also Q0017). The + obvious one is that there is a networking problem between the hosts. + If you can ping between the hosts or connect in other ways, the problem + might be caused by ECN (Explicit Congestion Notification) being enabled + in your kernel. ECN uses TCP flags originally assigned to TOS - it's a + "new" invention, and some hosts and routers are known to be confused if + a client uses it. If you are running Linux, you can turn ECN off by + running this command: + +==> /bin/echo "0" > /proc/sys/net/ipv4/tcp_ecn + + This has also been reported to cure web connection problems from Mozilla + and Netscape browsers in Linux when there were no problems with Windows + Netscape browsers. + + +Q0069: What does the error \*SMTP data timeout (message abandoned) on connection + from...*\ mean? + +A0069: It means that there was a timeout while Exim was reading the contents of + a message on an incoming SMTP connection. That is, it had successfully + accepted a MAIL command, one or more RCPT commands, and a DATA command, + and was in the process of reading the data itself. The length of timeout + is controlled by the \smtp_receive_timeout\ option. + + If you get this error regularly, the cause may be incorrect handling of + large packets by a router or firewall. The maximum size of a packet is + restricted on some links; routers should split packets that are larger. + There is a feature called ``path MTU discovery'' that enables a sender + to discover the maximum packet size over an entire path (multiple + Internet links). This can be broken by misconfigured firewalls and + routers. There is a good explanation at \?http://www.netheaven.com/pmtu.html?\. + Reducing the MTU on your local network can sometimes work round this + problem. See Q0017 (3) for further discussion. + + +Q0070: What does the error \*SMTP command timeout on connection from...*\ mean? + +A0070: Exim was expecting to read an SMTP command from the client, but no + command was read within the \smtp_receive_timeout\ time limit. + + +Q0071: What does the error \*failed to open DB file \(/var/spool/exim//db/retry)\: + Illegal argument*\ mean? + +A0071: See Q0058. The cause of this error is usually the same. + + +Q0072: Exim will deliver to normal aliases, and aliases that are pipes or + files, but it objects to aliases that involve \":include:"\ items, + complaining that it can't change gid or uid. Why is this? + +A0072: See Q0066 for a general answer. The problem happens during verification + of an incoming SMTP message, not during delivery itself. In this + particular case, you must have set up your aliasing router with a \user\ + setting. This causes Exim to change uid/gid when reading \":include:"\ + files. If you do not need the detailed verification provided by the + router, the easy solution is to set \no_verify\ so that the router isn't + used during verification. + + Otherwise, if you set \user\ on the router in order to provide a user + for delivery to pipes or files, one solution is to put the \user\ + setting on the transports instead of on the router. You may need to + create some special transports just for this router. The alternative is + to supply two different routers, one with \user\ and \no_verify\, and + the with \verify_only\ but no \user\ setting. + + +Q0073: I'm seeing log file corruption, with parts of log lines getting mangled + by other log entries. + +A0073: The only time this has been seen is when several servers were writing to + the same log files over NFS. Exim assumes that its log file is on local + disk, and using NFS, especially for more than one server, will not work. + + +Q0074: What does the error message \*remote delivery process count got out of + step*\ mean? + +A0074: Exim uses subprocesses for remote deliveries; this error means that the + master process expected to have a child process running, but found there + were none. Prior to release 4.11, this error could be caused by running + Exim under \^strace^\ on a Linux system, because stracing causes + children to be ``stolen'' such that a parent that tries to wait for + ``any of my children'' is told that it has none. Current releases of + Exim have code to get round this problem. + + +Q0075: I'm using LDAP, and some email addresses that contain special characters + are causing parsing errors in my LDAP lookups. + +A0075: You should be using \"${quote_ldap:$local_part}"\ instead of just + \"$local_part"\ in your lookups. + + +Q0076: I've configured Exim to use \^syslog^\ for its logs, with the main and + reject logs sent to different files, but whenever a message is rejected, + I get one message on the reject log and two messages on the main log. + +A0076: You are probably putting your reject items into the main log as well; + remember \^syslog^\ levels are inclusive (for example, \"mail.info"\ + includes all higher levels, so a \"mail.notice"\ message will be caught + by a \"mail.info"\ descriptor). + Test this by running the command: + +==> logger -p mail.notice test + + and seeing which logs it goes into. + + +Q0077: I've installed Exim and it is delivering mail just fine. However, when I + try to read mail from my PC I get \*connection rejected*\ or \*unable to + connect*\. + +A0077: See Q5021. + + +Q0078: Exim is logging the unknown SMTP command \"XXXX"\ from my client hosts, + and they are unable to authenticate. + +A0078: This is a sign of a Cisco PIX firewall getting in the way. It does not + support ESMTP, and turns EHLO commands into XXXX. You should configure + the Pix to leave SMTP alone; see Q0053 for how to do this. + + +Q0079: Our new PIX firewall is causing problems with incoming mail. How can + this be fixed? + +A0079: See Q0053 and Q0078. If some messages get through and others do not, + see also Q0017. + + +Q0080: Am I to understand that the database lookups must only return one value? + They can not return a list of values? The documentation seems to + indicate that it's possible to return a list. + +A0080: Lookups can be used in two different situations, and what they return is + different in the two cases. (Be thankful Exim 3 is gone; there was yet + another case!) + + (1) You can use a lookup in any expanded string. The syntax is + +==> ${lookup ..... } + + In this case, whatever is looked up replaces the expansion item. It + may be one value or a list of values. Whether a single value or a + list is acceptable or not depends on where you are using the string + expansion. If it is for an option that expects just one value, then + only one value is allowed (for example). + + (2) You can make use of the lookup mechanism to test whether something + (typically a host name or IP address) is in a list. For example, + +==> hosts = a : b : c + + in an ACL tests whether the calling host's name matches ``a'', or + ``b'', or ``c''. Now, suppose you want to keep the list of names in + a database, or cdb file, or NIS map, or... By writing + +==> hosts = pgsql;select .... + + you are saying to Exim: ``Run this lookup; if it succeeds, behave as + if the host is in the list; if it fails, the host is not in the + list.'' You are using the indexing mechanism of the database as a + fast way of checking a list. A simpler example is + +==> hosts = lsearch;/some/file + + where the file contains the list of hosts to be searched. + + The complication happens when a list is first expanded before being + interpreted as a list. This happens in a lot of cases. You can therefore + write either of these: + +==> hosts = cdb;/some/file + hosts = ${lookup{something}cdb{/some/file}} + + but they have different meanings. The first means ``see if the host name + is in the list in this file''. The second means ``run this lookup and + use the result of the lookup as a list of host items to check''. In the + second case, the list could contain multiple values (colon separated), + and one of those values could even be ``cdb;/some/file''. + + Flexibility does lead to complexity, I'm afraid. + + +Q0081: What does \*error in redirect data: included file xxxx is too big*\ + mean? + +A0081: You are trying to include a very large file in a redirection list, using + the \":include:"\ feature. Exim has a built-in limit on the size, as a + safety precaution. The default is 1 megabyte. If you want to increase + this, you have to rebuild Exim. In your \(Local/Makefile)\, put + +==> MAX_INCLUDE_SIZE = whatever + + and then rebuild Exim. The value is a number of bytes, but you can give + it as a parenthesized arithmetic expression such as \"(3*1024*1024)"\. + However, an included file of more than a megabyte is likely to be quite + inefficient. How many addresses does yours contain? You get the best + performance out of Exim if you arrange to send mailing list messages + with no more than about 100 recipients (in order to get parallelism in + the routing). + + +Q0082: What does \*relocation error: /lib/libnss_dns.so.2: symbol + __libc_res_nquery, version GLIBC_PRIVATE not defined in file + libresolv.so.2 with link time reference*\ mean? + +A0082: You have updated \^glibc^\ while an Exim daemon is running. Stop and + restart the daemon. + + +Q0083: Netscape on Unix is sending messages containing an unqualified user name + in the ::Sender:: header line, which Exim is rejecting because I have + set \"verify = header_syntax"\. How can I fix this? + +A0083: The only thing you can do in Exim is to set the + \sender_unqualified_hosts\ option to allow unqualified sender addresses + form the relevant hosts; of course, this applies to all sender + addresses, not just the ::Sender:: header line. + + Alternatively, you can configure Netscape not to include the header line + in the first place. Add the following line to the + \($HOME/.netscape/preferences.js)\ and \($HOME/.netscape/liprefs.js)\ + files: + +==> user_pref("mail.suppress_sender_header", true); + + Netscape \*must*\ be shutdown while doing this. + + +Q0084: I want to set up an alias that pipes a message to \^gpg^\ and then pipes + the result to \^mailx^\ to resubmit the message, but when I use my + tested command in an alias file, I get an error from \^gpg^\. + +A0084: Probably you are using a shell command with two pipe symbols in it. An + alias like this: + +==> gpg-xxx: "|gpg <options> | mailx <options" + + does not work, because Exim does not run pipes under a shell by default. + You must call a shell explicitly if you want to make use of the shell's + features for double-piping, either by piping to \"/bin/sh"\ with a + suitable \"-c"\ option, or by piping to a shell script. + + +Q0085: I see a lot of \*rejected EHLO ... syntactically invalid argument(s)*\. + I know it's because of the underscore in the host name, but is there a + switch to allow Exim to accept mail from such hosts? + +A0085: Yes. Add this to your configuration: + +==> helo_allow_chars = _ + + For more seriously malformed host names, see \helo_accept_junk_hosts\. + See also Q0732. + + +Q0086: What does \*SMTP protocol violation: synchronization error (next input + sent too soon)*\ mean? + +A0086: SMTP is a ``lock-step'' protocol, which means that, at certain points in + the protocol, the client must wait for the server to respond before + sending more data. Exim checks for correct behaviour, and issues this + error if the client sends data too soon. This protects against + malefactious clients who send a bunch of SMTP commands (usually to + transmit spam) without waiting for any replies. + + This error is also provoked if the client is trying to start up a TLS + session immediately on connection, without using the STARTTLS command. + See Q1707 for a discussion of this case. + + +Q0087: What does \*rejected after DATA: malformed address: xx@yy may not follow + <xx@yy> : failing address in "from" header*\ mean? (I've obscured the + real email addresses.) + +A0087: Your DATA ACL contains + +==> verify = header_syntax + + and an incoming message contained the line + +==> From: xx@yy <xx@yy> + + This is syntactically invalid. The contents of an address in a header + line are either just the address, or a ``phrase'' followed by an address + in angle brackets. In the latter case, the ``phrase'' must be quoted if + it contains special characters such as @. The following are valid + versions of the bad header: + +==> From: xx@yy + From: "xx@yy" <xx@yy> + + though why on earth anything generates this kind of redundant nonsense I + can't think. + + +Q0088: The Windows mailer SENDFILE.EXE sometimes hangs while trying to send a + message to Exim 4, and eventually times out. It worked flawlessly with + Exim 3. What has changed? + +A0088: Exim 4 sets an obscure TCP/IP parameter called TCP_NODELAY. This + disables the "Nagle algorithm" for the TCP/IP transmission. The Nagle + algorithm can improve network performance in interactive situations such + as a human typing at a keyboard, by buffering up outgoing data until the + previous packet has been acknowledged, and thereby reducing the number + of packets used. This is not relevant for mail transmission, which + mostly consists of quite large blocks of data; setting TCP_NODELAY + should improve performance. However, it seems that some Windows clients + do not function correctly if the server turns off the Nagle algorithm. + If you are using Exim 4.23 or later, you can set + +==> tcp_nodelay = false + + This stops Exim setting TCP_NODELAY on the sockets created by the + listening daemon. + + +Q0089: What does the error \*kernel: application bug: exim(12099) has SIGCHLD + set to SIG_IGN but calls wait()*\ mean? + +A0089: This was a bad interaction between a relatively recent change to the + Linux kernel and some ``belt and braces'' programming in Exim. The + following explanation is taken from Exim's change log: + + When Exim is receiving multiple messages on a single connection, and + spinning off delivery processess, it sets the SIGCHLD signal handling to + SIG_IGN, because it doesn't want to wait for these processes. However, + because on some OS this didn't work, it also has a paranoid call to + \^waitpid()^\ in the loop to reap any children that have finished. Some + versions of Linux now complain (to the system log) about this + ``illogical'' call to \^waitpid()^\. I have therefore put it inside a + conditional compilation, and arranged for it to be omitted for Linux. + + I am pretty sure I caught all the places in Exim where this happened. + However, there are still occasional reports of this error. I have not + heard of any resolutions, but my current belief is that they are caused + by something that Exim calls falling foul of the same check. There was + at one time a suspicion that the IPv6 stack was involved. + + +Q0090: I can't seem to get a pipe command to run when I include a \"${lookup"\ + expansion in it. + +A0090: See Q0025. + + +Q0091: Why is Exim giving the error \*Failed to send message from address_reply + transport*\ when I run it using -C to specify an alternate + configuration? + +A0091: See Q0065. + + + +1. BUILDING AND INSTALLING + +Q0101: I'm having a problem with an Exim RPM. + +A0101: Normally the thing to do if you have a problem with an RPM package is + to contact the person who built the package first, not the person who + made the software that's in the package. You can usually find out who + made a package using the following command: + +==> rpm --query --package --queryformat '%{PACKAGER}\n' <rpm-package-file> + + where \[rpm-package-file]\ is the actual file, e.g. \(exim-3.03-2.i386.rpm)\. + Or, if the package is installed on your system: + +==> rpm --query --queryformat '%{PACKAGER}\n' <package-name> + + where \[package-name]\ is the name component of the package, e.g. \"exim"\. + If the packager is unable or unwilling to help, only then should you + contact the actual author or associated mailing list of the software. + + If you discover through the querying process that you can't tell who + the person (or company or group) is who built the package, or that they + no longer exist at the given address, then you should reconsider + whether you want a package from an unknown source on your system. + + If you discover through the querying process that you yourself are the + person who built the package, then you should either (a) contact the + author or associated mailing list, or (b) reconsider whether you ought + to be building and distributing RPM packages of software you don't + understand. + + Similar rules of thumb govern other binary package formats, including + debs, tarballs, and POSIX packages. + + +Q0102: I can't get Exim to compile with Berkeley DB version 2.x or 3.x. + +A0102: Have you set \"USE_DB=yes\" in \(Local/Makefile)\? This causes Exim to use the + native interface to the DBM library instead of the compatibility + interface, which needs a header called \(ndbm.h)\ that may not exist on your + system. + + +Q0103: I'm getting an \*undefined symbol*\ error for \"hosts_ctl"\ when I try to + build Exim. (On some systems this error is \*undefined reference to + 'hosts_ctl'*\.) + +A0103: You should either remove the definition of \\USE_TCP_WRAPPERS\\ or add + \"-lwrap"\ to your \\EXTRALIBS\\ setting in Local/Makefile. + + +Q0104: I'm about to upgrade to a new Exim release. Do I need to ensure the + spool is empty, or take any other special action? + +A0104: It depends on where you are coming from. + + (1) If you are changing to release 4.00 or later from a release prior to + 4.00, you will need to make changes to the run time configuration file. + See the file \(doc/Exim4.upgrade)\ for details. If you are coming from + before release 3.00, you should also see \(doc/Exim3.upgrade)\. + + (2) If you are upgrading from an Exim 4 release to a later release, you + do not need to take special action. New releases are made backwards + compatible with old spool files and hints databases, so that upgrading + can be done on a running system. All that should be necessary is to + install a new binary and then HUP the daemon. + + +Q0105: What does the error \*install-info: command not found*\ mean? + +A0105: You have set \\INFO_DIRECTORY\\ in your \(Local/Makefile)\, and Exim is trying + to install the Texinfo documentation, but cannot find the command called + \(install-info)\. If you have a version of Texinfo prior to 3.9, you + should upgrade. Otherwise, check your installation of Texinfo to see why + the \(install-info)\ command is not available. + + +Q0106: Exim doesn't seem to be recognizing my operating system type correctly, + and so is failing to build. + +A0106: Run the command \"scripts/os-type -generic"\. The output should be one of + the known OS types, and should correspond to your operating system. You + can see which OS are supported by obeying \"ls OS/Makefile-*"\ and looking + at the file name suffixes. + + If there is a discrepancy, it means that the script is failing to + interpret the output from the \"uname"\ command correctly, or that the + output is wrong. Meanwhile, you can build Exim by obeying + +==> EXIM_OSTYPE=xxxx make + + instead of just \"make"\, provided you are running a Bourne-compatible + shell, or otherwise by setting \\EXIM_OSTYPE\\ correctly in your + environment. It is probably best to start again from a clean + distribution, to avoid any wreckage left over from the failed attempt. + + +Q0107: Exim fails to build, complaining about the absence of the \"killpg"\ + function. + +A0107: This function should be present in all modern flavours of Unix. If you + are using an older version, you should be able to get round the problem + by inserting + +==> #define killpg(pgid,sig) kill(-(pgid),sig) + + into the file called \(OS/os.h-xxx)\, where xxx identifies your operating + system, and is the output of the command \"scripts/os-type -generic"\. + + +Q0108: I'm getting an unresolved symbol \"ldap_is_ldap_url"\ when trying to build + Exim. + +A0108: You must have specified \"LOOKUP_LDAP=yes"\ in the configuration. Have you + remembered to set \"-lldap"\ somewhere (e.g. in \\LOOKUP_LIBS\\)? You need that + in order to get the LDAP library scanned when linking. + + +Q0109: I'm getting an unresolved symbol \"mysql_close"\ when trying to build Exim. + +A0109: You must have specified \"LOOKUP_MYSQL=yes"\ in the configuration. Have you + remembered to set \"-lmysqlclient"\ somewhere (e.g. in \\LOOKUP_LIBS\\)? You + need that in order to get the MySQL library scanned when linking. + + +Q0110: I'm trying to build Exim with PAM support. I have included \"-lpam"\ in + \\EXTRALIBS\\, but I'm still getting a linking error: + +==> /lib/libpam.so: undefined reference to `dlerror' + /lib/libpam.so: undefined reference to `dlclose' + /lib/libpam.so: undefined reference to `dlopen' + /lib/libpam.so: undefined reference to `dlsym' + +A0110: Add \"-ldl"\ to \\EXTRALIBS\\. In some systems these dynamic loading functions + are in their own library. + + +Q0111: I'm getting the error \*db.h: No such file or directory*\ when I try to + build Exim. + +A0111: This problem has been seen with RedHat 7.0, but could also happen in + other environments. If your system is using the DB library, you + need to install the DB development package in order to build Exim. + The package is called something like \"db3-devel-3.1.14-16.i386.rpm"\ for + Linux systems, but you should check which version of DB you have + installed (current releases are DB 4). + + +Q0112: I'm getting the error \*/usr/bin/ld: cannot find -ldb*\ when I try to + build Exim. + +A0112: This is probably the same problem as Q0111. + + +Q0113: I've compiled Exim and I've managed to start it but there was one + problem - it always complained that \(libmsqlclient.so.10)\ was not found, + even though this file is in \(/usr/local/lib/mysql/)\. + +A0113: Solaris: ensure you have this in your \(Local/Makefile)\: + +==> LOOKUP_LIBS=-L/usr/local/lib/mysql -R/usr/local/lib/mysql + + Net/Open/FreeBSD: Run this command (or ensure it gets run automatically + at boot time): + +==> ldconfig -m /usr/local/lib/mysql + + Linux: add \(/usr/local/lib/mysql)\ to \(/etc/ld.so.conf)\ and re-run \(ldconfig)\. + Alternatively, add + +==> -Wl,-rpath -Wl,/usr/local/lib/mysql + + to EXTRA_LIBS and then re-link (this is similar to the Solaris solution + above). This will probably also work on other systems that use GNU + Binutils. + + +Q0114: How can I remove Sendmail from my system? I've built Exim and run \"make + install"\, but it still doesn't seem to be fully operational. + +A0114: If you are running FreeBSD, see Q9201. Otherwise, you need to arrange + that whichever of the paths \(/usr/sbin/sendmail)\ or \(/usr/lib/sendmail)\ + exists on your system is changed to refer to Exim. For example, you + could use these commands (as \/root/\): + +==> mv /usr/sbin/sendmail /usr/sbin/sendmail.original + chmod u-s /usr/sbin/sendmail.original + ln -s /path/to/exim /usr/sbin/sendmail + + The second command removes the setuid privilege from the old MTA, as a + general safety precaution. In the third command, substitute the actual + path to the Exim binary for \(/path/to/exim)\. + + +Q0115: What does \*Can't open \(../scripts/newer)\: No such file or directory*\ + mean? I got it while trying to build Exim. + +A0115: You are using FreeBSD, or another OS that has a \^make^\ command which + tries to optimize the running of commands. Exim's \(Makefile)\ contains + targets with sequential commands like this: + +==> buildpcre: + @cd pcre; $(MAKE) SHELL=$(SHELL) AR="$(AR)" $(MFLAGS) CC="$(CC)" \ + CFLAGS="$(CFLAGS) $(PCRE_CFLAGS)" \ + RANLIB="$(RANLIB)" HDRS="$(PHDRS)" \ + INCLUDE="$(INCLUDE) $(IPV6_INCLUDE) $(TLS_INCLUDE)" + @if $(SHELL) $(SCRIPTS)/newer pcre/libpcre.a exim; then \ + /bin/rm -f exim eximon.bin; fi + + The second command assumes that the \"cd pcre"\ in the first command is + no longer in effect. If you have \"-j3"\ in your default set of + \"MAKEFLAGS"\, FreeBSD \^make^\ tries to optimize, and ends up up with both + commands in the same shell process. The result is that \"$(SCRIPTS)"\ + (which has a value of \"../scripts"\) is not found. + + The simplest solution is to force \^make^\ to use backwards compatibility + mode with each command in its own shell, by using the \-B\ flag. To + ensure that this happens throughout the build, it's best to export it in + your environment: + +==> MAKEFLAGS='-B' + export MAKEFLAGS + make + + +Q0116: I have tried to build Exim with Berkeley DB 3 and 4, but I always get + errors. + +A0116: One common problem, especially when you have several different versions + of BDB installed on the same host, is that the header files and library + files for BDB are not in a standard place. You therefore need to tell + Exim where they are, by setting INCLUDE and DBMLIB in your + \(Local/Makefile)\. For example, I use this on my workstation when + I want to build with DB 4.1: + +==> INCLUDE=-I/opt/local/include/db-4.1 + DBMLIB=/opt/local/lib/db-4.1/libdb.a + + Specifying the complete library file like this will cause it to be + statically linked with Exim. You'll have to check to see where these + files are on your system. For example, on FreeBSD 5, the header is in + \(/usr/local/include/db4)\ and the library is in \(/usr/local/lib)\ and + called \(libdb4)\. In that environment, you could use: + +==> INCLUDE=-I/usr/local/include/db4 + DBMLIB=-L/usr/local/lib -ldb4 + + This time, DBMLIB is specifying the library directory (\(/usr/local/lib)\) + and the name of the library (\(db4)\) separately. The name of the actual + library file is \(/usr/local/lib/libdb4.something)\. If the library was + compiled for dynamic linking, that will be used. + + +Q0117: Is there a quick walk-through of an Exim install from source anywhere? + +A0117: Here! This is a contribution from a RedHat user, somewhat edited. On + other operating systems things may be slightly different, but the + general approach is the same. + + (1) Install the db needed for Exim. This needs to be done first if you + don't have a DBM library installed. Go to \?http://www.sleepycat.com?\ + and download \(db-4.1.25.tar.gz)\, or whatever the current release is. + Then: + +==> gunzip db-4.1.25.tar.gz + tar -xvf db-4.1.25.tar + cd db-4.1.25 + cd build_unix + ../dist/configure + make + make install + + (2) Add a user for use by Exim, unless you want to use an existing user + such as \/mail/\: + +==> adduser exim + + (3) Now you can prepare to build Exim. Go to \?http://www.exim.org?\ or + one of its mirrors, or the master ftp site + \?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/exim4?\, and download + \(exim-4.20.tar.gz)\ or whatever the current release is. Then: + +==> gunzip exim-4.20.tar.gz + tar -xvf exim-4.20.tar + cd exim-4.20 + cp src/EDITME Local/Makefile + cp exim_monitor/EDITME Local/eximon.conf + + (4) Edit \(Local/Makefile)\: + + Comment out EXIM_MONITOR= unless you want to install the Exim + monitor (it requires X-windows). + + Set the user you want Exim to use for itself: + +==> EXIM_USER=exim + + If your DBM library is Berkeley DB, set up to use its native interface: + +==> USE_DB=yes + + Make sure Exim's build can find the DBM library and its headers. If + you've installed Berkeley DB 4 you'll need to have settings like this + in \(Local/Makefile)\: + +==> INCLUDE=-I/usr/local/BerkeleyDB.4.1/include + DBMLIB=/usr/local/BerkeleyDB.4.1/lib/libdb.a + + (Check that the first directory contains the db.h file and that the + second library exists.) + + You don't need to change anything else, but you might want to review + the default settings in the ``must specify'' section. + + (4) Build Exim by running the \/make/\ command. + + (5) Install Exim by running, as \/root/\: + +==> make install + + You \*must*\ be \/root/\ to do this. You do not have to be root for any of + the previous building activity. + + (6) Run some tests on Exim; see if it will do local and remote + deliveries. Change the configuration if necessary (for example, + uncommenting \group\ on the \%local_delivery%\ transport if you don't + use a ``sticky bit'' directory). + + (7) Change Sendmail to Exim (of course you need to have had Sendmail + installed to do this). + +==> /etc/init.d/sendmail stop + mv /usr/sbin/sendmail /usr/sbin/sendmail.org + ln -s /usr/exim/bin/exim /usr/sbin/sendmail + /etc/init.d/sendmail start + + (8) Check the Exim log. Either use the Exim monitor, or: + +==> tail -f /var/spool/exim/log/mainlog + + +Q0118: I've set \"LOOKUP_INCLUDE=-I/client/include"\ in Local/Makefile, but the + compilation of \^exim_dumpdb^\ is ignoring this option and failing. Why? + +A0118: LOOKUP_INCLUDE is the special include file for lookup modules in Exim + (e.g. mysql, LDAP). Confusingly, it doesn't apply to basic DBM code + which is used also for other things. Try setting INCLUDE and DBMLIB + instead. For example: + +==> USE_DB=yes + INCLUDE=-I/client/include + DBMLIB=/client/lib/libdb.a + + +Q0119: I know there are some 3rd-party patches for Exim, for exiscan and + other things. Where are they? + +A0119: Exiscan is at \?http://duncanthrax.net/exiscan-acl/?\. +[[br]] + Scanexi is at \?http://w1.231.telia.com/~u23107873/scanexi.html?\ +[[br]] + A sample \^^local_scan()^^\ function for interfacing to \^uvscan^\ is + at \?http://www.dcs.qmul.ac.uk/~mb/local_scan/?\. +[[br]] + An interface to SpamAssassin at SMTP time is at + \?http://marc.merlins.org/linux/exim/sa.html?\. +[[br]] + A mini-HOWTO (PDF file) about scanning and virus scanning, and some RPMs + can be found at \?http://www.timj.co.uk/linux/exim.php?\. + + + +2. ROUTING IN GENERAL + +Q0201: How can I arrange that messages larger than some limit are handled by + a special router? + +A0201: You can use a \condition\ option on the router line this: + +==> condition = ${if >{$message_size}{100K}{yes}{no}} + + +Q0202: Can I specify a list of domains to explicitly reject? + +A0202: Set up a named domain list containing the domains in the first section + of the configuration, for example: + +==> domainlist reject_domains = list:of:domains:to:reject + + You can use this list in an ACL to reject any SMTP recipients in those + domains. You can also give a customized error message, like this: + +==> deny message = The domain $domain is no longer supported + domains = +reject_domains + + If you also want to reject these domains in messages that are submitted + from the command line (not using SMTP), you need to set up a router to + do it, like this: + +==> reject_domains: + driver = redirect + domains = +reject_domains + allow_fail + data = :fail: The domain $domain is no longer supported + + +Q0203: How can I arrange to do my own qualification of non-fully-qualified + domains, and then pass them on to the next router? + +A0203: If you have some list of domains that you want to qualify, you can do + this using a redirect router. For example, + +==> qualify: + driver = redirect + domains = *.a.b + data = ${quote:$local_part}@$domain.c.com + + This adds \".c.com"\ to any domain that matches \"*.a.b"\. + If you want to do this in conjunction with a \%dnslookup%\ router, the + \widen_domains\ option of that router may be another way of achieving + what you want. + + +Q0204: Every system has a \"nobody"\ account under which httpd etc run. I would + like to know how to restrict mail which comes from that account to users + on that host only. + +A0204: Set up a first router like this: + +==> fail_nobody: + driver = redirect + senders = nobody@your.domain + domains = ! +local_domains + allow_fail + data = :fail: Nobody may not mail off-site + + This assumes you have defined \+local_domains\ as in the default + configuration. + + +Q0205: How can I get Exim to deliver to me locally and everyone else at the same + domain via SMTP to the MX record specified host? + +A0205: Create an \%accept%\ router to pick off the one address and pass it to + an appropriate transport. Put this router before the one that does MX + routing: + +==> me: + driver = accept + domains = dom.com + local_parts = me + transport = local_delivery + + In the transport you will have to specify the \user\ option. An + alternative way of doing this is to add a condition to the router that + does MX lookups to make it skip your address. Subsequent routers can then + deliver your address locally. You'll need a condition like this: + +==> condition = \ + ${if and {{eq{$domain}{dom.com}}{eq{$local_part}{me}}}{no}{yes}} + + +Q0206: How can I get Exim to deliver certain domains to a different SMTP port + on my local host? + +A0206: You must set up a special \%smtp%\ transport, where you can specify the + \port\ option, and then set up a router to route the domains to that + transport. There are two possibilities for specifying the host: + + (1) If you use a \%manualroute%\ router, you can specify the local host + in the router options. You must also set + +==> self = send + + so that it does not object to sending to the local host. + + (2) If you use a router that cannot specify hosts (for example, an + \%accept%\ router with appropriate conditions), you have to specify + the host using the \hosts\ option of the transport. In this case, + you must also set \allow_localhost\ on the transport. + + +Q0207: Why does Exim lower-case the local-part of a non-local domain when + routing? + +A0207: Because \caseful_local_part\ is not set (in the default configuration) + for the \%dnslookup%\ router. This does not matter because the local + part takes no part in the routing, and the actual local part that is + sent out in the RCPT command is always the original local part. + + + +3. ROUTING TO REMOTE HOSTS + +Q0301: What do \*lowest numbered MX record points to local host*\ and \*remote + host address is the local host*\ mean? + +A0301: They mean exactly what they say. Exim expected to route an address to a + remote host, but the IP address it obtained from a router was for the + local host. If you really do want to send over TCP/IP to the local host + (to a different version of Exim or another MTA, for example), see Q0206. + + More commonly, these errors arise when Exim thinks it is routing some + foreign domain. For example, the router configuration causes Exim to + look up the domain in the DNS, but when Exim examines the DNS output, + either the lowest numbered MX record points at the local host, or there + are no MX records, and the address record for the domain contains an + IP address that belongs to the local host. + + There has been a rash of instances of domains being deliberately set up + with MX records pointing to \"localhost"\ (or other names with A records + that specify 127.0.0.1), which causes this behaviour. You can use the + \ignore_target_hosts\ option to get Exim to ignore these records. The + default contiguration does this. For more discussion, see Q0319. For + other cases: + + (1) If the domain is meant to be handled as a local domain, there + is a problem with the configuration, because it should not then have + been looked up in the DNS. Check the \domains\ settings on your + routers. + + (2) If the domain is one for which the local host is providing a + relaying service (called ``mail hubbing''), possibly as part of a + firewall, you need to set up a router to tell Exim where to send + messages addressed to this domain, because the DNS directs them to + the local host. You should put a router like this one before the one + that does DNS lookups: + +==> hubbed_hosts: + driver = manualroute + transport = remote_smtp + route_list = see discussion below + + The contents of the \route_list\ option depend on how many hosts you + are hubbing for, and how their names are related to the domain name. + Suppose the local host is a firewall, and all the domains in + \(*.foo.bar)\ have MX records pointing to it, and each domain + corresponds to a host of the same name. Then the setting could be + +==> route_list = *.foo.bar $domain + + If there isn't a convenient relationship between the domain names + and the host names, you either have to list each domain separately, + or use a lookup expansion to look up the host from the domain, or + put the routing information in a file and use the \route_data\ + option with a lookup expansion. + + (3) If neither (1) nor (2) is the case, the lowest numbered MX record or + the address record for the domain should not be pointing to your + host. You should arrange to get the DNS mended. + + +Q0302: Why does Exim say \*all relevant MX records point to non-existent hosts*\ + when MX records point to IP addresses? + +A0302: MX records cannot point to IP addresses. They are defined to point to + host names, so Exim always interprets them that way. (An IP address is a + syntactically valid host name.) The DNS for the domain you are having + problems with is misconfigured. + + However, it appears that more and more DNS zones are breaking the rules + and putting IP addresses on the RHS of MX records. Exim follows the + rules and rejects this, but other MTAs do support it, so the + \allow_mx_to_ip\ was regretfully added at release 3.14 to permit this + heinous activity. + + +Q0303: How do I configure Exim to send all messages to a central server? I + don't want to do any local deliveries at all on this host. + +A0303: Use this as your first and only router: + +==> send_to_gateway: + driver = manualroute + transport = remote_smtp + route_list = * central.server.host + + +Q0304: How do I configure Exim to send all non-local mail to a gateway host? + +A0304: Replace the \%dnslookup%\ router in the default configuration with the + following: + +==> send_to_gateway: + driver = manualroute + domains = !+local_domains + transport = remote_smtp + route_list = * gate.way.host + + If there are several hosts you can send to, you can specify them as a + colon-separated list. + + +Q0305: How can I arrange for mail on my local network to be delivered directly + to the relevant hosts, but all other mail to be sent to my ISP's mail + server? The local hosts are all DNS-registered and behave like normal + Internet hosts. + +A0305: Set up a first router to pick off all the domains for your local + network. There are several ways you might do this. For example + +==> local_network: + driver = dnslookup + transport = remote_smtp + domains = *.mydomain.com + + This does a perfectly conventional DNS routing operation, but only for + the domains that match \(*.mydomain.com)\. Follow this with a `smart + host' router: + +==> internet: + driver = manualroute + domains = !+local_domains + transport = remote_smtp + route_list = * mail.isp.net + + This routes any other non-local domains to the smart host. + + +Q0306: How do I configure Exim to send all non-local mail to a central server + if it cannot be immediately delivered by my host? I don't want to have + queued mail waiting on my host. + +A0306: Add to the \%remote_smtp%\ transport the following: + +==> fallback_hosts = central.server.name(s) + + If there are several names, they must be separated by colons. + + +Q0307: The \route_list\ setting \"^foo$:^bar$ $domain"\ in a \%manualroute%\ + router does not work. + +A0307: The first thing in a \route_list\ item is a single pattern, not a list of + patterns. You need to write that as \"^(foo|bar)$ $domain"\. + Alternatively, you could use several items and write + +==> route_list = foo $domain; bar $domain + + Note the semicolon separator. This is because the second thing in each + item can itself be a list - of hosts. + + +Q0308: I have a domain for which some local parts must be delivered locally, + but the remainder are to be treated like any other remote addresses. + +A0308: One possible way of doing this is as follows: Assuming you are using a + configuration that is similar to the default one, first exclude your + domain from the first router by changing it to look like this: + +==> non_special_remote: + driver = dnslookup + domains = ! +local_domains : ! special.domain + transport = remote_smtp + ignore_target_hosts = 127.0.0.0/8 + no_more + + Then add a second router which handles the local parts that are not to + be delivered locally: + +==> special_remote: + driver = dnslookup + domains = special.domain + local_parts = ! lsearch;/list/of/special/localparts + transport = remote_smtp + ignore_target_hosts = 127.0.0.0/8 + no_more + + The remaining local parts will fall through to the remaining routers, + which can delivery them locally. + + +Q0309: How can I configure Exim on a firewall machine so that if mail arrives + addressed to a domain whose MX points to the firewall, it is forwarded + to the internal mail server, without having to have a list of all the + domains involved? + +A0309: As your first router, have the standard \%dnslookup%\ router from the + default configuration, with the added option + +==> self = pass + + This will handle all domains whose lowest numbered MX records do not + point to your host. Because of the \no_more\ setting, if it encounters + an unknown domain, routing will fail. However, if it hits a domain whose + lowest numbered MX points to your host, the \self\ option comes into + play, and overrides \no_more\. The \"pass"\ setting causes it to pass + the address on to the next router. (The default causes it to generate an + error.) + + The only non-local domains that reach the second router are those with + MX records pointing to the local host. Set it up to send them to the + internal mail server like this: + +==> internal: + driver = manualroute + domains = ! +local_domains + transport = remote_smtp + route_list = * internal.server + + +Q0310: If a DNS lookup returns no MX records why doesn't Exim just bin the + message? + +A0310: If a DNS lookup returns no MXs, Exim looks for an address record, in + accordance with the rules that are defined in the RFCs. If you want to + break the rules, you can set \mx_domains\ in the \%dnslookup%\ router, but + you will cut yourself off from those sites (and there still seem to be + plenty) who do not set up MX records. + + +Q0311: When a DNS lookup for MX records fails to complete, why doesn't Exim + send the messsage to the host defined by the A record? + +A0311: The RFCs are quite clear on this. Only if it is known that there are no + MX records is an MTA allowed to make use of the A record. When an MX + lookup fails to complete, Exim does not know whether there are any MX + records or not. There seem to be some name servers (or some + configurations of some name servers) that give a ``server fail'' error when + asked for a non-existent MX record. Exim uses standard resolver calls, + which unfortunately do not distinguish between this case and a timeout, + so all Exim can do is try again later. + + +Q0312: Is it possible to use a conditional expression for the host item in a + \route_list\ for \%manualroute%\ router? I tried the following, but it + doesn't work: + +==> route_list = * ${if match{$header_from:}{\N.*\.usa\.net$\N} \ + {<smarthost1>}{<smarthost2>} + +A0312: The problem is that the second item in \route_list\ contains white + space, which means that it gets terminated prematurely. To avoid this, + you must put the second item in quotes: + +==> route_list = * "${if match{$header_from:}{\N.*\.usa\.net$\N} \ + {<smarthost1>}{<smarthost2>}}" + + +Q0313: I send all external mail to a smart host, but this means that bad + addresses also get passed to the smart host. Can I avoid this? + +A0313: Assuming you have DNS availability, set up a conventional \%dnslookup%\ + router to do the routing, but in the \%remote_smtp%\ transport set this: + +==> hosts = your.smart.host + hosts_override + + This will override the hosts that the router finds so that everything + goes to the smart host, but any non-existent domains will be failed by + the router. + + +Q0314: I have a really annoying intermittent problem where attempts to mail to + valid sites are rejected with \*unknown mail domain*\. This only happens a + few times a day and there is no particular pattern to the sites it + rejects. If I try to lookup the same domain a few minutes later then it + is OK. + +A0314: This is almost certainly a problem with the DNS resolver or the the + domain's name servers. + + (1) Have you linked Exim against the newest DNS resolver library that + comes with Bind? If you are using SunOS4 that may be your problem, as + the resolver that comes with that OS is known to be buggy and to give + intermittent false negatives. + + (2) Effects like this are sometimes seen if a domain's name servers get + out of step with each other. + + +Q0315: I'd like route all mail with addresses that can't be resolved (the DNS + lookup times out) to a relay machine. + +A0315: Set \pass_on_timeout\ on your \%dnslookup%\ router, and add below it a + \%manualroute%\ router that routes all relevant domains to the relay. + + +Q0316: I would like to forward all incoming email for a particular domain to + another host via SMTP. Whereabouts would I configure that? + +A0316: Use this as your first router: + +==> special: + driver = manualroute + transport = remote_smtp + route_list = the.particular.domain the.other.host + + You will also need to adjust the ACL for incoming SMTP so that this + domain is accepted for relaying. If you are using the default + configuration, there is a domain list called \relay_domains\ that is + set up for this. + + +Q0317: What I'd like to do is have alternative smart hosts, where the one to be + used is determined by which ISP I'm connected to. + +A0317: The simplest way to do this is to arrange for the name of the smart host + du jour to be placed in a file when you connect, say \(/etc/smarthost)\. + Then you can read this file from a \%manualroute%\ router like this: + +==> smarthost: + driver = manualroute + transport = remote_smtp + route_list = * ${readfile{/etc/smarthost}{}} + + The second argument of the \"readfile"\ item is a string that replaces + any newline characters in the file (in this case, with nothing). + By keeping the data out of the main configuration file, you avoid having + to HUP the daemon when it changes. + + +Q0318: Exim won't route to a host with no MX record. + +A0318: More than one thing may cause this. + + (1) Are you sure there really is no MX record? Sometimes a typo results + in a malformed MX record in the zone file, in which case some name + servers give a SERVFAIL error rather than NXDOMAIN. Exim has to treat + this as a temporary error, so it can't go on to look for address records. + You can check for this state using one of the DNS interrogation commands, + such as \(nslookup)\, \(host)\, or \(dig)\. + + (2) Is there a wildcard MX record for \(your)\ domain? Is the + \search_parents\ option on in your \%dnslookup%\ router? If the answer to + both these questions is ``yes'', that is the cause of the problem. When + the DNS resolver fails to find the MX record, it tries adding on your + domain if \search_parents\ is true, and thereby finds your wildcard MX + record. For example: + + . There is a wildcard MX record for \(*.a.b.c)\. + + . There is a host called \(x.y.z)\ that has an A record and no MX record. + + . Somebody on the host \(m.a.b.c)\ domain tries to mail to \(user@x.y.z)\. + + . Exim calls the DNS to look for an MX record for \(x.y.z)\. + + . The DNS doesn't find any MX record. Because \search_parents\ is true, + it then tries searching the current host's parent domain, so it + looks for \(x.y.z.a.b.c)\ and picks up the wildcard MX record. + + Setting \search_parents\ false makes this case work while retaining the + wildcard MX record. However, anybody on the host \(m.a.b.c)\ who mails to + \(user@n.a)\ (expecting it to go to \(user@n.a.b.c)\) now has a problem. The + \widen_domains\ option of the \%dnslookup%\ router may be helpful in this + circumstance. + + +Q0319: I have some mails on my queues that are sticking around longer than + the retry time indicates they should. They are all getting frozen + because some remote admin has set their MX record to 127.0.0.1. + +A0319: The admin in question is an idiot. Exim will always freeze such messages + because they are apparently routed to the local host. To bounce these + messages immediately, set + +==> ignore_target_hosts = 127.0.0.1 + + on the \%dnslookup%\ router. This causes Exim to completely ignore any hosts + with that IP address. In fact, there are quite a number of IP addresses + that should never be used. Here is a suggested configuration list for + the IPv4 ones: + +==> # Don't allow domains whose single MX (or A) record is a + # "special-use IPv4 address", as listed in RFC 3330. + ignore_target_hosts = \ + # Hosts on "this network"; RFC 1700 (page 4) states that these + # are only allowed as source addresses + 0.0.0.0/8 : \ + # Private networks, RFC 1918 + 10.0.0.0/8 : 172.16.0.0/12 : 192.168.0.0/16 : \ + # Internet host loopback address, RFC 1700 (page 5) + 127.0.0.0/8 : \ + # "Link local" block + 169.254.0.0/16 : \ + # "TEST-NET" - should not appear on the public Internet + 192.0.2.0/24 : \ + # 6to4 relay anycast addresses, RFC 3068 + 192.88.99.0/24 : \ + # Network interconnect device benchmark testing, RFC 2544 + 198.18.0.0/15 : \ + # Multicast addresses, RFC 3171 + 224.0.0.0/4 : \ + # Reserved for future use, RFC 1700 (page 4) + 240.0.0.0/4 + + +Q0320: How can I arrange for all mail to \*user@some.domain*\ to be forwarded + to \*user@other.domain*\? + +A0320: Put this as your first router: + +==> forward: + driver = redirect + domains = some.domain + data = ${quote:$local_part}@other.domain + + +Q0321: How can I tell an Exim router to use only IPv4 or only IPv6 addresses + when it finds both types in the DNS? + +A0321: You can do this by making it ignore the addresses you don't want. This + example ignores all IPv6 addresses and all IPv4 addresses in the 127 + network: + +==> ignore_target_hosts = <; 0000::0000/0 ; 127.0.0.0/8 + + To ignore all IPv4 addresses, use + +==> ignore_target_hosts = 0.0.0.0/0 + + See Q0319 for a general discussion of \ignore_target_hosts\. + + +Q0322: How can I reroute all messages bound for 192.168.10.0 and 10.0.0.0 to + a specific mail server? + +A0322: That is an odd requirement. However, there is an obscure feature in + Exim, originally implemented for packet radio people, that perhaps can + help. Check out the \translate_ip_address\ generic router option. + + + +4. ROUTING FOR LOCAL DELIVERY + +Q0401: I need to have any mail for \(virt.dom.ain)\ that doesn't match one of the + aliases in \(/usr/lib/aliases.virt)\ delivered to a particular address, for + example, \(postmaster@virt.dom.ain)\. + +A0401: Adding an asterisk to a search type causes Exim to look up ``*'' when the + normal lookup fails. So if your aliasing router is something like this: + +==> virtual: + driver = redirect + domains = virt.dom.ain + data = ${lookup{$local_part}lsearch{/usr/lib/aliases.virt}} + no_more + + you should change \"lsearch"\ to \"lsearch*"\, and put this in the alias + file: + +==> *: postmaster@virt.dom.ain + + This solution has the feature that if there are several unknown + addresses in the same message, only one copy gets sent to the + postmaster, because of Exim's normal de-duplication rules. + + NOTE: This solution works only if there is also an entry for \(postmaster)\ + in the alias file, ultimately resolving to an address that is not in + \(virt.dom.ain)\. See also Q0434. + + +Q0402: How do I arrange for all incoming email for \(*@some.domain)\ to go into one + pop3 mail account? The customer doesn't want to add a list of specific + local parts to the system. + +A0402: Set up a special transport that writes to the mailbox like this: + +==> special_transport: + driver = appendfile + file = /pop/mailbox + envelope_to_add + return_path_add + delivery_date_add + user = exim + + The file will be written as the user \"exim"\. Then arrange to route all + mail for that domain to that transport, with a router like this: + +==> special_router: + driver = accept + domains = some.domain + transport = special_transport + + +Q0403: How do I configure Exim to send messages for unknown local users to a + central server? + +A0403: Assuming you are using something like the default configuration, where + local users are processed by the later routers, you should add the + following router at the end: + +==> unknown: + driver = manualroute + transport = remote_smtp + route_list = * server.host.name + no_verify + + However, you should if possible try to verify that the user is known on + the central server before accepting the message in the first place. This + can be done by making use of Exim's ``call forward'' facility. + + +Q0404: How can I arrange for messages submitted by (for example) Majordomo to + be handled specially? + +A0404: You can use the \condition\ option on a router, with a setting such as + +==> condition = ${if and {{eq {$sender_host_address}{}} \ + {eq {$sender_ident}{majordom}}} {yes}{no}} + + This first tests for a locally-submitted message, by ensuring there is + no sending host address, and then it checks the identity of the user + that ran the submitting process. + + +Q0405: On a host that accepts mail for several domains, do I have to use fully + qualified addresses in \(/etc/aliases)\ or do I have to set up an alias + file for each domain? + +A0405: You can do it either way. The default aliasing router contains this line: + +==> data = ${lookup{$local_part}lsearch{/etc/aliases}} + + which is what does the actual lookup. To make it look up the complete + address instead of just the local part, use + +==> data = ${lookup{$local_part@$domain}lsearch{/etc/aliases}} + + If you want to use a separate file for each domain, use + +==> data = ${lookup{$local_part}lsearch{/etc/aliases/$domain}} + + +Q0406: Some of my users are using the \(.forward)\ to pipe to a shell command which + appends to the user's INBOX. How can I forbid this? + +A0406: If you allow your users to run shells in pipes, you cannot control which + commands they run or which files they write to. However, you should point + out to them that writing to an INBOX by arbitrary commands is not + interlocked with the MTA and MUAs, and is liable to mess up the contents + of the file. + + If a user simply wants to choose a specific file for the delivery of + messages, this can be done by putting a file name in a \(.forward)\ file + rather than using a pipe, or by using the \"save"\ command in an Exim + filter file. + + You can set \forbid_pipe\ on the router, but that will prevent them from + running any pipe commands at all. Alternatively, you can restrict which + commands they may run in their pipes by setting the \allow_commands\ + and/or \restrict_to_path\ options in the \%address_pipe%\ transport. + + +Q0407: How can I arrange for a default value when using a query-style lookup + such as LDAP or NIS+ to handle aliases? + +A0407: Use a second query in the failure part of the original lookup, like + this: + +==> data = ${lookup ldap\ + {ldap://x.y.z/l=yvr?aliasaddress?sub?(&(mail=$local_part@$domain))}\ + {$value}\ + {\ + ${lookup ldap \ + {ldap://x.y.z/l=yvr?aliasaddress?sub?(&(mail=default@$domain))}}\ + }} + + Of course, if the default is a fixed value you can just include it + directly. + + +Q0408: If I don't fully qualify the addresses in a virtual domain's alias file + then mail to aliases which also match the local domain get delivered to + the local domain. + +A0408: Set the \qualify_preserve_domain\ option on the \%redirect%\ router. + + +Q0409: I want mail for any local part at certain virtual domains to go + to a single address for each domain. + +A0409: One way to to this is + +==> virtual: + driver = redirect + data = ${lookup{$domain}lsearch{/etc/virtual}} + + The \(/etc/virtual)\ file contains a list of domains and the addresses to + which their mail should be sent. For example: + +==> domain1: postmaster@some.where.else + domain2: joe@xyz.plc + + If the number of domains is large, using a DBM or cdb file would be more + efficient. If the lookup fails to find the domain in the file, the value + of the \data\ option is empty, causing the router to decline. + + +Q0410: How can I make Exim look in the alias NIS map instead of \(/etc/aliases)\? + +A0410: The default configuration does not use NIS (many hosts don't run it). + You need to change this line in the \%system_aliases%\ router: + +==> data = ${lookup{$local_part}lsearch{/etc/aliases}} + + Change it to + +==> data = ${lookup{$local_part}nis{mail.aliases}} + + If you want to use \(/etc/aliases)\ as well as NIS, put this router (with + a different name) before or after the default one, depending on which + data source you want to take precedence. + + +Q0411: Why will Exim deliver a message locally to any username that is longer + than 8 characters as long as the first 8 characters match one of the + local usernames? + +A0411: The problem is in your operating system. Exim just calls the \^^getpwnam()^^\ + function to test a local part for being a local login name. It does not + presume to guess the maximum length of user name for the underlying + operating system. Many operating systems correctly reject names that are + longer than the maximum length; yours is apparently deficient in this + regard. To cope with such systems, Exim has an option called + \max_user_name_length\ which you can set to the maximum allowed length. + + +Q0412: Why am I seeing the error \*bad mode (100664) for /home/test/.forward*\? + I've looked through the documentation but can't see anything to suggest + that Exim has to do anything other than read the \(.forward)\ file. + +A0412: For security, Exim checks for mode bits that shouldn't be set, by + default 022. You can change this by setting the \modemask\ option of the + \%redirect%\ router that is handling \(.forward)\ files. + + +Q0413: When a user's \(.forward)\ file is syntactially invalid, Exim defers + delivery of all messages to that user, which sometimes include the + user's own test messages. Can it be told to ignore the \(.forward)\ file + and/or inform the user of the error? + +A0413: Setting \skip_syntax_errors\ on the redirect router causes syntax + errors to be skipped. When dealing with users' \(.forward)\ files it is best + to combine this with a setting of \syntax_errors_to\ in order to send + a message about the error to the user. However, to avoid an infinite + cascade of messages, you have to be able to send to an address that + bypasses \(.forward)\ file processing. This can be done by including a + router like this one + +==> real_localuser: + driver = accept + check_local_user + transport = local_delivery + prefix = real- + + before the \%redirect%\ router that handles \(.forward)\ files. This will + do an ordinary local delivery without \(.forward)\ processing, if the + local part is prefixed by \"real-"\. You can then set something like + the following options on the \%redirect%\ router: + +==> skip_syntax_errors + syntax_errors_to = real-$local_part@$domain + syntax_errors_text = "\ + This is an automatically generated message. An error has been \ + found\nin your .forward file. Details of the error are reported \ + below. While\nthis error persists, messages addressed to you will \ + get delivered into\nyour normal mailbox and you will receive a \ + copy of this message for\neach one." + + A final tidying setting to go with this is a rewriting rule that changes + \"real-username"\ into just \"username"\ in the headers of the message: + +==> \N^real-([^@]+)@your\.dom\.ain$\N $1@your.dom.ain h + + This means that users won't ever see the \"real-"\ prefix, unless they + look at the ::Envelope-To:: header. + + +Q0414: I have set \caseful_local_part\ on the routers that handle my local + domain because my users have upper case letters in their login names, + but incoming mail now has to use the correct case. Can I relax this + somehow? + +A0414: If you really have to live with caseful user names but want incoming + local parts to be caseless, then you have to maintain a file, indexed by + the lower case forms, that gives the correct case for each login, like + this: + +==> admin: Admin + steven: Steven + mcdonald: McDonald + lamanch: LaManche + ... + + and at the start of the routers that handle your local domain, put one + like this: + +==> set_case_router: + driver = redirect + data = ${lookup{${lc:$local_part}}lsearch{/the/file}} + qualify_preserve_domain + + For efficiency, you should also set the \redirect_router\ option to cause + processing of the changed address to begin at the next router. If you + are otherwise using the default configuration, the setting would be + +==> redirect_router = system_aliases + + If there are lots of users, then a DBM or cdb file would be more + efficient than a linear search. If you are handling several domains, + you will have to extend this configuration to cope appropriately. + + +Q0415: Can I use my existing alias files and forward files as well as procmail + and effectively drop in Exim in place of Sendmail ? + +A0415: Yes, as long as your alias and forward files don't assume that pipes are + going to run under a shell. If they do, you either have to change them, + or configure Exim to use a shell (which it doesn't by default). + + +Q0416: What is quickest way to set up Exim so any message sent to a + non-existing user would bounce back with a different message, based + on the name of non-existing user? + +A0416: Place this router last, so that it catches any local addresses that + are not otherwise handled: + +==> non_exist: + driver = accept + transport = non_exist_reply + no_verify + + Then add the following transport to the transports section: + +==> non_exist_reply: + driver = autoreply + user = exim + to = $sender_address + subject = User does not exist + text = You sent mail to $local_part. That's not a valid user here. \ + The subject was: $subject. + + If you want to pick up a message from a file, you can use the \file\ + option (use \file_expand\ if you want its contents expanded). + + +Q0417: What do I need to do to make Exim handle \(/usr/ucb/vacation)\ processing + automatically, so that people could just create a \(.vacation.msg)\ file in + their home directory and not have to edit their \(.forward)\ file? + +A0417: Add a new router like this, immediately before the normal \%localuser%\ + router: + +==> vacation: + driver = accept + check_local_user + require_files = $home/.vacation.msg + transport = vacation_transport + unseen + + and a matching new transport like this: + +==> vacation_transport: + driver = pipe + command = /usr/ucb/vacation $local_part + + However, some versions of \(/usr/ucb/vacation)\ do not work properly unless + the DBM file(s) it uses are created in advance - it won't create them + itself. You also need a way of removing them when the vacation is over. + + Another possibility is to use a fixed filter file which is run whenever + \(.vacation.msg)\ exists, for example: + +==> vacation: + driver = redirect + check_local_user + require_files = $home/.vacation.msg + file = /some/central/filter + allow_filter + + The filter file should use the \"if personal"\ check before sending mail, + to avoid generating automatic responses to mailing lists. If sending a + message is all that it does, this doesn't count as a ``significant'' + delivery, so the original message goes on to be delivered as normal. + + Yet another possibility is to make use of Exim's \%autoreply%\ transport, + and not use \(/usr/ucb/vacation)\ at all. + + +Q0418: I want to use a default entry in my alias file to handle unknown local + parts, but it picks up the local parts that the aliases generate. For + example, if the alias file is + +==> luke.skywalker: luke + ls: luke + *: postmaster + + then messages addressed to \/luke.skywalker/\ end up at \/postmaster/\. + +A0418: The default mechanism works best with virtual domains, where the + generated address is not in the same domain. If you just want to pick up + all unknown local parts and send them to postmaster, an easier way to do + it is to put this as your last router: + +==> unknown: + driver = redirect + data = postmaster + no_verify + + Another possibility is to put the redirect router for these aliases + after all the other routers, so that local parts which are user names + get picked off first. You will need to have two aliasing routers if + there are some local parts (e.g. \/root/\) which are login names, but which + you want to handle as aliases. + + +Q0419: I have some obsolete domains which people have been warned not to use + any more. How can I arrange to delete any mail that is sent to them? + +A0419: To reject them at SMTP time, with a customized error message, place + statments like this in the ACL: + +==> deny message = The domain $domain is obsolete + domains = lsearch;/etc/exim/obsolete.domains + + For messages that don't arrive over SMTP, you can use a router like + this to bounce them: + +==> obsolete: + driver = redirect + domains = lsearch;/etc/exim/obsolete.domains + allow_fail + data = :fail: the domain $domain is obsolete + + If you just want to throw away mail to those domains, accept them at + SMTP time, and use a router like this: + +==> obsolete: + domains = lsearch;/etc/exim/obsolete.domains + data = :blackhole: + + +Q0420: How can I arrange that mail addressed to \(anything@something.mydomain.com)\ + gets delivered to \(something@mydomain.com)\? + +A0420: Set up a router like this: + +==> user_from_domain: + driver = redirect + data = ${if match{$domain}{\N^(.+)\.mydomain\.com$\N}\ + {$1@mydomain.com}} + + +Q0421: I can't get a regular expression to work in a \local_parts\ option on + one of my routers. + +A0421: Have you remembered to protect any backslash and dollar characters in + your regex from unwanted expansion? The easiest way is to use the + \"@\N"\ facility, like this: + +==> local_parts = \N^0740\d{6}\N + + +Q0422: How can I arrange for all addresses in a group of domains \(*.example.com)\ + to share the same alias file? I have a number of such groups. + +A0422: For a single group you could just hard wire the file name into a router + that had + +==> domains = *.example.com + + set, to restrict it to the relevant domains. For a number of such groups + you can create a file containing the domains, like this: + +==> *.example1.com example1.com + *.example2.com example2.com + ... + + Then create a router like this + +==> domain_aliases: + driver = redirect + domains = partial-lsearch;/that/file + data = ${lookup{$local_part}lsearch*{/etc/aliases.d/$domain_data}} + + The variable \$domain_data$\ contains the data that was looked up when the + \domains\ option was matched, i.e. \"example1.com"\, \"example2.com"\, etc. + in this case. + + +Q0423: Some of our users have no home directories; the field in the password + file contains \(/no/home/dir)\. This causes the error \*failed to stat + /no/home/dir (No such file or directory)*\ when Exim tries to look for a + \(.forward file)\, and the delivery is deferred. + +A0423: There are two issues involved here: + + (1) With the default configuration, you are asking Exim to check for a + \(.forward)\ file in the user's home directory. If no file is found, + Exim tries to \^^stat()^^\ the home directory. This is so that it will + notice a missing NFS home directory, and not treat it as if the + \(.forward)\ file did not exist. This \^^stat()^^\ is failing when the + home directory really doesn't exist. You should arrange for the + \%userforward%\ router not to run for these special users, by adding + this line: + +==> condition = ${if eq {$home}{/no/home/dir}{no}{yes}} + + (2) If you use \check_local_user\ on another router to route to a local + transport (again, this is what is in the default configuration), you + will also have to specify a current directory for the transport, because + by default it makes the home directory current. This is easily done by + adding + +==> current_directory = / + + to the transport or + +==> transport_current_directory = / + + to the router. Or you can add \home_directory\ to the transport, because + the current directory defaults to the home directory. + + +Q0424: How can I disable Exim's de-duplication features? I want it to do two + deliveries if two different aliases expand to the same address. + +A0424: This is not possible. Duplication has other ramifications other than + just (in)convenience. Consider: + + . Message is addressed to A and to B. + + . Both A and B are aliased to C. + + . Without de-duplication, two deliveries to C are scheduled. + + . One delivery happens, Exim records that it has delivered the message + to C. + + . The next delivery fails (C's mailbox is over quota, say). + + Next time round, Exim wants to know if it has already delivered to C or + not, before scheduling a new delivery. Has it? Obviously, if duplicate + deliveries are supported, it has to remember not only that it has + delivered to C but also the ``history'' of how that delivery happened - in + effect an ancestry list back to the original envelope address. This it + does not do, and changing it to work in that way would be a lot of work + and a big upheaval. + + The best way to get duplicate deliveries if you want them is not to use + aliases, but to route the addresses directly to a transport, e.g. + +==> duplicates: + driver = accept + local_parts = lsearch;/etc/list/of/special/local/parts + transport = local_delivery + user = exim + + +Q0425: My users' mailboxes are distributed between several servers according to + the first letter of the user name. All the servers receive incoming mail + at random. I would like to have the same configuration file for all the + servers, which does local delivery for the mailboxes it holds, and sends + other addresses to the correct other server. Is this possible? + +A0425: It is easiest if you arrange for all the users to have password entries + on all the servers. This means that non-existent users can be detected + at the first server they reach. Set up a file containing a mapping from + the first letter of the user names to the servers where their mailboxes + are held. For example: + +==> a: server1 + b: server1 + c: server2 + ... + + Before the normal \%localuser%\ router, place the following router: + +==> mailbox_host: + driver = manualroute + check_local_user + transport = remote_smtp + route_list = * ${lookup{${substr_0_1:$local_part}}lsearch{/etc/mapfile}} + self = pass + + This router checks for a local account, then looks up the host from the + first character of the local part. If the host is not the local host, + the address is routed to the \%remote_smtp%\ transport, and sent to the + correct host. If the host is the local host, the \self\ option causes + the router to pass the address to the next router, which does a local + delivery. + + The router is skipped for local parts that are not the names of local + users, and so these addresses fail. + + +Q0426: One of the things I want to set up is for \(anything@onedomain)\ to forward + to \(anything@anotherdomain)\. I tried adding \($local_part@anotherdomain)\ to + my aliases but it did not expand - it sent it to that literal address. + +A0426: If you want to do it that way, you can use the \"expand"\ operator on + the lookup used in the data option of the redirect router. For example: + +==> data = ${expand:${lookup{$local_part}lsearch*{/etc/aliases}}} + + Another approach is to use a router like this: + +==> forwarddomain: + driver = redirect + domains = onedomain + data = $local_part@anotherdomain + + The value of \data\ can, of course, be more complicated, involving + lookups etc. if you have lots of different cases. + + +Q0427: How can I have an address looked up in two different alias files, and + delivered to all the addresses that are found? + +A0427: Use a router like this: + +==> multi_aliases: + driver = redirect + data = ${lookup{$local_part}lsearch{/etc/aliases1}\ + {$value${lookup{$local_part}lsearch{/etc/aliases2}{,$value}}}\ + {${lookup{$local_part}lsearch{/etc/aliases2}{$value}fail}}}\ + + If the first lookup succeeds, the result is its data, followed by the + data from the second lookup, if any, separated by a comma. If the first + lookup fails, the result is the data from the third lookup (which also + looks in the second file), but if this also fails, the entire expansion + is forced to fail, thereby causing the router to decline. + + Another approach is to use two routers, with the first re-generating the + original local part when it succeeds. This won't get processed by the + same router again. For example: + +==> multi_aliases1: + driver = redirect + data = ${lookup{$local_part}lsearch{/etc/aliases1}{$value,$local_part}} + +==> multi_aliases2: + data = ${lookup{$local_part}lsearch{/etc/aliases2}} + + This scales more easily to three or more alias files. + + +Q0428: I've converted from Sendmail, and I notice that Exim doesn't make use + of the \"owner-"\ entries in my alias file to change the sender address in + outgoing messages to a mailing list. + +A0428: If you have an alias file with entries like this: + +==> somelist: a@b, c@d, ... + owner-somelist: postmaster + + Sendmail assumes that the second entry specifies a new sender address + for the first. Exim does not make this assumption. However, you can make + it take the same action, by adding + +==> errors_to = owner-$local_part@whatever.domain + + to the configuration for your aliasing router. This is fail-safe, + because Exim verifies a new sender address before using it. Thus, the + change of sender address occurs only when the owner entry exists. + + +Q0429: I would like to deliver mail addressed to a given domain to local + mailboxes, but also to generate messages to the envelope senders. + +A0429: You can do this with an ``unseen'' router and an \%autoreply%\ transport, + along the following lines: + +==> # Router + auto_warning_r: + driver = accept + check_local_user + domains = <domains you want to do this for> + condition = ${if eq{$sender_address}{}{no}{yes}} + transport = warning_t + no_verify + unseen + + Place this router immediately before the normal \%localuser%\ router. The + \unseen\ option means that the address is still passed on to the next + router. The transport is configured like this: + +==> # Transport + warning_t: + driver = autoreply + file = /usr/local/mail/warning.txt + file_expand + from = postmaster@your.domain + to = $sender_address + user = exim + subject = Re: Your mail to $local_part@$domain + + Note the use of the \condition\ option to avoid attempting to send a + message when there is no sender (that is, when the incoming message is a + bounce message). You can of course extend this to include other + conditions. If you want to log the sending of messages, you can add + +==> log = /some/file + + to the transport and also make use of the \once\ option if you want to + send only one message to each sender. + + +Q0430: Whenever Exim tries to route a local address, it gives a permission + denied error for the \(.forward)\ file, like this: + +==> 1998-08-10 16:55:32 0z5y2W-0000B8-00 == xxxx@yyy.zzz <xxxx@yyy.zz> + D=userforward defer (-1): failed to open /home/xxxx/.forward + (userforward router): Permission denied (euid=1234 egid=101) + +A0430: Have you remembered to make Exim setuid \/root/\? + + +Q0431: How do I configure Exim to allow arbitrary extensions in local parts, of + the form \/+extension/\? + +A0431: Add this pre-condition to the relevant router: + +==> local_part_suffix = +* + + If you want the extensions to be optional, also add the option + +==> local_part_suffix_optional + + When the router runs, \$local_part$\ contains the local part with the + extension removed, and the extension (if any) is in \$local_part_suffix$\. + If you have set \check_local_user\, the test is carried out after the + extension is removed. + + +Q0432: I use NIS for my user data. How can I stop Exim rejecting mail when my + NIS servers are being restarted? + +A0432: Exim doesn't know that you are using NIS; it just calls the \^^getpwnam()^^\ + function, which is routed by nsswitch. Unfortunately, \^^getpwnam()^^\ + was never designed to be routed through NIS, and it returns NULL if the + entry is not found or if the connection to the NIS server fails. This + means that Exim cannot tell the difference between ``no such user'' and + ``NIS is down''. + + Crutches to help with this problem are \finduser_retries\ in Exim, and + \^nscd^\ on the Unix side, but they are not perfect, and mail can still + be lost. However, Nico Erfurth pointed out that you can create a router + for Exim that tests for the availability of NIS, and force a defer if + NIS is not running: + +==> check_nis: + driver = redirect + data = ${lookup {$local_part} nis {passwd}{}} + + This should be placed before any router that makes any use of NIS, + typically at the start of your local routers. How does it work? If + your NIS server is reachable, the lookup will take place, and whether it + succeeds or fails, the result is an empty strting. This causes the + router to decline, and the address is passed to the following routers. + If your NIS server is down, the lookup defers, and this causes the + router to defer. A verification of an incoming address gets a temporary + rejection, and a delivery is deferred till later. + + +Q0433: How can I arrange for a single address to be processed by \*both*\ + \%redirect%\ \*and*\ \%accept%\? + +A0433: Check out the \unseen\ option. + + +Q0434: How can I redirect all local parts that are not in my system aliases to + a single address? I tried using an asterisk in the system alias file + with an \"lsearch*"\ lookup, but that send \*all*\ messages to the + default address. + +A0434: If your alias file generates addresses in the local domain, they are + also processed as a potential aliases. For example, suppose this is your + alias file: + +==> caesar: jc + anthony: ma + *: brutus + + The local part \/caesar/\ is aliased to \/jc/\, but that address is then + reprocessed by the routers. As the address is in the local domain, the + alias file is again consulted, and this time the default matches. In + fact after the second aliasing, \/brutus/\ is also processed again from + the start, and is aliased to itself. However, this happens only once, + because the next time, Exim notices that the aliasing router has already + processed \/brutus/\, so the router is skipped in order to avoid + looping. + + There are several ways of solving this problem; which one you use + depends on your aliasing data. + + (1) If the result of aliasing is always a local user name, that is, + aliasing never generates another alias, you can use the + \redirect_router\ option on the router to specify that processing + the generated addresses must start at the next router. For example: + +==> redirect_router = userforward + + assuming that the next router is called \%userforward%\. This + ensures that there is at most one pass through the aliasing router. + + (2) If you cannot rely on aliases generating non-aliases, it is often + easier not to use a default alias, but instead to place a router + such as the one below after all the other local routers (for the + relevant domains): + +==> catch_unknown: + driver = redirect + domains = ... + data = brutus@$domain + + Note that the default aliasing technique works more successfully for + virtual domains (see Q0401) because the generated address for the + default is not usually in the same virtual domain as the incoming + address. + + +Q0435: My alias file contains fully qualified addresses as keys, and some + wildcard domains in the form @foo.bar. Can Exim handle these? + +A0435: You can handle fully qualified addresses with this router: + +==> qualified_aliases: + driver = redirect + data = ${lookup{$local_part@$domain}lsearch{/etc/aliases}} + + (Add any other options you need for the \%redirect%\ router.) Place this + router either before or after the default aliases router that looks up + the local part only. (Or, if you have no unqualified aliases, replace + the default router.) + + To handle wildcards in the form @foo.bar you will need yet another + router. (Wildcards of the form *@foo.bar can be handled by an lsearch*@ + lookup.) Something like this: + +==> wildcard_aliases: + driver = redirect + data = ${lookup{@$domain}lsearch{/etc/aliases}} + + Place this after the routers that handle the more specific aliases. + + + +5. FILTERING + +Q0501: My filter isn't working. How can I test it? + +A0501: Use the \-bf-\ option (\-bF-\ for a system filter) to test the basic operation + of your filter. You can request debugging information for filtering only + by adding \"-d-all+filter"\ to the command. + + +Q0502: What I really need is the ability to obtain the result of a pipe + command so that I can filter externally and redirect internally. Is + this possible? + +A0502: The result of a pipe command is not available to a filter, because Exim + does not run any actual deliveries while filtering. It just sets up + deliveries at this time. They all actually happen later. If you want to + run pipes and examine their results, you need to set up a single + delivery to a delivery agent such as \^procmail^\ which provides this kind + of facility. + + An possible alternative is to use the \"${run"\ expansion item to run an + external command while filtering. In this case, you can make use of some + of the results of the command. + + +Q0503: I received a message with a ::Subject:: line that contained a non-printing + character (a carriage return). This messed up my filter file. Is there a + way to get round it? + +A0503: Instead of \"$h_subject:"\ use \"${escape:$h_subject:}"\ + + +Q0504: I want to search for \"$"\ in the subject line, but I can't seem to get + the syntax. + +A0504: Try one of these: + +==> if $h_subject: contains \$ then ... + if $h_subject: contains "\\$" then ... + + +Q0505: My problem is that Exim replaces \$local_part$\ with an empty string in the + system filtering. What's wrong or what did I miss? + +A0505: A message may have many recipients. The system filter is run just once + at the start of a delivery attempt. Consequently, it does not make sense + to set \$local_part$\. Which recipient should it be set to? However, you + can access all the recipients from a system filter via the variable + called \$recipients$\. + + +Q0506: Using \$recipients$\ in a system filter gives me another problem: how can + I do a string lookup if \$recipients$\ is a list of addresses? + +A0506: Check out the section of the filter specification called \*Testing a list of + addresses*\. If that doesn't help, you may have to resort to calling an + embedded Perl interpreter - but that is expensive. + + +Q0507: What are the main differences between using an Exim filter and using + \^procmail^\? + +A0507: Exim filters and \^procmail^\ provide different facilities. Exim filters run + at routing time, before any deliveries are done. A filter is like a + ``\(.forward)\ file with conditions''. One of the benefits is de-duplication. + Another is that if you forward, you are forwarding the original message. + + However, this does mean that pipes etc. are not run at filtering time, + nor can you change the headers, because the message may have other + recipients and Exim keeps only a single set of headers. + + \^procmail^\ runs at delivery time. This is for one recipient only, and so + it can change headers, run pipes and check the results, etc. However, if + it wants to forward, it has to create a new message containing a copy + of the original message. + + It's your choice as to which of these you use. You can of course use + both. + + +Q0508: How can I allow the use of relative paths in users' filter files when + the directories concerned are not available from the password data? + +A0508: You need to be running Exim 4.11 or later. You can then specify a value + for \$home$\ by setting the router_home_directory option on the + \%redirect%\ router. + + For earlier releases, there is no way to specify the value of \$home$\ + for a \%redirect%\ router; it either comes from the password data as a + result of \check_local_user\, or is unset. + + +Q0509: How can I set up a filter file to detect and block virus attachments? + +A0509: Exim's filter facilities aren't powerful enough to do much more than + very crude testing. Most people that want virus checking are nowadays + using one of the separate scanning programs such as \^exiscan^\ (see + \?http://duncanthrax.net/exiscan/?\). There is some further information + about scanning with Exim via \?http://www.timj.co.uk/linux/exim.php?\. + + +Q0510: Is it possible to write code for scanning messages in Python? + +A0510: \^elspy^\ is a layer of glue code that enables you to write Python code + to scan email messages at SMTP time. \^elspy^\ also includes a small + Python library with common mail-scanning tools, including an interface + to SpamAssassin and a simple but effective virus detector. You can + optain \^elspy^\ from \?http://elspy.sourceforge.net/?\. + + +Q0511: Whenever my system filter uses a \mail\ command to send a message, I get + the error \*User 0 set for address_reply transport is on the never_users + list*\. What does this mean? + +A0511: The system filter runs as \/root/\ in Exim 4, unless you set + \system_filter_user\ to specify otherwise. When you set up a delivery + direct from a system filter (an autoreply is a special kind of + ``delivery'') the transport runs as the same user, unless it has a + \user\ setting of its own. Normally, deliveries are not allowed to run + as \/root/\ as a security precaution; this is implemented by the + \never_users\ option. + + The easiest solution is to add this to your configuration: + +==> system_filter_user = exim + + The system filter then runs as \/exim/\ instead of \/root/\. + Alternatively, you can arrange for autoreplies from the system filter to + use a special transport of their own, and set the \user\ option on that + transport. + + +Q0512: I'm trying to reference the ::Envelope-To:: header in my filter, but + \$h_envelope-to:$\ is always empty. + +A0512: ::Envelope-To:: is added at delivery time, by the transport. Therefore, + the header doesn't exist at filter time. In a user filter, the values + you probably want are in \$original_local_part$\ and + \$original_domain$\. In a system filter, the complete list of all + envelope recipients is in \$recipients$\. + + +Q0513: I want my system filter to freeze all mails greater than 500K in size, + but to exclude those to a specific domain. However, I don't seem to be + able to use \$domain$\ in a system filter. + +A0513: You cannot do this in a system filter, because a single message may have + multiple recipients, some in the special domain, and some not. That is + also the reason why \$domain$\ is not set in a system filter. + + If you want to take actions on a per-recipient basis, you have to do it + in a router. However, freezing is not appropriate, because freezing + stops all deliveries. You could, however, delay delivery to all but the + special domains by using something like this: + +==> delay_if_too_big: + driver = redirect + domains = !the.special.domain + condition = ${if >{$message_size}{500K}{yes}{no}} + allow_defer + data = :defer: message too big. + + However, there isn't an easy way of ``releasing'' such messages at + present. + + +Q0514: When I try to send to two addresses I get an error in the filter + file \*malformed address: , e@fgh.com may not follow a@bcd.com*\. What + is going on? + +A0514: Have you got + +==> deliver "a@bcd.com, e@fgh.com" + + in your filter? If so, that is your problem. You should have + +==> deliver a@bcd.com + deliver e@fgh.com + + Each \deliver\ command expects just one address. + + + +6. DELIVERY + +Q0601: What does the error \*Neither the xxx router nor the yyy transport set + a uid for local delivery of...*\ mean? + +A0601: Whenever Exim does a local delivery, it runs a process under a specific + user and group id (uid and gid). For deliveries into mailboxes, and to + pipes and files set up by forwarding, it normally picks up the uid/gid + of the receiving user. However, if an address is directed to a pipe or a + file by some other means, such an entry in the system alias file of the + form + +==> majordomo: |/local/mail/majordomo ... + + then Exim has to be told what uid/gid to use for the delivery. This can + be done either on the routerr that handles the address, or on the + transport that actually does the delivery. If a pipe is going to run a + setuid program, then it doesn't matter what uid Exim starts it out with, + and so the most straightforward thing is to put + +==> user = exim + + on either the router or the transport. A setting on the transport + overrides a setting on the router, so if the same transport is being + used with several routers, you should set the user on it only if you + want the same uid to be used in all cases. + + In the default configuration, the transports used for file and pipe + deliveries are the ones called \address_file\ and \address_pipe\. You + can specify different transports by setting, for example, + +==> pipe_transport = special_pipe_transport + + on the \%system_aliases%\ router. Then you can set up \%special_pipe_transport%\ + +==> special_pipe_transport: + driver = pipe + user = ???? + + which will be used only for pipe deliveries from that one router. + What you put for the ???? is up to you, and depends on the particular + circumstances. + + +Q0602: Exim keeps crashing with segmentation errors (signal 11 or 139) during + delivery. This seems to happen when it is about to contact a remote + host or when a delivery is deferred. + +A0602: This could be a problem with Exim's databases. Try running a delivery + with debugging turned on. If the last line of the debug output is + something like this: + +==> locked /var/spool/exim/db/retry.lockfile + + the crash is happening inside the DBM library. Check that your DBM + library is correctly installed. In particular, if you have installed a + second DBM library onto a system that already had one, check that its + version of \(ndbm.h)\ is being seen first. For example, if the new + version is in \(/usr/local/include)\, check that there isn't another + version in \(/usr/include)\. If you are using Berkeley db, you can set + +==> USE_DB=yes + + in your \(Local/Makefile)\ to avoid using \(ndbm.h)\ altogether. This is + particularly relevant for version 2 (or later) of Berkeley db, because + no \(ndbm.h)\ file is distributed with it. Another thing you can try is + to run + +==> exim_dumpdb /var/spool/exim retry + + to see if it also crashes, or build the \^test_dbfn^\ tool and fiddle + around with it. If both fail, it is most almost certainly a problem with + your DBM library. You could try to update it, or force Exim to use + another library. See the file \(doc/dbm.discuss.txt)\ for hints about + this. + + +Q0603: How can mails that are being routed through routers that do not set + \check_local_user\ be delivered under the uid of the recipient? + +A0603: Q0601 contains background information on this. If you are using, say, an + alias file to direct messages to specific mailboxes, you can use + the \user\ option on either the router or the transport to set the uid. + What you put in the setting depends on how the required uid is to be + found. It could be looked up in a file or computed somehow from the + local part, for example. + + +Q0604: I want to use MMDF-style mailboxes. How can I get Exim to append the + ctrl-A characters that separate indvidual emails? + +A0604: Set the \message_suffix\ option in the \%appendfile%\ transport. In fact, + for MMDF mailboxes you need a prefix as well as a suffix to get it + working right, so your transport should contain these settings: + +==> message_prefix = "\1\1\1\1\n" + message_suffix = "\1\1\1\1\n" + + Also, you need to change the \check_string\ and \escape_string\ settings so + that the escaping happens for lines in the message that happen to begin + with the MMDF prefix or suffix string, rather than ``From'' (the default): + +==> check_string = "\1\1\1\1\n" + escape_string = "\1\1\1\1 \n" + + Adding a space to the line is sufficient to prevent it being taken as a + separator. + + +Q0605: If a user's mailbox is over quota, is there a way for me to set it up so + that the mail bounces to the sender and is not stored in the mail queue? + +A0605: In the retry section of the configuration, put + +==> *@your.dom.ain quota + + That is, provide no retry timings for over quota errors. They will then + bounce immediately. Alternatively, you can set up retries for a short + time only, or use something like this: + +==> *@your.dom.ain quota_7d + *@your.dom.ain quota F,2h,15m; F,3d,1h + + which bounces immediately if the user's mailbox hasn't been read for 7 + days, but otherwise tries for up to 3 days after the first quota + failure. + + +Q0606: I'm using tmail to do local deliveries, but when I turned on the + \use_crlf\ option on the \%pipe%\ transport (tmail prefers \"@\r@\n"\ + terminations) message bodies started to vanish. + +A0606: You need to unset the \mesage_prefix\ option, or change it so that its + default \"@\n"\ terminator becomes \"@\r@\n"\. For example, the + transport could be: + +==> local_delivery_mbx: + driver = pipe + command = /usr/local/bin/tmail $local_part + user = exim + current_directory = / + use_crlf + message_prefix = + + The reason for this is as follows: tmail uses the line terminator on + the first line it sees to determine whether lines are terminated by + \"@\r@\n"\ or \"@\n"\. If the latter, it moans to stderr and changes subsequent + \"@\n"\ terminators to \"@\r@\n"\. The default setting of the \message_prefix\ + option is \"From ...@\n"\, and this is unaffected by the \use_crlf\ option. + If you don't change this, tmail sees the first line terminated by + \"@\n"\ and prepends \"@\r"\ to the \"@\n"\ terminator on all subsequent + lines. However, if \use_crlf\ is set, Exim makes all other lines + \"@\r@\n"\ terminated, leading to doubled \"@\r@\r@\n"\ lines and + corrupt mbx mailboxes. + + +Q0607: When I activate ``return receipt'' for example in Netscape Mailbox + sending options, then I get an error message from Exim... something + like \*not supported*\. Can I activate delivery confirmations? + +A0607: Exim does not support any kind of delivery notification. + + (1) You can configure it to recognize headers such as + \Return-receipt-to:\ if you wish. + + (2) Some people want MSN (message status notification). Such services + are implemented in MUAs, and don't impact on the MTA at all. + + (3) I investigated the RFCs which describe the DSN (delivery status + notification) system. However, I was unable to specify any sensible way + of actually doing anything with the data. There were comments on the + mailing list at the time; many people, including me, conclude that DSN + is in practice unworkable. The killer problem is with forwarding and + aliasing. Do you propagate the DSN data with the generated addresses? + Do you send back a ``reached end of the DSN world'' or ``expanded'' message? + Do you do this differently for different kinds of aliasing/forwarding? + For a user who has a \(.forward)\ file with a single address in, this + might seem easy - just propagate the data. But what if there are several + forwardings? If you propagate the DSN data, the sender may get back + several DSN messages - and should the sender really know about the + detail of the receiver's forwarding arrangements? There isn't really + any way to distinguish between a \(.forward)\ file that is forwarding + and one that is a mini mailing list. And so on, and so on. There are so + many questions that don't have obvious answers. + + +Q0608: What does the message \*retry time not reached [for any host]*\ on the log + mean? Why won't Exim try to deliver the message? + +A0608: That is not an error. It means exactly what it says. A previous attempt + to deliver to that address failed with a temporary error, and Exim + computed the earliest time at which to try again. This can apply to + local as well as to remote deliveries. For remote deliveries, each host + (if there are several) has its own retry time. + + If you are running on a dial-up host, the rest of this answer probably + does not apply to you. Go and read Q1404 instead. If your host is + permanently online, read on... + + Some MTAs have a retrying schedule for each message. Exim does not work + like this. Retry timing is normally host-based for remote deliveries and + address-based for local deliveries. (There are some exceptions for certain + kinds of remote failure - see \*Errors in outgoing SMTP*\ in the manual.) + + If a new message arrives for a failing address and the retry time has + not yet arrived, Exim will log \*retry time not reached*\ and leave the + message on the queue, without attempting delivery. Similarly, if a queue + runner notices the message before the time to retry has arrived, it + writes the same log entry. When the retry time has past, Exim attempts + delivery at the next queue run. If you want to know when that will be, + run the exinext utility on the address, for example: + +==> exinext user@some.domain + + You can suppress these messages on the log by including \"-retry_defer"\ + in the setting of \log_selector\. You can force a delivery attempt on a + specific message (overriding the retry time) by means of the -M option: + +==> exim -M 10hCET-0000Bf-00 + + If you want to do this for the entire queue, use the \-qf-\ option. + + +Q0609: Exim seems to be sending the same message twice, according to the log, + although there is a difference in capitalization of the local part of + the address. + +A0609: That is correct. The RFCs are explicit in stating that capitalization + matters for local parts. For remote domains, Exim is not entitled to + assume case independence of local parts. I know, it is utterly silly, + and it causes a lot of grief, but that's what the rules say. Here is a + quote from RFC 2821: + + ... a command verb, an argument value other than a mailbox local-part, + and free form text MAY be encoded in upper case, lower case, or any + mixture of upper and lower case with no impact on its meaning. This + is NOT true of a mailbox local-part. The local-part of a mailbox + MUST BE treated as case sensitive. Therefore, SMTP implementations + MUST take care to preserve the case of mailbox local-parts. Mailbox + domains are not case sensitive. In particular, for some hosts the + user "smith" is different from the user "Smith". However, exploiting + the case sensitivity of mailbox local-parts impedes interoperability + and is discouraged. + + +Q0610: How can I force the next retry time for a host to be now? + +A0610: You can change the retry time with the \^exim_fixdb^\ utility, but its + interface is very clumsy. If you have a message for the host on the + queue, the simplest thing to do is to force a delivery with the \-M-\ + command line option. If delivery succeeds, the retry data will get + cleared. If the host is past the cutoff time, so that messages are + bouncing immediately without trying a delivery, you can use \-odq-\ to + put a message on the queue without a delivery attempt, and then use + \-M-\ on it. + + +Q0611: I set up \"|/bin/grep Subject|/usr/bin/smbclient -M <netbiosname>"\ as an + alias but it doesn't work. + +A0611: That is a shell command line. Exim does not run pipe commands under a + shell by default (for added security - and it saves a process). You + need something like + +==> "|/bin/sh -c '/bin/grep Subject|/usr/bin/smbclient -M <netbiosname>'" + + +Q0612: Why does the \%pipe%\ transport add a line starting with \">From"\ to + messages? + +A0612: Actually, it adds a line starting with \"From"\ followed by a space. + This is commonly referred to as the \"From_"\ line, to emphasize the + fact that \"From"\ is followed by a space and not a colon. This is a + pseudo-header line that contains the envelope sender address and the + time of delivery. It originated as a separator line in Berkeley format + mailboxes, but is also used in other contexts. (And yes, it is often + confused with the ::From:: header line, and this causes a lot of grief. + The use of \"From_"\ was one of the really bad email design decisions.) + + Exim's \%pipe%\ transport adds this pseudo-header line by default + because \(/usr/ucb/vacation)\ needs it, and that is one of the the most + common uses of piping. The \^procmail^\ local delivery agent also makes + use of the \"From_"\ line. If you do not want it, change the setting of + \message_prefix\ on the \%pipe%\ transport. For example, to remove the + line altogether, use + +==> message_prefix = + + If you are not piping to \(/usr/ucb/vacation)\ or \^procmail^\, it is + likely that you do not need a \"From_"\ line, and indeed it may cause + problems if it is present. + + One user reported that this line gave trouble when a pipe was used to + send messages to Courier's \^deliverquota^\ program. The line was + retained with the message, and caused problems for MS Exchange 2000 when + retrieving messages with its built-in POP collector. Specifically, it + caused Exchange to not be able to recognise message attachments. + + +Q0613: I have set \fallback_hosts\ on my \%smtp%\ transport, but after the error + \*sem@chat.ru cannot be resolved at this time*\ Exim isn't using them. + +A0613: \fallback_hosts\ works only if an attempt at delivery to the original + host(s) fails. In this case, Exim couldn't even resolve the domain + \(chat.ru)\ to discover what the original hosts were, so it never got as far + as the transport. However, see Q0315 for a possible solution. + + +Q0614: After the holidays my ISP has always hundreds of e-mails waiting for me. + These are forced down Exim's throat in one go. Exim spawns a lot of + kids, but is there some limit to the number of processes it creates? + +A0614: Unless you have changed \smtp_accept_queue_per_connection\ it should + spawn only that many processes per connection (default 10). Your ISP + may be making many connections, of course. That is limited by + \smtp_accept_max\. + + +Q0615: When a message in the queue got to 12h old, Exim wrote \*retry timeout + exceeded*\ and removed all messages in the queue to this host - even + recent messages. How I can avoid this behaviour? I only want to remove + messages that have exceeded the maximum retry time. + +A0615: Exim's retrying is host-based rather than message-based. The philosophy + is that if a host has been down for a very long time, there is no point + in keeping messages hanging around. However, you might like to check + out \delay_after_cutoff\ in the \%smtp%\ transport. It doesn't do what you + want, but it might help. + + +Q0616: Can Exim add a ::Content-Length:: header to messages it delivers? + +A0616: You could include something like + +==> headers_remove = "content-length" + headers_add = "Content-Length: $message_body_size" + + to the \%appendfile%\ transport. However, the use of ::Content-Length:: can + cause several problems, and is not recommended unless you really know + what you are doing. There is a discussion of the problems in + \?http://home.netscape.com/eng/mozilla/2.0/relnotes/demo/content-length.html?\. + + +Q0617: Exim seems to be trying to deliver a message every 10 minutes, though + the retry rules specify longer times after a while, because it is + writing a log entry every time, like this: + +==> 1999-08-26 14:51:19 11IVsE-000MuP-00 == example@example.com T=smtp defer + (-34): some host address lookups failed and retry time not reached for + other hosts or connection limit reached + +A0617: It is looking at the message every 10 minutes, but it isn't actually + trying to deliver. It's looking up \(example.com)\ in the DNS and finding + this information: + +==> example.com. MX 10 example-com.isp.example.com. + example.com. MX 0 mail.example.com. + mail.example.com. A 202.77.183.45 + A lookup for example-com.isp.example.com. yielded NXDOMAIN + + The last line means that there is no address (A) record in the DNS for + \(example-com.isp.example.com)\. That accounts for \*some host address + lookups failed*\, but the retry time for \(mail.example.com)\ hasn't been + reached, which accounts for \*retry time not reached for other hosts*\. + + +Q0618: I am trying to set exim up to have a automatic failover if it sees that + the system that it is sending all mail to is down. + +A0618: Add to the \%remote_smtp%\ transport the following: + +==> fallback_hosts = failover.server.name(s) + + If there are several names, they must be separated by colons. + + +Q0619: I can't get Exim to deliver over NFS. I get the error \*fcntl() failed: + No locks available*\, though the lock daemon is running on the NFS server + and other hosts are able to access it. + +A0619: Check that you have \(lockd)\ running on the NFS client. This is not + always running by default on some systems (Red Hat is believed to be one + such system). + + +Q0620: Why does Exim bounce messages without even attempting delivery, giving + the error \*retry time not reached for any host after a long failure + period*\? + +A0620: This message means that all hosts to which the message could be sent + have been failing for so long that the end of the retry period + (typically 4 or 5 days) has been reached. In this situation, Exim still + computes a next time to retry, but any messages that arrive in the + meantime are bounced straight away. You can alter this behaviour by + unsetting the \delay_after_cutoff\ option on the smtp transport. Then Exim + will try most messages for those hosts once before giving up. + + +Q0621: My \(.forward)\ file is \"|/usr/bin/procmail -f-"\ and mail gets delivered, + but there was a bounce to the sender, sending him the output of procmail. + How can I prevent this? + +A0621: Exim's default configuration is set up like this: + +==> address_pipe: + driver = pipe + return_output + + The \return_output\ option requests that any output that the pipe + produces be returned to the sender. That is the safest default. If you + don't want this, you can either remove the option altogether, or change + it to \return_fail_output\, to return output only if the command fails. + Note that this will affect all pipes that users run, not just your + procmail one. It might be better to arrange for procmail not to produce + any output when it succeeds. + + +Q0622: Can I write an ordinary file when I run a perl script as a transport + filter for the \%remote_smtp%\ and \%address_pipe%\ transports? + +A0622: Yes, provided the file is writeable by the uid under which the transport + runs (the Exim user in the case of the remote transport). However, if two + messages are being delivered at once, their data will get mixed up in + the file unless you implement your own locking scheme. If all you want + to do is to take a copy of the message, another approach that avoids + the locking problem is to use a system filter to set up an ``unseen'' + delivery to a file. If you only want the message's headers, you can + set \message_filter_file_transport\ to point to a special \%appendfile%\ + transport that has \headers_only\ set. + + +Q0623: My \(/var/spool/mail)\ has grown drastically. Is there any possibility of + using two directories? + +A0623: You can use an expansion string to split mailboxes between two + directories. For example, + +==> file = /var/spool/mail${nhash_2:$local_part}/$local_part + + which does a hash on the local part, producing either 0 or 1, thereby + using \(mail0) or \(mail1)\. But remember, the MUAs that read these mailboxes + also have to know where they are. + + +Q0624: Sendmail has a program called \^smrsh^\ that restricts what binaries + can be run from sendmail aliases. Is there something like this in Exim ? + +A0624: Check out the \allow_commands\ option in the \%pipe%\ transport. + + +Q0625: I wish to have large emails go out one at a time. + +A0625: One possibility is to set up a router that defers all large messages, + except in queue runs. Since queue runners deliver just one + message at a time, if you limited the number of simultaneous queue + runners to 1, you would get the effect you wanted. A suitable router + might be + +==> defer_if_large_unless_queue_run: + driver = redirect + condition = ${if or{{queue_running}{<{$message_size}{200K}}}{no}{yes}} + allow_defer + data = :defer: too large for immediate delivery + no_verify + + Of course, this would always delay any large message until the next + queue runner, but if you run them fairly regularly, this shouldn't be a + huge problem, and may even be desirable. Note the use of \no_verify\ to + ensure that this router is not used when Exim is verifying addresses. + + +Q0626: Exim can route local parts independent of their case, but the Cyrus LMTP + daemon requires the correct case. How can I fix this? + +A0626: You need to rewrite the local part to the correct case before running + the router that routes to Cyrus. For example, if you require all lower + case, and your router is called \local_user\, put this router in front + of it: + +==> lowercase_local: + driver = redirect + redirect_router = local_user + domains = +local_domains + data = ${lc:$local_part}@$domain + + The setting of \redirect_router\ causes processing of the rewritten + address to start at the next router, instead of the first router. See + also Q0630, and C045 for a more complete Cyrus configuration. + + +Q0627: Is there a command I can send to Exim to retry all queued messages + regardless of their retry schedule? + +A0627: The \-qff-\ option starts a queue runner that forces a delivery attempt + for all messages, including frozen ones. If you use \-qf-\, frozen + messages are skipped. + + +Q0628: I have the default retry rule, which I thought meant that Exim should + keep trying for four days, but it seems to be bouncing some messages + immediately. + +A0628: See Q0615 and Q0620. + + +Q0629: I'm having trouble with quotas and Courier, because Exim is not handling + maildirsize files. + +A0629: You will do better to move the quota handling to Courier. Use \^maildrop^\ + as your MDA rather than direct Exim delivery. This also has the + advantage that if you give web access to the mail spool (over \^sqwebmail^\) + you can then use the web front end to edit \^maildrop^\ filter files. + + +Q0630: How can I configure Exim to deliver to a Cyrus message store? + +A0630: (1) The reference manual contains an example that uses pipe delivery. + + (2) Here is a transport that uses LMTP delivery, assuming that + \$local_part$\ contains the username: + +==> cyrus_inbox: + driver =lmtp + user = cyrus + socket = /var/cyrus/socket/lmtp + + (3) This is a transport that delivers direct to a non-inbox mailbox: + +==> cyrus_mailbox: + driver = pipe + user = $local_part + message_prefix = + message_suffix = + log_fail_output + return_output + command = "/usr/cyrus/bin/deliver -a $local_part \ + -m <mailbox-name> $local_part" + + This delivers to the Cyrus mailbox \"user.$local_part.<mailbox-name>"\. + Using \"user = $local_part"\ and \"-a $local_part"\ makes it work + without needing an explicit `p' ACL set for `anyone' on the mailbox. + + +Q0631: I would like to choose a retry rule based on on the sender rather than + the recipient address. Is this possible? + +A0631: Yes. The address part of a retry rule is matched as a single-item + address list. Such lists are always expanded, so you can use something + like this: + +==> "${if eq{$sender_address}{xxx}{*@*}{no@no}}" quota F,1h,10m; ... + + If the sender address is ``xxx'', the pattern expands to ``*@*'', which + matches all recipient addresses; if you want to, you can make this a + more restrictive pattern. If the sender address is not ``xxx'', the + pattern expands to ``no@no'', which is assumed to be a recipient address + that can never match, so the retry rule is skipped. + + +Q0632: What does the error \*User 1 set for local_mbx_delivery transport is on + the never_users list*\ mean? + +A0632: You have configured the \%local_mbx_delivery%\ to run as the user whose + id (uid) is 1. However, this user is on the list defined by the + \never_users\ runtime option, or the \\FIXED_NEVER_USERS\\ compile-time + option. These are ``safety catch'' lists; Exim refuses to deliver to any + user that is on them. The most common use of \never_users\ is to avoid + doing any deliveries as \/root/\, but it can contain other uids. + + +Q0633: Why is \$domain$\ not set in the \%smtp%\ transport? + +A0633: The \%smtp%\ transport can handle several recipient addresses at once. + This happens by default if the host lists for the addresses are + identical. A single copy of the message is sent, using multiple \\RCPT\\ + commands to transmit multiple envelope recipients. The \$domain$\ + variable is set in the \%smtp%\ transport only if all the recipient + addresses have the same domain. You must have a case where several + addresses with different domains resolve to the same set of hosts. + + If you want to restrict the transport so that it handles only a single + domain at once (but still possibly with more than one recipient), set + +==> multi_domain = false + + If you want to restrict the transport so that it handles only a single + address at once, set + +==> max_rcpt = 1 + + +Q0634: How can I stop a local transport from trying to access the user's home + directory, even when the delivery is to a file that is elsewhere? + +A0634: See answer (2) for Q0423. + + +Q0635: The log message \*error ignored*\ appears after some delivery failures. + What does it mean? + +A0635: This message is written when Exim fails to deliver a bounce message whose + age is greater than \ignore_bounce_errors_after\. It indicates that the + failing bounce message has been discarded. + + The same message is written after failed deliveries when a filter file + uses the \noerror\ feature when setting up a delivery, or if a router + has the setting + +==> errors_to = <> + + Both of these specify that delivery failures are to be discarded. + + + +7. POLICY CONTROLS + +Q0701: How do I block unwanted messages from outside my host? + +A0701: Exim uses Access Control Lists (ACLs) for controlling incoming mail from + other hosts. A whole chapter in the reference manual is devoted to + describing how they work. A wide variety of conditions can be imposed on + incoming messages. + + The default Exim run time configuration contains an example of an ACL + which blocks all relaying, and messages whose senders cannot be + verified. This example is heavily commented and worth studying. + + +Q0702: I don't want to block spam entirely; how can I inspect each message + before deciding whether or not to deliver it? + +A0702: Wherever possible, inspection and rejection is best done automatically + in an ACL, that is, before the message is accepted. If you want to + verify manually each message that is classified as spam by an automatic + check, you can arrange for a system filter to freeze such messages after + they have been accepted. + + If, after inspection, you decide not to deliver the message, it is + safest to discard it, using the \-Mrm-\ option. Use of the \-Mg-\ option + to force a bounce carries the risk of ``collateral spam'' if the sender + address is faked. + + +Q0703: How can I test that my spam blocks are working? + +A0703: The \-bh-\ option allows you to run a testing SMTP session as if from a + given IP address. For example, + +==> exim -bh 192.168.178.39 + + In addition to the normal SMTP replies, it outputs commentary about + which tests have succeeded or failed. If you are not interested in the + details, but just want to know if a particular sender at a particular IP + address is able to mail to a particular recipient, you can use the + \exim_checkaccess\ utility, which provides a ``packaged'' version of + \-bh-\. You call it like this: + +==> exim_checkaccess 192.168.53.23 recip@my.domain -f sender@some.domain + + If you don't give a sender, \"<>"\ is used (that it, it acts like a + bounce message). + + +Q0704: How can I test that Exim is correctly configured to use the Realtime + Blackhole List (RBL)? + +A0704: The \-bh-\ option allows you to run a testing SMTP session as if from a + given address. The \^exim_checkaccess^\ utility provides a more packaged + version of this facility. You need to know a blocked IP address with + which to test. Such a testing address is kindly provided by Russell + Nelson: + +==> linux.crynwr.com [192.203.178.39] + + You can also send mail to \(nelson@linux.crynwr.com)\ from the server + whose RBL block you are testing. The robot that receives that email + will attempt to send a piece of test email in reply. If your RBL block + didn't work, you get a message to that effect. Regardless of whether the + RBL block succeeds or not, it emails you the results of the SMTP + conversation from a host that is not on the RBL, so you can see how your + server looks from the view of someone on the RBL. + + +Q0705: How can I use tcpwrappers in conjunction with Exim? + +A0705: Exim's own control facilities can do all that tcpwrappers can do. + However, if you are already using tcpwrappers for other things it might + be convenient to include Exim controls in the same place. + + First of all, ensure that Exim is built to call the tcpwrappers library, + by including \\USE_TCPWRAPPERS=yes\\ in \(Local/Makefile)\. You also need to + ensure that the header file \(tcpd.h)\ is available at compile time, and the + \(libwrap.a)\ library is available at link time, typically by including it in + \\EXTRALIBS\\. You may need to copy these two files from the tcpwrappers + build directory to, for example, \(/usr/local/include)\ and \(/usr/local/lib)\, + respectively. Then you could reference them by + +==> CFLAGS=-I/usr/local/include + EXTRALIBS=-L/usr/local/lib -lwrap + + in \(Local/Makefile)\. There are two ways to make use of the functionality, + depending on how you have tcpwrappers set up. If you have it set up to + use only one file, you ought to have something like: + +==> /etc/hosts.allow: + +==> exim : <client_list> : <allow_or_deny> + + For example: + +==> exim : LOCAL 192.168.0. .friendly.domain special.host : ALLOW + exim : ALL : DENY + + This allows connections from local hosts (chiefly //localhost//), from + the subnet 192.168.0.0/24, from all hosts in \(*.friendly.domain)\, and + from a specific host called \(special.host)\. All other connections are + denied. If you have tcpwrappers set up to use two files, use the + following: + +==> /etc/hosts.allow: + +==> exim : <client_list> + +==> /etc/hosts.deny: + +==> exim : <client_list> + + Read the \^hosts_access^\ man page for more ways of specifying clients, + including ports, etc., and on logging connections. + + +Q0706: How can I get POP-auth-before-relay (aka POP-before-SMTP) support in + Exim? + +A0706: Exim 4 supports the ``whoson'' (\?http://whoson.sourceforge.net?\) + facility for doing this. If you set this up, you can do the check in an + Exim ACL by a statement like this: + +==> require condition = \ + ${lookup whoson {$sender_host_address}{yes}{no}} + + Otherwise you need to arrange for a list of permitted IP addresses to be + maintained in a file or database, and use this in a \hosts\ condition in + an ACL statement. An Exim user has published this recipe: + + \#\#\#\#\?http://www.zeiss.cx/memo/computer/linux/email/exim-s-a-p.html?\ + + Another Exim user submitted the following idea: + + Use a script to grab authenticated IP addresses from the log files of + the POP3 and IMAP4 daemons. These are used to create files in the + directory tree \(/var/db/popb4smtp)\. The existence of a file represents a + valid ``popped recently token'' for the IP address used as the filename. + + Another script periodically removes stale files from the tree (after two + hours). There's a small race condition here; it's possible for a file + to be deleted just after it has been updated by the script that watches + the logs. For low-volume servers, the odds of hitting this window are + low. + + A POPB4SMTP_CLIENT macro in the Exim configure file provides a reusable + ``has this sender popped recently?'' query: + +==> POPB4SMTP_SUBDIR = /var/db/popb4smtp/${substr_-1_1:$sender_host_address} + POPB4SMTP_CLIENT = ${if exists {POPB4SMTP_SUBDIR/$sender_host_address} \ + {$sender_host_address} {0} } + + Now you can use it just about anywhere, including in your ACLs. Simple + examples include: + +==> hostlist relay_hosts = 127.0.0.1/32 : ... : POPB4SMTP_CLIENT + host_lookup = !127.0.0.1/32 : ... : !POPB4SMTP_CLIENT + rfc1413_hosts = !127.0.0.1/32 : ... : !POPB4SMTP_CLIENT + + The two scripts (and a FreeBSD startup script for them) are available + for download at: + + \#\#\#\#\?http://people.FreeBSD.org/~sheldonh/popb4smtp-nodb.tar.gz?\ + + +Q0707: I have one or two cases where my host correctly rejects messages, but + the remote host is quite persistent, and keeps trying over and over. + +A0707: It is an unfortunate fact that a number of SMTP clients, in violation of + the SMTP RFC, do not treat a permanent error code that is given after + the DATA portion of the transaction as a permanent error. Consequently + they keep resending the message, and the worst offenders do so at very + short intervals. + + The only way to stop such behaviour is to blacklist the IP address, or + the envelope sender, or both, in such a way that future messages get + rejected at RCPT time instead of at DATA time. You could also complain + to the remote host's administrators. + + +Q0708: How can I run customized verification checks on incoming addresses? + +A0708: There are a number of possibilities: + + (1) If you can implement your checks in Perl, you can use Exim's + facility for running an embedded Perl interpreter. For example, if you + want to run special checks on local addresses, you could use ACL + an statement like this: + +==> require domains = my.local.domain + condition = ${perl{verify}{$local_part}} + + The result of the Perl function should be ``yes'' or ``no''. + + (2) You could also run an external program in a similar way, by a + statement such as: + +==> require domains = my.local.domain + condition = ${run{/my/verifier $local_part}} + + This requires the use of another process, so could prove more expensive + than Perl. + + (3) If you are prepared to write C code, read the chapter in the manual + entitled \*Adding a local scan function to Exim*\. + + +Q0709: Does Exim apply RBL checks to error messages, those with an envelope + sender of \"<>"\ ? + +A0709: This depends on the ACL configuration. You can test for bounce messages + (by looking for an empty sender address) and thereby exclude them from + RBL checking if you want. This ACL statement does that: + +==> deny senders = ! : + dnslist = blackholes.mail-abuse.org + + However, some spam does come with an empty sender address, so this may + not be a good idea. + + +Q0710: I want to reject certain sender-recipient combinations, with a specific + message for each such combination. + +A0710: Set up a file (or database) containing the messages, keyed by the + combination, for example: + +==> sender1@sdomain1=>recipient1@rdomain1: blocked because... + sender2@sdomain2=>recipient2@rdomain2: blocked because... + + If you have lots of recipients for the same sender, it might be easier + to generate this file from more convenient data. In your ACL that is run + for each RCPT command, you can then put: + +==> deny message = ${lookup{$sender_address=>$local_part@$domain}\ + lsearch{/that/file}} + condition = ${lookup{$sender_address=>$local_part@$domain}\ + lsearch{/that/file}}{yes}{no}} + + The condition is tested first. If the lookup succeeds, the condition + succeeds so access is denied. The message is then expanded, but the + lookup won't be repeated, because Exim will have cached the previous + result. + + This approach blocks only incoming SMTP messages. If you need to do + similar blocks for messages that do not arrive over SMTP, you have to + set up a suitable \%redirect%\ router with a \:fail:\ setting. + + +Q0711: Will Exim allow me to create a file of regexs and match incoming + external email to the list - and if a match is found file the offending + message into a special location? Also is it possible to make Exim only + filter parts of an incoming email - e.g. ignore large MIME attachments + for example and only process text/plain? + +A0711: You can do some of this in a system filter. For example: + +==> if $message_body matches <...some complicated regex...> or + $message_body matches <...some other regex...> or + $header_from: matches <...regex...> or + etc. + then + save /some/special/file + endif + + or instead of \"save"\ you could have \"deliver"\ (to some address) or + \"pipe"\ (to some script). + + There isn't any mechanism for ignoring attachments, but \$message_body$\ + only looks at the first n bytes of the body, where n defaults to 500 but + can be changed. + + A more expensive alternative would be to run a Perl subroutine using the + embedded Perl mechanism. If you passed over the message id, the Perl + code could read the message files on the spool and implement any + algorithm it liked for deciding what should be done. + + +Q0712: I've hacked sendmail to make an ioctl call at the time of the SMTP RCPT + command, to check if a user has exceeded their email quota. If they have + I issue a temporary failure and a message - can I do this with Exim? + +A0712: If you can make this happen in Perl you can use the embedded Perl + facility, and use it from a \condition\ condition in an ACL statement. + You can also use the expansion facility to run an external program, but + this uses more resources because it uses another process. + + +Q0713: I'd like to pass all messages through a virus-scanning system before + delivery. Can Exim do this? + +A0713: One way of achieving this is to deliver all messages via a pipe to a + checking program that resubmits them for delivery in some private way + that can be checked (e.g. on a specific SMTP port, or IP address). One + possibility is to use the `received protocol` field that can be set + for locally submitted mail via the \-oMr-\ command line option. This + router sends all messages that are not from the local host and whose + received protocol is not \"scanned-ok"\ to the \%virus_scan%\ transport: + +==> vircheck: + driver = accept + transport = virus_scan + condition = ${if or {{eq {$received_protocol}{scanned-ok}} \ + {eq {$sender_host_address}{127.0.0.1}}}\ + {0}{1}} + + One problem is that this approach scans the message for each recipient, + not just once per message. + + The virus_scan transport should be set up to pipe the message to a + suitable checking program or script which runs as a trusted user. This + can then re-submit the message to Exim, using \-oMr-\ to set the received + protocol to \"scanned-ok"\, and the \-f-\ option to set the correct envelope + sender address. \**Warning:**\ If you forget to make the resubmitting process + run as a trusted user, the received protocol does not get set, and you + are likely to generate a loop. + + +Q0714: Is there a way to configure Exim to reject mail to a certain local host? + +A0714: No, only to certain domains. To reject at SMTP time, you can put a line + like this in your ACL: + +==> deny message = this domain is deliberately rejected + domains = a.certain.domain + + To fail addresses in messages that do not arrive over SMTP, you can set + up a router like this: + +==> reject_a_certain_domain: + driver = redirect + domains = a.certain.domain + allow_fail + data = :fail: this domain is deliberately rejected + + +Q0715: How can I get Exim to remove attachments from messages? + +A0715: Exim does not contain facilities for modifying messages. You must use + an external program if you want to do this. You can route messages that + have a ::Content-type:: header line via a pipe to a command that does + the job and then re-submits the message to Exim. Alternatively, you + could use a transport filter to do this job. + + +Q0716: How can I arrange for each user to have a file listing the only sender + addresses from which she will accept mail? I want to do this so my + family members don't get any spam (or other inappropriate mail). + +A0716: Let's assume each user has a file called \(.acceptlist)\ in the home + directory. You can put in your ACL a line like this: + +==> require senders = /home/$local_part/.acceptlist + + This will reject RCPT commands when the sender is not in the accept + list for the recipient. (Replace \(/home/$local_part)\ with whatever + the correct path to your user's home directories is.) + + One problem with this is that it will block bounce messages, which have + empty senders. You can get round this, by changing the line to this: + +==> require senders = : /home/$local_part/.acceptlist + + However, this will, of course, let in spam that has a null sender. + + +Q0717: When using Nessus on a system that runs Exim, a number of security + issues are raised. Nessus complains that Exim answers to EXPN and/or + VRFY; sometimes it even complains that Exim allows relaying. + +A0717: Exim supports EXPN and VRFY only if you permit it to do so in the ACLs + defined by \acl_smtp_expn\ and \acl_smtp_vrfy\, respectively. Otherwise, + its responses are + +==> 550 Administrative prohibition + 252 Administrative prohibition + + Maybe the use of 252 is the ``problem''. It is recommended that this be + done (by those that discuss these things) because there are stupid + clients that attempt VRFY before sending a message. + + +Q0718: Could anyone points me to right rules to prevent sending/receiving + messages to/for domains which have one MX to localhost or only have + address 127.0.0.1 ? + +A0718: See Q0319. + + +Q0719: I would like to have a per-user limit for the maximum size of messages + that can be sent. + +A0719: The simplest way to do this is to put something in a system filter along + these lines: + +==> if $message_size is above + "${lookup{$sender_address}lsearch{/some/file}{$value}{10M}}" + then + fail "Message is larger than $sender_address is allowed to send" + endif + + In practice, an additional check that the message has arrived from your + local host or local network is probably wise because sender addresses + are easily forged. + + +Q0720: I set \"accept hosts=192.168.122.96/32"\ in order to accept mail for + relaying from my local LAN, but it doesn't work. What's wrong? + +A0720: 192.168.122.96/32 is not a network, it is a single host. Exim uses CIDR + notation for specifying networks, where the number after the slash is + the number of bits in the IP address that must match. Your setting says + ``32 bits must match''. If you really mean to specify ``the next 32 + IP addresses'', you need 192.168.122.96/27. + + +Q0721: I have POP-before-SMTP set up on my Exim server, but some clients use + Outlook Express, which sends queued messages before checking the + mailbox, so it doesn't work. + +A0721: Implement SMTP authentication. + + +Q0722: I installed Amavis and it is working, but bounces are simply vanishing. + +A0722: Check that you haven't inadvertently set up the transport like this: + +==> amavis: + driver = pipe + command = "/usr/sbin/amavis -f ${sender_address} -d ${pipe_addresses}" + + The last line should be: + +==> command = /usr/sbin/amavis -f <$sender_address> -d $pipe_addresses + + The important thing is the <> around the sender address; removal of + the unnecessary "" and {} is just tidying. See the amavis FAQ at + \?http://www.amavis.org/amavis-faq.php3?\. + + +Q0723: I can't get Pine to work with PLAIN authentication; Exim keeps + responding "535 Incorrect authentication data". + +A0723: You need to have this setting in your PLAIN authenticator: + +==> server_prompts = : + + This is missing in the examples in all but the most recent Exim + documentation, because it was not realized that PLAIN authentication + could be requested by a client without sending the data with the + request. If the data is not sent, an empty prompt is expected. + + +Q0724: I have used \":fail:"\ in some aliases; when one of these addresses is + refused, I see the message on the log, but the response to the remote + user is ``unknown user'' instead of the message from the alias file. + How can I change this? + +A0724: Have you got a \message\ qualifier in the relevant ACL? Exim uses the + message line in the ACL in preference to the message returned by the + router. This is so you can restrict the amount of information that + ``escapes'' from your site via SMTP if you want to. Remove the \message\ + line in the ACL entry that has \"verify = recipient"\ and your message + will get through. + + Alternatively, if you are running Exim 4.10 or later, you can use the + \$acl_verify_message$\ variable in your message to include the message + from the router. See also Q0725. + + +Q0725: I've set up some specific rejection messages for certain recipients, but + when I test them, the SMTP message is always \*550 5.1.1 + <user@mydomain.com>... User unknown*\. + +A0725: That is not an Exim message (the ``5.1.1'' is a clue; Exim doesn't use + those extended codes). You are probably being defeated by software that + sees the 550 error code, and insists on putting in its own text. There + is stupid software that does this. You can test Exim by using \-bh-\ or + making a telnet call to the SMTP port. That way, there's no other + software intervening. + + +Q0726: My SMTP authentication can be bypassed by sending an unknown user name + and an empty password. What is wrong with this condition in a PLAIN + authenticator? + +==> server_condition = ${if eq{$2} {${lookup mysql{SELECT password FROM \ + accounts WHERE username='${local_part:$1}'}}}{1}{0}} + +A0726: Your lookup item returns an empty string when the user does not exist. + You should instead arrange for the lookup to fail: + +==> server_condition = ${if eq{$2} {${lookup mysql{SELECT password FROM \ + accounts WHERE username='${local_part:$1}'}{$value}fail}}{1}{0}} + + +Q0727: When a message has many recipients, how can I stop SpamAssassin from + being called for each of them? I'm running it from a pipe transport. + +A0727: In the transport configuration, set \batch_max\ to a value greater than + one. + + +Q0728: How do I use Exiscan, SA-Exim, SpamAssassin, Clam Antivirus, Sophos + SAVI, or sophie with Exim? + +A0728: There's a mini-HOWTO about these available via + \?http://www.timj.co.uk/linux/exim.php?\. + See also sample configuration C047. + + +Q0729: How can I screen out addresses that are neither valid usernames or + distribution lists on mail being forwarded to an internal Win2K server? + +A0729: A user suggested using a router like this to do the recipient + verification: + +==> verify_user_router: + driver = accept + domains = win2kdomain.com + local_parts=\ + ldap;user="cn=ldap-guest,cn=Users,dc=win2kdomain,dc=com"\ + pass=guest \ + ldap:://win2kpdc/dc=win2kdomain,dc=com?mailNickname?\ + sub?(&(mailNickname=$local_part)\ + (showInAddressBook=*)(sAMAccountName=*)) + verify_only + + Set up ldap-guest as a normal domain user on the Win2K PDC. + + Also, you need to set \no_verify\ on all the other routers that handle + that domain. + + +Q0730: How can I use the same passwords for SMTP authentication as I use for + Courier IMAP access to my server? + +A0730: You can access the Courier authdaemon from an Exim authenticator. You + must arrange for the Exim user (often \/exim/\ but sometimes \/mail/\) + to be able to access \(/var/run/courier/authdaemon/socket)\. The + configuration is something of a hack, but it is reported to work. Here + is a LOGIN authenticator: + +==> login: + driver = plaintext + public_name = LOGIN + server_prompts = Username:: : Password:: + server_condition = \ + ${if eq {${readsocket{/var/run/courier/authdaemon/socket}\ + {AUTH 76\n${length_76:exim\nlogin\n$1\n$2\ + \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ + \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ + \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n}}}}{FAIL\n} {no}{yes}} + server_set_id = $1 + + Here is a PLAIN authenticator: + +==> plain: + driver = plaintext + public_name = PLAIN + server_prompts = : + server_condition = \ + ${if eq {${readsocket{/var/run/courier/authdaemon/socket}\ + {AUTH 76\n${length_76:exim\nlogin\n$2\n$3\ + \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ + \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\ + \n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n}}}}{FAIL\n} {no}{yes}} + server_set_id = $2 + + +Q0731: Is there any defence I can use against spam sent through an open proxy? + +A0731: The \*ident*\ feature can be used in some cases. See the discussion in + Q5023. + + +Q0732: I would like to either warn or deny when a host uses an underscore in + the EHLO command. + +A0732: First, set + +==> helo_allow_chars = _ + + This tells Exim not to reject the EHLO or HELO command immediately. Once + you have done that, you can test for the underscore in an ACL. For + example, to log a warning for hosts in your LAN, and reject for other + hosts, you could do something like this: + +==> deny message = Underscores are not valid in host names + hosts = ! +lan_hosts + condition = ${if match{$sender_helo_name}{_}{yes}{no}} + +==> warn log_message = Accepted underscore from [$sender_host_address] + condition = ${if match{$sender_helo_name}{_}{yes}{no}} + + +Q0733: Is there any way to tell Exim not to lookup the IP address against any + DNS black list if the connection is over IPv6? + +A0733: Use this condition in your ACL: + +==> condition = ${if match{${mask:$sender_host_address/0}}\ + {${mask:::0/0}}{no}{yes}} + + From Exim 4.23 onwards, this can be simplified to + +==> condition = ${if isip6{$sender_host_address}{no}{yes}} + + +Q0734: How do MailScanner and Exiscan compare? What are the pros and cons? + +A0734: The big advantage of Exiscan is that it can reject messages at SMTP time + before you have accepted responsibility for them, which means you don't + have to deal with bouncing messages and thereby becoming a collateral + spammer. + + The big advantage of MailScanner is that it gives you much greater + control over the load on your machines. You configure it according to + the maximum processing capacity of your computer and it will not exceed + that; in fact because it deals with messages in batches the cost of + processing a message actually goes down slightly as the load increases, + because the per-batch costs are shared by more messages. + + With Exiscan, you have to rely on Exim's load protection mechanisms, + which basically means that you have to stop accepting messages when your + machine gets too loaded. This is bad if the machine happens to be an + SMTP smarthost. You therefore need more overcapacity with Exiscan than + with MailScanner. + + +Q0735: How can I block non-FQDNs in HELO/EHLOs? + +A0735: Many workstation clients send single-component names; take care that you + do not block legitimate mail. With that proviso, you can do it using + something like this in an ACL: + +==> drop message = HELO doesn't look like a hostname + log_message = Not a hostname + condition = ${if match{$sender_helo_name} \ + {\N^[^.].*\.[^.]+$\N}{no}{yes}} + + This means: Drop the HELO unless it contains a dot somewhere in the HELO + string, but the string may not begin or end with a dot. Thus, the + imposed minimum length is 3 characters. + + The data for HELO/EHLO doesn't have to be a host name; it may + legitimately be an IP address literal instead. The above test succeeds + with an IPv4 address literal, but if you want also to accept IPv6 + address literals, you will have to modify the regular expression. + + +Q0736: Is it possible to tell exim to drop the connection after a server + attempts to send a message to a number of unknown users? + +A0736: Yes. Use \$rcpt_fail_count$\ and the \^drop^\ ACL command, as in this + example: + +==> drop message = Too many unknown users + condition = ${if >{$rcpt_fail_count}{15}{yes}{no}} + + +Q0737: Is there some way to tell Exim not to consider 127.0.0.1 as a valid MX? + +A0737: See Q0319. + + +Q0738: How can I configure Exim to delay the SMTP connection if more than 10 + invalid recipients are received in one message? + +A0738: Put something like this in your RCPT ACL: + +==> deny message = Max $rcpt_fail_count failed recipients allowed + condition = ${if >{$rcpt_fail_count}{10} {1}} + ! verify = recipient + delay = ${eval: $rcpt_fail_count * 10}s + log_message = $rcpt_fail_count failed recipient attempts + + This example increases the delay for each failed recipient. + + +Q0739: Does Exim support SPF? + +A0739: An Exim ACL can be used. See \?http://spf.pobox.com/downloads.html?\. + + + +8. REWRITING ADDRESSES + +Q0801: How can I get Exim to strip the hostname from the sender's address? + +A0801: If you set up a rewriting rule in the following form: + +==> *@*.your.domain $1@your.domain + + then Exim will rewrite all addresses in the envelope and the headers, + removing anything between \"@"\ and \"your.domain"\. This applies to all + messages that Exim processes. If you want to rewrite sender addresses + only, the the rule should be + +==> *@*.your.domain $1@your.domain Ffrs + + This applies the rule only to the envelope sender address and to the + ::From::, ::Reply-to::, and ::Sender:: headers. + + +Q0802: I have Exim configured to remove the hostname portion of the domain on + outgoing mail, and yet the hostname is present when the mail gets + delivered. + +A0802: Check the DNS record for your domain. If the MX record points to a CNAME + record instead of to an A record, some MTAs (not Exim) are liable to + rewrite addresses, changing your domain name to its ``canonical'' form, + as obtained from the CNAME record. + + +Q0803: I want to rewrite local addresses in mail that goes to the outside + world, but not for messages that remain within the local intranet. + +A0803: You can use the \headers_rewrite\ option on a transport to do this. + The rewriting will then apply to just those copies of a message that + pass through the transport. The \return_path\ option can similarly be + used to rewrite the sender address. There is no way of rewriting + recipient addresses at transport time. However, as these are by + definition remote addresses, you probably don't want to rewrite them. + + You have to set up the configuration so that it uses different SMTP + transports for internal and external mail. If you are using a single + router in both cases, you could configure it like this: + +==> dnslookup: + driver = dnslookup + transport = ${if match{$domain}{\N\.my\.domain$\N}{int_smtp}{ext_smtp}} + + This example uses the \%int_smtp%\ transport for domains ending in + \(.my.domain)\, and \%ext_smtp%\ for everything else. The \%ext_smtp%\ transport + could be something like this: + +==> ext_smtp: + driver = smtp + headers_rewrite = *@*.my.domain \ + ${lookup{$1}cdb{/etc/$2/mail.handles.cdb}{$value}fail} + return_path = \ + ${if match{$return_path}{\N^([^@]+)@(.*)\.my\.domain$\N}\ + {\ + ${lookup{$1}cdb{/etc/$2/mail.handles.cdb}{$value}fail}\ + }\ + fail} + + This example uses a separate file of local-to-external address + translations for each domain. This is not the only possibility, of + course. The \headers_rewrite\ and \return_path\ options apply the same + rewriting to the header lines and the envelope sender address, + respectively. + + +Q0804: I'm using this rewriting rule to change login names into ``friendly'' + names, but if mail comes in for an upper case login name, it doesn't + get rewritten. + +==> *@my.domain ${lookup{$1}dbm{/usr/lib/exim/longforms}\ + {$value}fail}@my.domain bcfrtFT + + The longforms database has entries of the form: + +==> ano23: A.N.Other + +A0804: Replace \"$1"\ in your rule by \"${lc:$1}"\ to force the local part to lower + case before it is used as a lookup key. + + +Q0805: Is it possible to completely fail a message if the rewrite rules fail? + +A0805: It depends on what you mean by ``fail a message'' and what addresses you + are rewriting. If you are rewriting recipient addresses for your local + domain, you can do: + +==> *@dom.ain ${lookup{$1}dbm{/wher/ever}{$value}{failaddr}} Ehq + + and in your alias file put something like + +==> failaddr: :fail: Rewriting failed + + This fails a single recipient - others are processed independently. + + +Q0806: I'm using \$domain$\ as the key for a lookup in a rewriting rule, but its + contents are not being lowercased. Aren't domains supposed to be handled + caselessly? + +A0806: The value of \$domain$\ is the actual domain that appears in the address. + It could of course be lower cased, but I know that would cause some + unhappiness, because some people have mixed-case domain names which look + silly if the case is changed. Thus, one wants to preserve the case in + rewrites such as + +==> *@*.TheRap.com something@$domain + + because ``therap'' doesn't look like two words. I know it seems trivial, + but it is important to some people - especially if by some unfortunate + accident the lowercased word is something indecent. + + You can trivally force lower casing by means of the \"${lc:"\ operator. + Instead of \"$domain"\ write \"${lc:$domain}"\. + + +Q0807: I want to rewrite local sender addresses depending on the domain of the + recipient. + +A0807: In general, this is not possible, because a message may have more than + one recipient and Exim keeps just a single copy of each message. It may + also deliver one copy of a message with several recipient addresses. + You can do an incomplete job by using a regular expression match in a + rewrite rule to test, for example, the contents of the ::To:: header. This + would work except in cases of multiple recipients. + + + +9. HEADERS + +Q0901: I would like add some custom headers to selected outgoing mail based on + a specific domain and the subject line. + +A0901: To the remote_smtp transport, add something like + +==> headers_add = ${if and{\ + {eq{$domain}{spec.dom}}\ + {matches{$h_subject:}{whatever}}}\ + {Content-Type: text/html; charset="us-ascii"} fail } + + This example shows a ::Content-Type:: header, but you can have anything you + like, and multiple headers can be inserted by using \"@\n"\ to separate them. + + +Q0902: Is it possible to have Exim add a header to only certain local parts of + outgoing mail? + +A0902: Only if you arrange for each such local part to receive its own private + copy of the mail. See \max_rcpt\ in the SMTP transport. If you set this + to 1, you could use conditions in an expansion string to add or not add + a header. + + +Q0903: How can I remove some part of the ::Received:: header? + +A0903: Set \received_header_text\. + + +Q0904: How I can insert the PGP header line using Exim filters? + +A0904: You can't insert headers in a user filter. A system filter can do so, + but the inserted lines then are included for all recipients. + + +Q0905: I know I can use a system filter to replace certain headers in messages, + but how can I add text to existing headers? I want to add [SPAM] to + the subject line of messages that appear to be spam. + +A0905: You can only do this in a round about way, using filter commands like + this: + +==> headers add "New-Subject: SPAM: $h_subject:" + headers remove subject + neaders add "Subject: $h_new-subject:" + headers remove new-subject + + This trick works only in system filters, where the commands are obeyed + in order, and affect the master list of headers that apply to the whole + message. You cannot do this with the \headers_add\ and \headers_remove\ + options on drivers. + + + +10. PERFORMANCE + +Q1001: I'm running a large mail server. Should I set \split_spool_directory\ to + improve performance? + +A1001: Splitting the spool directory has most benefit if there are times when + there are a large number of messages on the queue. If all mail is + delivered very quickly, and the queue is always less than, say, a few + hundred messages, there isn't any need to do this. With larger queues, + there is a definite performance benefit to splitting the spool. It shows + up earlier on some types of filing system, compared with others. + + Exim was not designed for handling large queues. If you are in an + enviroment where lots of messages remain on the queue for long periods + of time, consider implementing a back up host to which you pass these + messages, so that the main host's queue remains short. You can use + \fallback_hosts\ to do this, or a router that is conditional on + \$message_age$\. + + +Q1002: How well does Exim scale? + +A1002: Although the author did not specifically set out to write a high- + performance MTA, Exim does seem to be fairly efficient. The biggest + server at the University of Cambridge (a large Sun box) goes over + 100,000 deliveries per day on busy days (it has over 20,000 users). + There was a report of a mailing list exploder that sometimes handles + over 100,000 deliveries a day on a big Linux box, the record being + 177,000 deliveries (791MB in total). Up to 13,000 deliveries an hour + have been reported. + + These are quotes from some Exim users: + + "... Canada's largest internet provider, uses Exim on all of our mail + machines, and we're absolutely delighted with it. It brought life back + into one of our machines plagued with backlogs and high load averages. + Here's just an example of how much email our largest mail server + (quad SS1000) is seeing ... " [230,911 deliveries in a day: 4,475MB] + + "... Exim has to ... do gethostbyname()s and RBL lookups on all of the + incoming mail servers, and he runs from inetd (TCP Wrappers connected). + All the same, it seems to me that he runs as fast as lightning on our + SCO 5.0.4 box (1 Pentium 166) - far faster than MMDF which I (and many + customers) had before." + + "On a PII 400 with 128M of RAM running Linux 2.2.5, I have achieved + 36656 messages per hour (outgoing unique messages and recipients). For + about a 5 minute period, I was able to achieve an average of 30 messages + per second (that would be 108000 m/hour)! We are using: (options that + make a difference): + +==> queue_only + split_spool_directory + queue_run_max = 1 + remote_max_parallel = 1 + + We have a cron job hat runs every five minutes that spawns 5 \"exim -q"\ if + there are less that 120 exim processes currently running. We found + that by manually controlling the concurrency of \"exim -q"\ processes + contending for the spool for \%remote_smtp%\ delivery that we gained + considerable performance - 10000 m/hour." + + +Q1003: We have a large password file. Can Exim use alternative lookups during + delivery to speed things up? + +A1003: If you are using FreeBSD, this problem should not arise, because it + automatically uses an indexed password file. In some other operating + systems you can arrange for this to happen too. On Linux, for example, + all you need to do is + +==> # cd /var/db + # make + + and put \"db"\ before \"files"\ in any \(/etc/nsswitch.conf)\ lines you want to + use db for. + + On systems that do not include support for indexed password files, you + can build one yourself, and reference it from the Exim configuration. + For example, for routing to local mailboxes you could use this: + +==> localuser: + driver = accept + condition = ${lookup{$local_part}cdb{/etc/passwd.cdb}{yes}{no}} + transport = local_delivery + user = ${extract{1}{:}{${lookup{$local_part}cdb{/etc/passwd.cdb}}} + + This assumes a cdb version of the password file. + + +Q1004: I just wondered if it might be helpful to put the hints database on a + RAM disk during regular operation. Did anybody try that yet? + +A1004: A user reported thus: ``I have found that this works great under Solaris. + Make a RAM disk partition and keep everything in the \(db)\ directory on + it. However, when I try the same thing on Linux, I don't see the same + boost. I think that Linux's file buffer cache works about the same. + Plus, this leave more room for processes to run.'' + + There have been other reports that Linux's delayed buffer write provides + better overall performance in general. + + Apparently there is support in the Solaris kernel for a delayed writing, + as in Linux, but Sun's server policy is to have it disabled so that you + don't lose so much if the server crashes. There is a program called + \^fastfs^\ to enable and disable this support. You have to download and + compile it yourself; find it by looking for \"fastfs.c"\ in a search + engine. Solaris performance is reported to be much improved, but you + should take care to understand the potential hazards. In particular, + \^fsck^\ may be unable to ``fix'' disks automatically after a crash. + + +Q1005: A lot of incoming mail is pushing up my system load too much, and there + are many Exim processes. How can I control this? + +A1005: Have you set any of the Exim configuration options that limit what it + does under high load? For example, queue_only_load, deliver_queue_load_max? + See the list in the section entitled \*Resource control*\ in the manual. + + It sounds like a lot of simultaneous incoming mail pushes your system + into uncontrolled overload. The multiple Exim processes are probably + just multiple incoming messages. You can use the \^exiwhat^\ utility to + confirm this. + + + +11. MAJORDOMO + +Q1101: How do I set up Majordomo to work with Exim? + +A1101: Users have found several ways of setting up Exim for use with Majordomo. + One way has been documented at + \?http://www.averillpark.net/exim/majordomo.html?\. + + Somewhere in the Majordomo docs or FAQ it mentions using batchmail or + other additional programs to improve the performance of large lists. + They are not needed with Exim, and their use can actually make things + worse. However, it's a good idea to set \remote_max_parallel\ to a value + greater than 1 in the Exim configuration. + + +Q1102: I have set \$mailer$\ in \(majordomo.cf)\, but it still isn't setting the + sender correctly in the messages it sends. + +A1102: Make sure you have got the quoting correct in the \$mailer$\ setting. For + example, + +==> $mailer = "$sendmail_command -oi -oee -f$sender\@lists.mydomain.de"; + + is not correct. It needs three backslashes, not one, and the $ at the + start of \$sender$\ has to be escaped with a backslash. + + +Q1103: I'm trying to set up majordomo, but I'm getting a wrong mode error + when I try to send it mail. + +A1103: Check the mode of \(/var/lib/majordomo/lists/lists.aliases)\ and compare it + with the setting of the \modemask\ option in the Majordomo aliases + router. This option specifies bits which must not be set for the alias + file, and it defaults to 022. + + +Q1104: I'm getting return code 9 from \(/home/majordomo/majordomo-1.94.4/wrapper)\ + when it is passed a message from Exim. + +A1104: A problem like this turned out to be the Perl version that came with + RedHat 5.2. Rebuilding Perl 5.005x solved it. + + +Q1105: Exim is complaining about an invalid command line when Majordomo tries + to send it a message for delivery. + +A1105: Take a look at your \(majordomo.cf)\ file, It should have something that + looks like + +==> $sendmail_command = "/usr/lib/sendmail"; + + and another line like + +==> $mailer = "$sendmail_command -oi -oee -f\$sender"; + + If you have modified \^resend^\ (one of the majordomo programs) to use + \$sendmail_command$\ instead of \$mailer$\ you will be calling Exim with no + command line arguments. + + + +12. FETCHMAIL + +Q1201: When I run fetchmail, I get the error \*SMTP listener doesn't like + recipient address xxx@localhost*\. + +A1201: Make sure that //localhost// is recognized as a domain that is to be + delivered locally. If you are using the default Exim run time + configuration, you'll see a line near the top like this: + +==> domainlist local_domains = @ + + Change it to + +==> domainlist local_domains = @ : localhost + + +Q1202: I'm currently using Exim with fetchmail and I'd like to use the RBL on + Exim, but will it work? Do I need to configure fetchmail any particular + way? As far as Exim knows, all mail is coming from 127.0.0.1. Will it + check the source address against RBL? Or will it check the ::From:: header? + +A1202: It will check 127.0.0.1 (not very useful). The point of the RBL is to + keep messages from black-listed hosts out of your machine. If you are + using fetchmail, you have got the messages into your machine before you + approach Exim. That kind of defeats the purpose of the RBL. The right + way to do this would be for the host from which you fetch your mail to + do the RBL checking and insert some kind of warning header for you to + test, as Exim does if you run RBL checks in warning mode. + + + +13. PERL + +Q1301: Exim built with Perl support exits with the error message \*./exim: can't + load library 'libperl.so'*\. + +A1301: If you are using BSDI, see Q9401. + + +Q1302: Exim built with Perl support exits with several error messages of the + form \*undefined reference to `PL_stack_sp'*\. + +A1302: This has been seen on FreeBSD systems that had two different versions of + Perl installed, the older with an \^a.out^\ library and the newer with an + ELF library. Ensure that the older package is removed. + + + +14. DIAL-UP AND ISDN + +Q1401: When I'm not connected to the Internet, how can I arrange for mail to + other hosts on my local network to be delivered, while at the + same time mail to Internet hosts is queued without any delivery + attempts? + +A1401: Use the \queue_domains\ option to control which domains are held + on the queue for later delivery. For example, + +==> queue_domains = ! *.localnet + + allows delivery to domains ending in \(.localnet)\, while queueing all the + others. + + +Q1402: I have a dial-up machine, and I use the \queue_smtp_domains\ option so + that remote mail only goes out when I do a queue run. However, any email + I send with an address \(anything@aol.com)\ is returned within about 15 + minutes saying \*retry time exceeded*\, and all addresses are affected. + +A1402: You should be using \queue_domains\ rather than \queue_smtp_domains\. + With the latter, Exim is trying to route the addresses, which involves a + DNS lookup. This is presumably timing out, causing a retry time to be + set for the domain, and somehow a valid lookup never happened before the + maximum retry time (default of 4 days) passed. Hence the bounce. The + fact that it is \(aol.com)\ is probably not relevant. You should probably + also be using \-qq-\ to do your queue run rather than \-q-\. + + +Q1403: How should Exim be configured when it is acting as a temporary storage + system for a domain on a dial-up host? + +A1403: Exim isn't really designed for this, but... The lowest-numbered MX + record for the domain should be pointing to the dial-up host. A higher + numbered MX record (lower priority) should point to the Exim server that + is acting as a temporary storage system. + + You should set a large retry time for the domain, so that Exim doesn't + keep trying to deliver when the host is offline. When the host comes + online, the waiting messages have to be kicked somehow. This can be done + by calling Exim with the \-R-\ option, or via the SMTP ETRN command. + + This works provided the number of messages is low. If you are handling + lots of mail, keeping messages waiting for their host to connect and + those that are having delivery problems to remote hosts all in the same + queue doesn't work so well. It is better in this case to get Exim to + deliver the mail for the dial-in hosts into some local files which then + get transmitted by other software when the host connects. One tool for + doing this can be found at \?http://cr.yp.to/serialmail.html?\. + + For further discussion, see section entitled \*Intermittently connected + hosts*\ in the manual, and also the section in the Exim book with the + same name. + + +Q1404: I have \queue_domains\ or \queue_smtp_domains\ set, and use \-qf-\ to + force delivery of waiting mail when I dial in. How can I arrange for any + new messages that arrive while I'm connected to be delivered immediately? + +A1404: Instead of \queue_domains\ or \queue_smtp_domains\, use the \queue_only_file\ + option. This causes messages to be queued if a particular file exists. + If you put the word ``smtp'' before the file name, the queueing applies + only to domains that are delivered by SMTP, thus not affecting local + deliveries: + +==> queue_only_file = smtp/etc/present/when/not/connected + + Then, in the scripts which are run when you connect and disconnect, + arrange to remove the file after connection, and create it just before + disconnection. + + +Q1405: I have an ISDN connection and would like a way of running the queue + automatically when it is up. + +A1405: The following shell commands test for the interface being up and then + run the queue: + +==> ifconfig ppp0 | fgrep UP >/dev/null + if [ $? -eq 0 ] ; then exim -q ; fi + + You could put these commands into a script which runs them at regular + intervals. You might want to use \-qq-\ instead of \-q-\. + + With Linux, the script \(/etc/ppp/ip-up)\ is run after a ISDN connection + or a more general PPP connection has been established. If you are using + Linux, you could put the call to Exim in that script. + + +Q1406: When I dial up to collect mail from my ISP, only the first 10 messages + get delivered immediately; the remainder just sit on the queue until a + queue runner process finds them. + +A1406: See Q0049. + + +Q1407: RFC 1985 specifies that the SMTP command \"ETRN host.domain"\ causes all + mail queued for that host, no matter what domain it's for, to be + delivered. Why doesn't Exim support this? + +A1407: Exim does not keep queues of mail for specific destinations. It just + keeps one pool of undelivered messages. What is more, once you start a + delivery of a message, it tries to deliver to all the addresses in the + message, not just the one you may be interested in. (Of course, this + doesn't usually do any harm.) + + The only way it could be done within Exim would be, for every message + on the queue, to go through the motions of routing each undelivered + address and see if that resulted in a delivery to the host of interest. + This could be extremely expensive (e.g. 1,000 messages on the queue, + only 1 for the given host). + + The bottom line is that Exim just wasn't designed for this kind of + operation, that is, holding messages for intermittently connected hosts. + The queueing arrangements are designed for handling delivery problems + that are not expected to be common. + + A better way to do this is to implement the required queues separately. + After all, keeping such mail on an active queue (where Exim will keep + trying to deliver) is silly. If there is a lot of mail for these hosts, + it also masks genuine delivery problems when you inspect the queue. + + Large ISPs who provide this kind of functionality do not usually leave + waiting mail on the MTA's queue. Instead, they get it delivered into + per-host directories, one message per file, in one of the special + formats (BSMTP, maildir, or mailstore) and when an ETRN arrives, it + kicks off some completely different program that establishes an SMTP + connection to the host and shovels the waiting mail down it. That seems + to me to be a much neater way of doing this. It means you can easily add + additional functionality such as archiving or throwing away uncollected + mail. + + One program that has this functionality is \^ssmtp^\, which can be + found in \?ftp://metalab.unc.edu/pub/Linux/system/mail/mta/?\. + Alternatively, sample configuration C037 demonstrates an elegant way of + using Exim itself to deliver the saved messages when the client issues + an ETRN. + + +Q1408: If email has been deferred to a member on a local mailing list + (implemented through forward files), and one of our ETRN clients is on + this mailing list, the \-R-\ won't flush the mailing list message for + that client. + +A1408: That is because \-R-\ matches only original recipient addresses, not those + produced as a result of expansion, because these are not (by default) + preserved from delivery to delivery. You can get round this by setting + \one_time\ on the forwarding router, but you are not allowed to have + expansions to pipes or files on routers that have \one_time\ set. + Therefore, you will have to have a separate router for mailing lists + (with \one_time\ set) to the one used for normal forward files that might + specify pipe or file deliveries. However, the problem will still be + present for any user who sets up a \(.forward)\ file to redirect to any of + the ETRN domains. See the last 3 paragraphs of Q1407 for a discussion of + an alternative approach. + + +Q1409: I would like to have a separate queue per domain for hosts which dial + in to collect their mail. + +A1409: Exim isn't really designed for this kind of operation. The only way to + do this would be to cause it to send those messages to a differently + configured version of Exim with its own spool area. This could be done + via a pipe or SMTP to a private port. The main Exim, listening on port + 25, would then be configured to run an appropriate command to prod one + of the others when it received ETRN, by means of the \smtp_etrn_command\ + option. + + You could probably manage this with a single Exim binary and a number of + different configuration files, passed to the special versions using the + \-C-\ option. For this application they could all run as \^exim^\, since no + root privilege would be needed. + + An alternative approach id to get Exim to deliver mail for such hosts + in batch SMTP format into some directory, and have the ETRN run + something to pass such messages to the dialled-in host. See also Q1403. + + + +15. UUCP + +Q1501: The MX records for some UUCP domains point to my local host. How do I + get it to pass the messages on to UUCP? + +A1501: The simplest way is to create a file containing a list of domains, and + the hosts to which their messages should be sent, like this: + +==> uucp1.domain.example: uucp1.host.example + uucp2.domain.example: uucp2.host.example + .... + + Then you can use a router like this: + +==> uucp_router: + driver = accept + domains = lsearch;/etc/uucp/domains + transport = uucp_transport + + and a transport like this: + +==> uucp_transport: + driver = pipe + user = nobody + command = /usr/local/bin/uux - -r $domain_data!rmail $local_part + return_fail_output + + The \$domain_data$\ variable retains the value that is looked up when + the \domains\ option in the router is matched. + + +Q1502: How can I get Exim to handle ``bang path'' addresses? + +A1502: In general, you can't (Exim is an Internet mailer and recognizes only + RFC 2822 domain-style addresses) but some restricted kinds of bang path + can be dealt with by appropriate rewriting - but please note the warning + below. + + Exim treats a bang path address as an unqualified local part, and so + will qualify it with your domain. A rule such as + +==> \N^([^!]+)!(.+)@your\.domain$\N $2@$1 + + turns \(a!b@your.domain)\ into \(b@a)\. You can also use a repeating rule to + turn multi-component paths into the ``percent hack'' notation with a rule + such as + +==> \N^([^!]+)!([^@%]+)(.+)$\N $2%$1$3 R + + which turns \(a!b@c)\ into \(b%a@c)\ and \(a!b!c@d)\ first into \(b!c%a@d)\ and then, + because of the R flag, into \(c%b%a@d)\. The R flag causes repetition up to + 10 times. + + \**Warning:**\ If you install a general rewriting rule like the above, you are + opening yourself up to the possibility of unwanted relaying. A host that + is not permitted to relay through your system could send a message with + an SMTP command line such as + +==> RCPT TO:<victim-host!victim-user@your.domain> + + and this would be accepted because it is addressed to your domain. + However, the rewriting then converts the address, and the message does + in fact get relayed. One way round this, if all your bang path messages + are passed to Exim via SMTP, is to use the \"S"\ rewriting flag. This + applies a rewriting rule to incoming SMTP addresses as soon as they are + received, before checking for qualification, relaying, etc. So a rule + such as + +==> \N^([^!]+)!(.+)$\N $2@$1 S + + rewrites simple two-component bang paths before the result is checked + for relaying. However, this does not rewrite addresses in the headers of + the message. + + +Q1503: We see something strange on our system in regards to mail coming in via + rmail from a UUCP link. The sender is being set to mailmaster instead of + the real sender, and a ::Sender:: header is being added to the message. + +A1503: If \(mailmaster)\ is the user that is running rmail, you need to include + that user in the \trusted_users\ configuration option. Only trusted users + are permitted to specify senders when mail is passed to Exim via the + command line. + + + +16. MODIFYING MESSAGE BODIES + +Q1601: How can I add a disclaimer or an advertisement to a message? + +A1601: There are a number of technical and potential legal problems that arise + in connection with message modification. Some of them are listed below. + Some comment on the legal position of email disclaimers in English law + can be found at \?http://www.weblaw.co.uk/artemail.htm?\. + + See also \?http://www.goldmark.org/jeff/stupid-disclaimers/?\. There is + some discussion about the problems of actually adding disclaimers in + \?http://www.goldmark.org/jeff/stupid-disclaimers/apply.html?\. + + In many cases, email disclaimers will make your company look ridiculous, + at the very least. At worst, they may interfere with the normal + processing of mail. + + If, despite these considerations, you still want to modify messages, you + can do so using Exim, but not directly in Exim itself. It is not the job + of an MTA to modify messages, something that requires understanding of + their content and format. + + Exim provides a hook called a ``transport filter'' that lets you pass + any outgoing message through a program or script of your choice. It + is the job of this script to make any changes to the message that you + require. By this means, you have full control over what changes are + made, and Exim does not need to know anything about message bodies. + However, using a transport filter requires additional resources, and may + slow down mail delivery. + + You can use Exim's routers to arrange for those messages that you want + to modify to be delivered via a transport filter. For example, suppose + you want to do this for messages from addresses in your domain that are + being delivered to a remote host. First you need to set up a special + \%smtp%\ transport that uses a filter, like this: + +==> remote_smtp_filter: + driver = smtp + transport_filter = /your/filter/command + + Then you need to modify the \%dnslookup%\ router to use this transport + when the conditions are right: + +==> dnslookup: + driver = dnslookup + domains = ! +local_domains + transport = ${if eq {$sender_address_domain}{your.domain}\ + {remote_smtp_filter}{remote_smtp}} + ignore_target_hosts = 127.0.0.0/8 + no_more + + This is the standard \%dnslookup%\ router, but with a modified setting of + the \transport\ option. When the sender address is in your domain, it + routes to the special transport instead of the standard one. + + The entire message is passed to your filter command on its standard + input. It must write the modified version to the standard output, taking + care not to break the RFC 2822 syntax. The command is run as the Exim + user. + + There are a number of potential problems in doing this kind of + modification in an MTA. Many people believe that to attempt is it wrong, + because: + + 1. It breaks digital signatures, which are becoming legally binding + in some countries. It may well also break encryption. + + 2. It is likely to break MIME encoding, that is, it is likely to wreck + attachments, unless great care is taken. And what about the case of a + message containing only binary MIME parts? + + 3. It is illegal under German and Dutch law to change the body of + a mail message in transit. It might potentially be illegal in + the UK under European law. This consideration applies to ISPs and + other ``common carriers''. It would presumably not apply in a corporate + environment where modification was done only to messages originating + from the employees, before they left the company's network. It might + also not apply if the senders have explicitly given their consent + (e.g. agreed to have advertisements added to their incoming mail). + + 4. Since the delivered message body was produced by the MTA (not the + originator, because it was modified), the MTA operator could + potentially be sued for any content. This again applies to `common + carrier' MTAs. It's interesting that adding a disclaimer of liability + could be making you liable for the message, but this case seems + more likely to involve adding advertisements than disclaimers. After + all, no postal service in the world opens all the mail it carries to + add disclaimers. + + 5. Some mail clients (old versions of MS outlook) crash if the message + body of an incoming MIME message has been tampered with. + + There are also potential problems that could arise if a scheme to add + disclaimers goes wrong for some messages: + + 1. False negatives: `Ah, this guy usually says he does not represent + their views, but in this message he doesn't have the disclaimer'. + + 2. False positives: `This official announcement does not represent our + views, oh no'. + + An alternative approach to the disclaimer problem would be to insist + that all relevant messages have the disclaimer appended by the MUA. The + MTA should refuse to accept any that do not. Again, however, the MTA + must understand the format of messages in order to do this. Simply + checking for appropriate wording at the end of the body is not good + enough. It would probably be necessary to run a Perl script from within + an Exim system filter, or write a \^^local_scan()^^\ function in order + to adopt this approach. + + Finally, it's a trivial matter to add customized headers of the sort: + +==> X-Disclaimer: This is a standard disclaimer that says that the views + X-Disclaimer: contained within this message are somebody else's. + + which is a much easier alternative to modifying message bodies. + + +Q1602: How can I remove attachments from messages? + +A1602: The answer to this is essentially the same as for Q1601. + + + +17. ENCRYPTION (TLS/SSL) + +Q1701: I am trying to set up an Exim server that uses a self-signed certificate + to enable my clients to use TLS. However, clients other than Exim + refuse to accept this certificate. What's wrong? + +A1701: It seems that some clients require that the certificate presented by + the server be a user (also called ``leaf'' or ``site'') certificate, and not + a self-signed certificate. In this situation, the self-signed + certificate must be installed on the client as a trusted root + \*certification authority*\ (CA), and the certificate used by the server + must be a user certificate signed with that self-signed certificate. + + For information on creating self-signed CA certificates and using them + to sign user certificates, see the \*General implementation overview*\ + chapter of the Open-source PKI book, available online at + \?http://ospkibook.sourceforge.net/?\. Here is a quick overview. First, + read this message: + + \?http://www.FreeBSD.org/cgi/mid.cgi?id=3C3F3A93.C1ECF9B0%40mindspring.com?\ + + Then, follow the instructions found on these two (consecutive) pages: + + \?http://ospkibook.sourceforge.net/docs/OSPKI-2.4.6/OSPKI/initialisation.htm?\ + \?http://ospkibook.sourceforge.net/docs/OSPKI-2.4.6/OSPKI/keygensign.htm?\ + + Two points on the PKI Book literature: + + (1) It's assumed that it's okay to use a passphrase-protected key to + encrypt the user/site/leaf certificate. If this isn't acceptable, + you seem to be able to strip out the passphrase as follows: + +==> openssl rsa -in user.key -our user.key.new + mv user.key.new + + This should be done immediately after \(user.key)\ is created. + + (2) The \*sign.sh*\ script is available in the \*mod_ssl*\ distribution, + available at \?http://www.modssl.org/source/?\. + + Having followed the instructions, you end up with the following files: + + (a) \(ca.crt)\ + + This file should be installed into the client software as a trusted + root certification authority. In Windows XP, this can be done as follows: + + \#\#Call the file \(ca_cert.cer)\ + [[br]] + \#\#Double-click on the file + [[br]] + \#\#"Install Certificate"; + [[br]] + \#\#"Next" + [[br]] + \#\#"Place all certificates in the following store" + [[br]] + \#\#"Browse..." + [[br]] + \#\#"Trusted Root Certification Authorities" + [[br]] + \#\#"OK" + [[br]] + \#\#"Next" + [[br]] + \#\#"Finish" + [[br]] + \#\#"Yes" + [[br]] + \#\#"OK" + + (b) \(user.crt)\ and \(user.key)\ + + These files should be installed into the server software. In Exim, this + can be done by adding these lines to the configuration file: + +==> tls_certificate = /usr/local/etc/exim/tls_cert + tls_privatekey = /usr/local/etc/exim/tls_key + + Then install \(user.crt)\ and \(user.key)\ under the names \(tls_cert)\ + and \(tls_key)\ in the appropriate directory. + + +Q1702: How can I arrange for Exim to advertise support for SMTP authentication + only when the session is encrypted? + +A1702: Use this setting: + +==> auth_advertise_hosts = ${if eq{$tls_cipher}{}{}{*}} + + +Q1703: I have some legacy clients that don't use STARTTLS, but which expect to + negotiate a TLS session automatically on connection to the ssmtp port + (465). Can Exim handle this? + +A1703: The \-tls-on-connect-\ option is available to handle this. You need to + run two instances of an Exim listener, listening on different ports, one + of which is started with \-tls-on-connect-\. You can either use two + daemons, or a single daemon, with the other listenever using \^inetd^\. + For example, here are commands to start two daemons: + +==> exim -bd -q15m + exim -bd -oX '[0.0.0.0]::465' -tls-on-connect + + The first is a ``normal'' daemon; the second listens on port 465 and + expects to negotiate a TLS session at the start of each connection. + + +Q1704: When my Outlook Express 6.0 client sends a STARTTLS command to begin a + TLS session, Exim doesn't seem to receive it. + +A1704: See Q0059. + + +Q1705: I have listed some hosts in \tls_try_verify_hosts\, but when they + connect, no data appears in \$tls_peerdn$\. + +A1705: This means that the clients have not sent certificates when asked by + the server to do so. If the clients are running Exim, check that + \tls_certificate\ is correctly set in their \%smtp%\ transports. Note + that this value is not automatically inherited from the global + \tls_certificate\ option. + + +Q1706: I have listed some hosts in \tls_verify_hosts\ and provided them with + certificates, but their connections are always rejected. + +A1706: Make sure that the server file containing the expected certificates + (defined by \tls_verify_certificates\) is readable by the Exim user. + See also the answer to Q1705. + + +Q1707: I am trying to use TLS with Evolution as a client, and keep seeing this + error: \*SMTP protocol violation: synchronization error (next input + sent too soon): rejected "\200F^A^C".*\ What does it mean? + +A1707: See Q0086 for a general explanation of the error. In this case, it + probably means that Evolution is trying to negotiate a TLS session + immediately it connects, without first using the STARTTLS command. This + was an older way of starting up TLS, before STARTTLS was defined. You + will have to run a separate instance of Exim using the + \-tls-on-connect-\ command line option to cater for this usage, and + listening on a different port. For example: + +==> exim -bd -oX 465 -tls-on-connect + + 465 is the ``smtps'' port which is an unofficial standard for this kind + of SMTP server. + + +Q1708: I trying to use TLS with Outlook as a client on a box that is running + Norton Antivirus, but all my email is being rejected with \*Unsupported + command*\ errors. Why? + +A1708: Norton Antivirus does not support TLS or AUTH. It puts a broken SMTP + proxy between you and the Exim server. You need to turn off outbound + scanning of email. + + + +20. MILLENNIUM + +Q2000: Are there any Y2K issues with Exim? + +A2000: The author of Exim believes that it is Y2K-compliant, as long as the + underlying operating system and C library are. Exim does not parse dates + or times at all. Internally, it makes some use of binary timestamps in + Unix format (number of seconds since 1-Jan-1970) and uses C library + services to convert these to printing forms (e.g. for logging). The + printing forms all use 4-digit years. Some people have tried various + tests. No problems have been reported, but details of what tests have + been done are not available. + + Well, it's now November 2001, and no Y2K problems have been reported, so + it looks like I was right. This entry is retained as historical + nostalgia. + + + +50. MISCELLANEOUS + +Q5001: How can I arrange to allow a limited set of users to perform a limited + set of Exim administration functions? I don't want to put them all in + the //exim// group. + +A5001: See \?http://www.chiark.greenend.org.uk/~ian/userv/?\. Using \^userv^\ you can + arrange (for example) for certain users to be able to invoke \^mailq^\ or + \^runq^\ or other preset commands as \^exim^\ (or any other user, as configured) + with only \^userv^\ configuration. If you want to check the particular Exim + options available you can easily do it with shell or Perl scripts and + \^userv^\ configuration, and provided you know how to do argument + ``unparsing'' properly in shell or Perl it will be secure. + + +Q5002: I want to ``tail'' the Exim log, but I have a number of other logs I also + want to ``tail'', and the number of tailing windows is getting to be a + nuisance. + +A5002: Look for a program called \^xtail^\ (despite its name, it's not an + X-windows application). It allows you to do multiple tails, even of + entire directories. + + Alternately, get the GNU version of \^tail^\, from the GNU textutils + package (\?ftp://ftp.gnu.org/gnu/textutils/?\). GNU tail lets you run + \"tail -f\" on multiple files at the same time, although it doesn't work + on entire directories like \^xtail^\ can. If you are running Linux, you + probably already have a version of GNU \^tail^\ that can follow multiple + files. + + +Q5003: How can I persuade Exim to accept ETRN commands without the leading + # character? + +A5003: Set the option + +==> smtp_etrn_command = /usr/lib/sendmail -R $domain + + This causes Exim to run that command, with \$domain$\ replaced by the + argument of ETRN. The default action of Exim is to require the # sign + in order to be RFC-compliant, and to run the equivalent of + +==> smtp_etrn_command = /usr/lib/sendmail -R ${substr_1:$domain} + + which uses the argument without the leading # as the value for the \-R-\ + option. You aren't restricted to running Exim with the \-R-\ option, of + course. You can specify any command you like, with any number of + arguments. In particular, you can pass over the IP address of the caller + via \$sender_host_address$\. However, if you make use of expansion strings + in the arguments, each one must be entirely contained in a single + argument. For example, if you want to remove the first character of the + ETRN argument when it is @ or #, you could use + +==> smtp_etrn_command = "/usr/lib/sendmail -R \ + \"${if match {$domain}{^[@#]}{${substr_1:$domain}}{$domain}}\"" + + The internal quotes are necessary because of the white space inside the + expansion string. + + +Q5004: I've recently noticed that emails I send with a ::Bcc:: line are being + delivered to their final destination with the ::Bcc:: line still present. + +A5004: Exim removes ::Bcc:: lines only if you call it with the \-t-\ option (i.e. + when it is acting partly as an MUA). It does not remove ::Bcc:: lines that + are present in incoming SMTP mail or command-line mail that does not + use \-t-\. Indeed, it should not remove them, because only the + initiating software (i.e. the MUA) can tell what to do with ::Bcc:: + lines; any MTA software has to leave them alone. This is what RFC 2822 + has to say about ::Bcc:: + + \*The ::Bcc:: field (where the ``Bcc'' means ``Blind Carbon Copy'') contains + addresses of recipients of the message whose addresses are not to be + revealed to other recipients of the message. There are three ways in + which the ::Bcc:: field is used. In the first case, when a message + containing a ::Bcc:: field is prepared to be sent, the ::Bcc:: line is + removed even though all of the recipients (including those specified + in the ::Bcc:: field) are sent a copy of the message. In the second + case, recipients specified in the ::To:: and ::Cc:: lines each are sent + a copy of the message with the ::Bcc:: line removed as above, but the + recipients on the ::Bcc:: line get a separate copy of the message + containing a ::Bcc:: line. (When there are multiple recipient + addresses in the ::Bcc:: field, some implementations actually send a + separate copy of the message to each recipient with a ::Bcc:: + containing only the address of that particular recipient.) Finally, + since a ::Bcc:: field may contain no addresses, a ::Bcc:: field can be + sent without any addresses indicating to the recipients that blind + copies were sent to someone. Which method to use with ::Bcc:: fields + is implementation dependent, but refer to the ``Security + Considerations'' section of this document for a discussion of each.*\ + + +Q5005: I used \^gv^\ 3.5.8 (\^ghostview^\) to try printing \(spec.ps)\. After every + printed page, the printer ejects a blank sheet. Is this something to do + with using ``letter'' rather than A4 paper? + +A5005: This seems to be an effect of using \^ghostview^\. Although the PostScript + is generated for A4 pages, the size of the page images is such that they + should fit on a letter page (they are shorter than would normally be + used on A4 paper). If the PostScript file is sent directly to a + PostScript printer, there is no problem. An alternative is to get hold + of the \^psutils^\ toolset, which is available from + \?ftp://ftp.dcs.ed.ac.uk/pub/psutils/psutils.tar.gz?\. + It contains utilities for extracting pages (which can be useful for + double-sided printing) and for resizing pages. If you resize from A4 to + letter the text shrinks a bit, but should then be printable via + \^ghostview^\. + + +Q5006: Why aren't there any man pages for Exim? I don't always carry my printed + documentation. + +A5006: A single man page which lists the command line options is provided in + file \(doc/exim.8)\ in the Exim distribution. Several other forms of + online documentation are available. As well as plain ASCII text, the + there are two forms - Texinfo and HTML - which have a certain amount of + built-in indexing for ease of finding your way around. There are no man + pages apart from the command line one because the author of Exim hasn't + the time (or desire :-) to maintain yet another documentation format. + Besides, it is hard to know how to split the Exim manual up. + + +Q5007: When I send a message using the \-t-\ command line option, Exim sends only + to the addresses within the message, not to those on the command line. + +A5007: There seems to be some confusion in the Sendmail community about the + interpretation of recipient addresses on the command line if the \-t-\ + option is used. Some versions do one thing, and some another. Here is an + except from one version of the Sendmail documentation for \-t-\: + + \*Read message for recipients. ::To::, ::Cc::, and ::Bcc:: lines will + be scanned for recipient addresses. The ::Bcc:: line will be + deleted before transmission. Any addresses in the argument + list will be suppressed, that is, they will not receive + copies even if listed in the message header.*\ + + By default Exim follows this specification, and interprets addresses on + the command line as addresses not to send to. You can set + +==> extract_addresses_remove_arguments = false + + to change this behaviour so that command line addresses are added to the + addresses that are taken from the header lines. + + +Q5008: If I set up a domain list to contain //*customer.com//, it matches + //customer.com// and //abc.customer.com// as required, but it also matches + //noncustomer.com//, which is wrong. How can I get round this? + +A5008: You have to specify two entries in the list: + +==> customer.com : *.customer.com + + because * in a domain list matches any characters, including \"."\ and + including a null sequence. + + +Q5009: I want to match all domains of the form //*.oyoy.org// but want a few + exceptions. For instance I don't want //foo.oyoy.org// or //bar.oyoy.org// to be + included. What is the best way to do this? + +A5009: Use negative items in the domain list, like this: + +==> domainlist local_domains = !foo.oyoy.org : !bar.oyoy.org : *.oyoy.org + + If there are many exceptions, you can use a lookup instead of listing + them all inline. If there are a number of exceptions that match a + particular pattern, you could use a regular expression. + + +Q5010: I can't seem to find a pre-built version of Exim anywhere. The machine + is a Sparc 5 running Solaris 2.6. + +A5010: The primary distribution is source-only. However, some people have built + and distributed RPMs and debs for Linux systems, and ports for FreeBSD. + I haven't heard of anyone doing this for Solaris. The main problem with + binary distributions is that there are a number of build-time options, + requiring the answers to questions like: + + . Which DBM library do you have? (On Solaris probably ndbm, but no easy + default on some other systems.) + + . Which uid/gid do you want to use for Exim? + + . Where do you want the configuration file to be? (Many different + answers, even on the same OS, depending on local policy.) + + . Ditto for the binaries. + + . Which optional bits of Exim do you want to include? + + +Q5011: Is there a version of Exim available that runs under Windows? + +A5011: A long time ago somebody took a copy of the Exim source with the aim of + trying to port it to Windows NT. However, I never heard anything more. + However, current versions of Exim can be made to run under Cygwin. + + +Q5012: Does Exim support Delivery Status Notification (DSN), Message Status + Notification (MSN), or any other form of delivery acknowledgement? + +A5012: See Q0607. + + +Q5013: What does ``Exim'' stand for? + +A5013: Originally, it was ``EXperimental Internet Mailer'', which was the best I + could come up with when I was starting out. At that point it was + experimental - I wanted to see if the ideas I had for extending Smail's + approach actually worked. Then somebody discovered about it and wanted + to start using it, and told other people about it... + + +Q5014: Although I haven't set \check_spool_space\, Exim is still checking the + amount of space on the spool for incoming SMTP messages that use the + SIZE option. Can I suppress this? + +A5014: The RFC for the SIZE option says: + + \*If the server currently lacks sufficient resources to accept a + message of the indicated size, but may be able to accept the + message at a later time, it responds with code ``452 + insufficient system storage''.*\ + + and that is what Exim is trying to implement. This is entirely + independent from \check_spool_space\, which says \*don't accept any mail + if there is less than so much space in the spool partition*\, though the + code is optimised to do both checks at the same time if required. + However, you can suppress the SIZE check if you want to, by unsetting + \smtp_check_spool_space\. + + +Q5015: I just noticed log entries that start off \"<= <>"\. Am I correct in + assuming that the \"<>"\ indicates that the envelope did not contain any + ``From'' data? + +A5015: Yes. This indicates a delivery failure report (aka a ``bounce message''), + as specified in RFC 2821. The reason for using empty sender addresses is + to identify bounce messages so that they themselves do not cause further + bounces. Empty senders are also used for other kinds of report which + should not themselves cause the generation of bounce messages. For + example, Exim uses them when sending out warnings about delivery delays. + + +Q5016: I've received a message which does not have my address in the ::To:: + line. It is a spam message with the same address in both the ::From:: and + the ::To:: headers. How can this happen, and why doesn't Exim reject it? + +A5016: There is an important distinction between the ``envelope'' from and to and + the ``header'' from and to. The former are sometimes called the ``sender'' + and ``recipient''. An email message needs an ``envelope'' for the same + reason that paper mail does - the envelope tells the delivery mechanism + what to do with this copy of the message, whereas the ::To:: header lists + all the recipients, including those who have been sent different copies + of the message because their mailbox is on some other host. + + An MTA such as Exim works entirely with the ``envelope'' addresses, not + with those in the header lines. Don't try to block mail where envelope + from and the header from differ. There are common legitimate cases where + this happens, for example, messages forwarded from mailing lists and + delivery failure reports. + + +Q5017: Can (or will) Exim ever handle a message delivery purely in memory, + that is, it is handled without it ever hitting the disk? + +A5017: It doesn't, and never will. Accepting and delivering a message are two + entirely separate, independent processes, which communicate only by + writing/reading the message on the disk. + + +Q5018: If I am using dbm files for data that Exim reads, can I rebuild them + on the fly, or do I need to restart Exim every time I make a change? + +A5018: Exim re-reads the file every time it consults it, so if you are using a + cdb or a DBM library that uses just a single file (i.e. not ndbm), + you can just build the new file with a temporary file name, and use + \^mv^\ to rename it into the correct place on the fly. If there are two + files to rename, there is a window of time during which the DBM database + is inconsistent. On lightly loaded systems this may not matter. + + +Q5019: I need an option that is the opposite of \-bpa-\, that is, a listing of + those addresses generated from a top-level address that have not yet + been delivered. + +A5019: Exim does not keep this information. It saves only the top-level + addresses and the list of addresses that are finished with. At each + delivery attempt, generated addresses are recomputed from scratch. This + makes it possible to correct errors in redirection data that is + causing delivery delays. However, there is an option you can set on a + \redirect\ router that changes things. It is called \one_time\, and if + it is set, the list of generated addresses gets added to the top-level + list at the first delivery attempt, and is never regenerated. Because + top-level address lists must be real email addresses, this option cannot + be used if any of the generated addresses are pipes, files, or + autoreplies. + + +Q5020: How can I make Exim receive incoming mail, queue it, but not attempt to + deliver it? I want to be in this state while moving some mailboxes. + +A5020: Set \queue_only\ in the Exim configuration. Then kill your daemon, + and restart it without the \-q-\ option (i.e. with just the \-bd-\ option), + so that it does not spawn any queue runners. This stops all deliveries, + remote as well as local. + + +Q5021: What does Exim use for POP and IMAP as a default? Do I have to install + anything else? + +A5021: Yes. Exim provides MTA functionality. That is, it delivers mail. POP and + IMAP are two of several ways of reading previously-delivered mail. Exim + does not provide that functionality. You need to install POP and/or IMAP + daemons; there are several to choose from. There is a mailing list at + //pop-imap@exim.org// for the discussion of POP/IMAP issues. + + +Q5022: Is there an easy way of removing all queued messages at once in a safe + way? + +A5022: Try this command: + +==> exim -bp | awk '/^ *[0-9]+[mhd]/{print "exim -Mrm " $3}' | sh + + +Q5023: Why does Exim do \*ident*\ callbacks by default? Isn't this just a waste + of resources? I've been told this is an ancient way of authentication. + Is it obsolete? + +A5023: This is a common misunderstanding, at least partially resulting from the + incorrect naming of the protocol when it was first published. + The service on port 113 is an identification service, which allows a + target host to record information identifying the user responsible for + making a connection to it. The information may not be intelligible to + the recording host - it could, for example, be encrypted so that only + someone on the calling host can make sense of it. It is useful for + providing additional information in an audit trail. + + At least one site has found \^ident^\ effective against two rather + prevalent kinds of open proxy (whether already blacklisted at the RBLs + or not). An ACL statement is used to reject mail from servers that + return \^ident^\ strings of \"squid"\ and \"CacheFlow Server"\. + Snippets such as this in the RCPT ACL do the trick: + +==> deny condition = ${if eq{$sender_ident}{CacheFlow Server}{1}{0}} + message = Rejected - appears to be an unsecured proxy: $sender_ident + + The likelihood that a genuine mail process would return those specific + ident strings is vanishingly small. + + The \^ident^\ data should not be used for authentication in any form + except on a closed secure network between cooperating hosts (probably + not even then). The information from the source host is only as reliable + as the host itself. If it's not under your control then you have to + treat the information as opaque data that can be used only by the + sysadmin of the source system to trace back connection data. Some + \^ident^\ implementations send out opaque cookies or DES encrypted + information. \^Ident^\ is hugely useful at times - especially for + checking back on connections from multiuser machines (as opposed to + one-person desktop boxes). + + You can stop Exim making ident calls by adding + +==> rfc1413_query_timeout = 0s + + to its configuration, but it is better to leave it active (reducing the + timeout to 10s or less if it is causing problems) - it costs very + little, and in cases of mail forgery from a multiuser system can track + the sinner concerned very quickly. + + +Q5024: I often have the problem that a message gets stuck in the mail queue and + I want it to be bounced to a certain address. + +A5024: You can do this using a combination of four command line options, like + this: + +==> exim -Mf 14Fdlq-0003kM-00 + exim -Mmad 14Fdlq-0003kM-00 + exim -Mar 14Fdlq-0003kM-00 new@ddress + exim -M 14Fdlq-0003kM-00 + + The first command freezes the message so that a queue runner won't start + to deliver it while you are changing things. The second command marks + all existing recipients as delivered. The third command adds a new + recipient, and the fourth command forces a delivery of the message, + which will cause it to be delivered to the new address, and then + deleted. + + +Q5025: What precautions should I take when editing Exim's run time + configuration file? + +A5025: Edit the file and save the result in a new file. Test the syntax of + the new file by running a command like this: + +==> exim -bV -C exim.conf.new + + That will check for syntax errors without disturbing your running + configuration. If you are paranoid enough, run, as \/root/\, + +==> exim -C exim.conf.new <some address> + <some message> + . + + and see if it delivers it. Carry on testing until happy. When happy, + +==> mv exim.conf.new exim.conf + kill -HUP `cat /var/spool/exim/exim-daemon.pid` + + Then check the Exim log to be sure the daemon restarted OK. Watch the + log for a bit to see that mail is flowing. + + +Q5026: Is exim able to use RFC 2645, \*On-demand Mail Relay*\ (ODMR)? + +A5026: No. + + +Q5027: Is there any way I can send bounces to the postmaster, and nobody else? + Basically, I want to receive them, and I don't want the reply/from + person to get them. If I think they need it I will forward it myself. + +A5027: Put \"errors_to=postmaster"\ on every router. + + +Q5028: When I HUP the Exim daemon, the name shown in the process table changes + from \(/usr/lib/sendmail)\ (which is a symlink) to the real binary name. + Can I change this? + +A5028: Add this to your Exim configuration: + +==> exim_path = /usr/lib/sendmail + + +Q5029: A message with a recipient address that contains a non-printing character + is stuck on my mail queue. How can I remove this address? + +A5029: You can use the \-Mmd-\ command line option to mark a recipient address + ``delivered'', which effectively removes it. If you are using the Bash + shell, you can enter non-printing characters using an escape sequence. + For example: + +==> exim -Mmd 15HKvU-00013Q-00 $'\240'abc@x.y.z + + In this example, the first character of the local part has a code value + of 240. If you are using a shell that does not support this, create the + command in a file and run it as a shell script. + + +Q5030: I am using exim in a two queues scenario, with two different + configuration files. How can I run a second copy of \^eximon^\ to + inspect and modify the alternate queue? + +A5030: Use these commands (or put them in a script): + +==> EXIMON_EXIM_CONFIG=/your/path/exim/configure.alternate + export EXIMON_EXIM_CONFIG + /your/path/exim/bin/eximon + + +Q5031: Why is there no sender address on bounce messages? It shows up as "<>". + +A5031: See the answer to Q0042. + + +Q5032: Are there any Exim web-based administration scripts? + +A5032: No (as far as is known). It seems likely that producing one that is + generic enough would be a difficult task. + + +Q5033: How can I send a copy of all outgoing messages to another mailbox? + +A5033: The most straightforward way is to set up a system filter, and include + a command such as: + +==> unseen deliver mailbox@whatever.domain + + This sends a copy of every message to //mailbox@whatever.domain// + (unless the message already has that recipient - Exim never does + duplicate deliveries). + + To save only ``outgoing'' messages, you need to come up with a + definition of what ``outgoing'' means. Typically, this might be a check + on the sender address and/or on the originating host. Here is an + example: + +==> if $sender_address_domain is mydomain.com and + ${mask:$sender_host_address/24} is 192.168.324.0/24 + then + unseen deliver mailbox@whatever.domain + endif + + +Q5034: Is there any way to make the \queue_only\ option conditional? I would + like the ability to queue messages from external sources while deliver + locally generated email as normal. + +A5034: There is no direct way of doing this. However, you can achieve the + effect. In one of your ACLs that checks incoming mail from external + sources, put + +==> warn control = queue_only + + You can add other conditions as well, of course. + + + +91. MAC OS X + +Q9101: How can I install Exim on Mac OS X? + +A9101: (1) There is useful advice on this web page: + \?http://www.afp548.com/Articles/Jaguar/exim410.html?\. + + (2) There is a package installer available at this URL: + \?ftp://members.aol.com/AFP548dotcom/EximInstaller.sit?\. + + (3) There is another package installer for the combination of MySQL, + Exim, Exiscan, CourierIMAP, and SpamAssassin at this URL: + \?http://maxo.captainnet.net/installs/mail-install.html?\. + + + +92. FREEBSD + +Q9201: On FreeBSD, \(/usr/sbin/sendmail)\ is a symbolic link to + \(/usr/sbin/mailwrapper)\; it doesn't contain the Sendmail binary. How + should I replace Sendmail with Exim on FreeBSD? + +A9201: There is a file called \(/etc/mail/mailer.conf)\ which selects what to + run for various MTA calls. Instead of changing \(/usr/sbin/sendmail)\, + you should edit this file instead, to read something like this: + +==> sendmail /usr/exim/bin/exim + send-mail /usr/exim/bin/exim + mailq /usr/exim/bin/exim -bp + newaliases /usr/bin/true + + You probably also need to edit \(/etc/periodic.conf)\; see Q9202. + + +Q9202: A script that FreeBSD runs nightly uses \^mailq^\ with the \-Ac-\ + parameter. Why doesn't Exim recognize this? + +A9202: \-Ac-\ is a Sendmail option that requests that mailq ``Show the mail + submission queue specified in \(/etc/mail/submit.cf)\ instead of the + MTA queue specified in \(/etc/mail/sendmail.cf)\''. Exim doesn't have + the concept of a ``submission queue''. You can disable this feature + of the nightly script by adding the line + +==> daily_status_include_submit_mailq="NO" # No separate 'submit' queue + + to the file \(/etc/periodic.conf)\. + + +Q9203: How can I use Exim for authenticated SMTP using Cyrus on FreeBSD? + +A9203: This web page may help: \?http://www.munk.nu/exim/exim-freebsd-asmtp.php?\. + + + +93. HP-UX + +Q9301: I'm trying to compile on an HP machine and I don't have \^gcc^\ there. So I + put \"CC=cc"\ in the \(Local/Makefile)\, but I got this error: + +==> (Bundled) cc: "buildconfig.c", line 54: error 1705: Function prototypes + are an ANSI feature. + +A9301: The bundled compiler is not an ANSI C compiler. You either have to get a + copy of \^gcc^\ from the HPUX Software Porting Archives or buy the ANSI cc + from HP. The advice given by one user of HP systems on the Exim + mailing list was as follows: + + \*Personally, I wouldn't use anything but the ANSI C compiler. gcc + works for compilation, but it doesn't know squat about PA-RISC chips + past the 1.0 rev. Since then, HP has come out with PA-RISC 1.1, 2.0, + and 2.1, each with better features. gcc will compile for them, but it + doesn't produce anywhere near the optimization that HP's compiler + does.*\ + + \*I took the gcc road when we moved from FreeBSD to HP-UX because I was + familiar with it. After 6 months, I had to go and re-port everything + over when we realized that gcc wasn't going to do it for us long-term. + If I could give advice to any new HP-UX admin: don't use gcc if you + can afford the ANSI C compiler. Based on the cost of even the lowest + HP workstation, that usually isn't a problem.*\ + + + +94. BSDI + +Q9401: On BSDI 4.0, Exim built with Perl support exits with the error message + +==> ./exim: can't load library 'libperl.so' + +A9401: You probably compiled perl5 yourself, without looking into + +==> /usr/src/contrib/perl5/perl5.004_02/hints/bsdos.sh + + first. The problem is that the command + +==> perl5 -MExtUtils::Embed -e ldopts + + doesn't give you sufficient flags to link something with libperl. + Since 5.004_02 the \(hints/bsdos.sh)\ file has changed to adapt to the + changes between BSDI 3.1 and 4.0, but it is still not entirely right. + + The solution is, when you compile perl, change the \ccdlflags\ + variable in config.sh to: + +==> -rdynamic -Wl,-rpath,/usr/local/lib/perl5/5.00502/i386-bsdos/CORE + + (or something similar). Alternatively, you can run \(./Configure)\ and + answering the question \*Any special flags to pass to cc to use dynamic + loading?*\ with the above line. It is not known what \-rdynamic-\ means + (it's not apparently documented in any man page), but that's what BSDI + guys did to compile perl5 which comes with BSDI 4.0 distribution. + + + +95. IRIX + +Q9501: The IP addresses for incoming calls are all being given as + 255.255.255.255 or 0.0.0.0. + +A9501: This problem should no longer occur because a workaround has been + installed in Exim. + + + +96. LINUX + +Q9601: Exim is mysteriously crashing, usually when forking to send a delivery + error message. + +A9601: This has been seen in cases where Exim has been incorrectly built with + a muddled combination of an \(ndbm.h)\ include file and a non-matching + DBM library. + + Faults like this have also been seen on systems with faulty motherboards. + You could try to compile the Linux kernel 10 times - if the compile + process stops with signal 11, your hardware is to blame. + + +Q9602: I want to use \^logrotate^\ which is standard with RH5.2 Linux to rotate + my mail logs. Anyone worked out the \^logrotate^\ config file that will + do this? + +A9602: Here's one suggestion: + +==> /var/log/exim/main.log { + create 644 exim exim + rotate 4 + compress + delaycompress + } + + The sleep is added to allow things to close the log file prior to + compression. You also need similar entries for the panic log and the + reject log, of course. + + +Q9603: I'm seeing the message \*inetd[334]: imap/tcp server failing (looping), + service terminated*\ on a RedHat 5.2 system, causing \^imap^\ connections to + be refused. The \^imapd^\ in use is Washington Univers 12.250. Could this + be anything to do with Exim? + +A9603: No, it's nothing to do with Exim, but here's the answer anyway: there + is a maximum connection rate for \^inetd^\. If connections come in faster + than that, it thinks a caller is looping. The default setting on RedHat + 5.2 is 40 calls in any one minute before \^inetd^\ thinks there's a problem + and suspends further calls for 10 mins. This default setting is very + conservative. You should probably increase it by a factor of 10 or 20. + For example: + +==> imap stream tcp nowait.400 root /usr/sbin/tcpd /usr/local/etc/imapd + + The rate setting is the number following ``nowait''. This syntax seems to + be specific to the Linux version of \^inetd^\. Other operating systems + provide similar functionality, but in different ways. + + +Q9604: I get the \*too many open files*\ error especially when a lot of messages + land for Majordomo at the same time. + +A9604: The problem appears to be the number of open files the system can + handle. This is changable by using the proc filesystem. To your + \(/etc/rc.d/rc.local)\ file append something like the following: + +==> # Now System is up, Modify kernel parameters for max open etc. + +==> if [ -f /proc/sys/kernel/file-max ]; then + echo 16384 >> /proc/sys/kernel/file-max + fi + if [ -f /proc/sys/kernel/inode-max ]; then + echo 24576 >> /proc/sys/kernel/inode-max + fi + if [ -f /proc/sys/kernel/file-nr ]; then + echo 2160 >> /proc/sys/kernel/file-nr + fi + + By echoing the value you want for file-max to the file \(file-max)\ etc., + you actually change the kernel parameters. + + +Q9605: I installed debian 2.2 linux on a small 325mb 486 laptop. When I try + to test the Mail program, I get the following error: \*Failed to open + configuration file /etc/exim.conf*\. + +A9605: The Debian installation should have given you \(/usr/sbin/eximconfig)\, + which asks you some questions and then sets up the configuration file + in \(/etc/exim.conf)\. Try running that (you'll probably need \/root/\) and see + how it goes. In any case you get a thoroughly commented conf file at + the end, which will give you a sample from which to work if you need + further modification. + + The Exim docs in the Debian package are in \(/usr/doc/exim)\ where the full + reference manual is \(spec.txt.gz)\. + + +Q9606: I'm having trouble configuring Exim 4 on a Debian system. How does + \(/etc/exim4/conf.d)\ work? + +A9606: The Debian Exim 4 package uses a quite uncommon, but elegant, + method of configuration where the ``real'' Exim configuration file is + assembled from a tree of snippets by a script invoked just before the + daemon is started (see Q9608). + + This fits very well into the Debian system of configuration file + management and is a great ease for the automatic configuration with + Debconf. However, it is \*very*\ different from the normal way Exim 4 is + configured. Non-Debian users on the Exim mailing list will probably have + difficulty in trying to answer specific questions about it. You may have + to find a Debian expert. + + +Q9607: I'm having difficulties trying to make Exim 4 with Redhat 9 and Berkeley + DB 4. + +A9607: Have you remembered to install the db4-devel package? + + +Q9608: I'm running Exim 3 under Debian, and want to upgrade to Exim 4. How + difficult is it? + +A9608: A user who did this, using the Debian Exim 4 package, reported as + follows: + + (1) The exim4 package installs easily, and the exim (3.38) package + uninstalls at the same time. + + (2) Exim runs from \^inetd^\. Exim4 runs from \^/etc/init.d^\. \*Much*\ nicer! + + (3) The exim conffile lives in \(/etc/exim/exim.conf)\. The exim4 conffile + lives in \(/var/lib/exim4/config.autogenerated)\. It is, as the name + suggests, autogenerated. + + (4) A new directory is created called \(/etc/exim4)\. This contains the + conffiles to generate the above config. You make changes here. + + (5) Once you have made changes to the files in \(/etc/exim4)\ you run the + script \^update-exim4.conf^\ which generates a replacement + \(config.autogenerated)\. + + [Added comment by the Debian maintainer, slightly edited: + You also need to tell the Exim daemon to reread the changed + configuration. You can do this using SIGHUP by hand. Alternatively, + instead of running \^update-exim4.conf^\ you can use + +==> invoke-rc.d exim4 reload + + which does the rebuild and also tells Exim to reread the changed + configuration.] + + (6) In my experience, you need to \*carefully*\ check the generated + configs. eg, it did not generate a system filter file reference in the + \(config.autogenerated)\. I didn't bother too much, since this is a home + setup. + + (7) All of this may be in the docs. I've read some of them, obviously, + but didn't come across an actual upgrade guide. + + [The Debian maintainer says: + \(/usr/share/doc/exim4-base/README.Debian.gz)\ and \^update-exim4.conf(8)^\ + should answer most of the questions.] + + (8) I've still got some minor things to tweak to get back to where I + was before with Exim 3. But overall, it's no drama. + + +Q9609: Why do some servers refuse SMTP connections from my Linux box, but accept + connections from hosts running other operating systems? + +A9609: If you are sure this isn't a policy issue (that is, your box isn't + administratively blocked for some reason), this may be because your + Linux box has ECN (Explicit Congestion Notification) enabled in its + TCP/IP stack. There are many broken firewalls that refuse connections + from ECN-enabled hosts. You can check the state of your box by running + +==> cat /proc/sys/net/ipv4/tcp_ecn + + If the value is "1", you have ECN enabled. You can turn it off by + running this command: + +==> echo "0" > /proc/sys/net/ipv4/tcp_ecn + + + +97. SUN SYSTEMS + +Q9701: Exim builds fine with \^gcc^\ on SunOS 4 but crashes inside \^^sscanf()^^\. + +A9701: Make sure you are liking with the GNU \^ld^\ linker and not the system + version of \^ld^\. + + +Q9702: How can I get rid of spurious \"^M"\ characters in messages sent from + CDE \^dtmail^\? + +A9702: CDE \^dtmail^\ passes messages to Exim via the command line interface with + lines terminated by CRLF, instead of the Unix convention of just LF. As + Exim is an 8-bit clean program it treats the CR as just another data + character. Exim has a command line option called \-dropcr-\ which causes + it to ignore all CR characters in an incoming non-SMTP message. You + should configure \^dtmail^\ to add this option to the command it uses to + call Exim (using the path \(/usr/lib/sendmail)\). However, it has been + reported that it isn't possible to change this call from \^dtmail^\ by any + official means. An alternative approach is to replace \(/usr/lib/sendmail)\ + by a filtering script which removes the spurious CRs from the input + before passing it to Exim. + + +Q9703: On SunOS 4 Exim crashes when looking up domains in the DNS that have + more than 10 A records. + +A9703: There are Sun library patches to fix this. It is not Exim's problem. + For 4.13_U1 the patch is 101558-xx; for 4.1.3 the patch is 100891-xx. + From the README: \*1054748 ftp, ping dump core when connecting to a host + with multiple DNS A records.*\ An alternative is to build another + resolver library - such as the ones that are part of the \^bind^\ + distribution - and explicitly link against those. + + +Q9704: I am experiencing mailbox locking problems with Sun's \^mailtool^\ used + over a network. + +A9704: Under the \"Expert"\ settings of \^mailtool^\ is a option to turn on \*Use + network aware mail file locking*\. By default \^dtmail^\ has this set, but + \^mailtool^\ doesn't. You should set it. The help info on \^dtmail^\ has this + to say about it: + + \*Mailer tries to prevent two different instances of itself from opening + the same mail file at the same time through a technique that detects + this access when both instances of Mailer and the file are all on the + same machine. A network-aware mail file locking protocol is available + that uses ToolTalk to coordinate instances of Mailer running from more + than one machine, or mail files accessed over the network. Mailer can + only change this option when first opening a mail file.*\ + + If you are using the SunOS4 version of \^mailtool^\, this apparently + doesn't work. The only thing which does seem to work it getting the user + to hit the \"done"\ button to make it release the lock. + + +Q9705: Exim has been crashing on my Solaris x86 system, apparently while + running DBM functions. + +A9705: The use of \^ndbm^\ with \^gcc^\ has caused problems on x86 Solaris systems. + Try changing one or the other; using either DB with gcc, or Sun's + WS compiler with \^ndbm^\, has fixed this in the past. + + +Q9706: The \^exiwhat^\ utility isn't working for me on a Solaris 2 system. + +A9706: Have you got \(/usr/ucb)\ on your path? If so, it is probably picking up the + wrong version of the \^ps^\ command. The \^exiwhat^\ script is built on + Solaris to expect the normal Solaris version of \^ps^\. + + +Q9707: How do I stop Sun's \^dtcm^\ from hanging? + +A9707: From qmail's FAQ: \*There is a novice programming error in dtcm, known as + ``failure to close the output side of the pipe in the child.'' Sun has, + at the time of this writing, not yet provided a patch.*\ + + +Q9708: I want Exim to use only the resolver (i.e. ignore \(/etc/hosts)\), but don't + want to alter the \(nsswitch.conf)\ file in Solaris 2. + +A9708: You need to rebuild Exim after fiddling with \(OS/os.h-SunOS5)\: + +==> #define gethostbyaddr res_gethostbyaddr + #define gethostbyname res_gethostbyname + #define endhostent res_endhostent + #define endnetent res_endnetent + #define gethostent res_gethostent + #define getnetbyaddr res_getnetbyaddr + #define getnetbyname res_getnetbyname + #define getnetent res_getnetent + #define sethostent res_sethostent + #define setnetent res_setnetent + + Note that \-lnsl-\ is still needed in the Makefile as it + contains code used by the NIS lookup and also the \^^inet_addr()^^\ function + that Exim uses. + + +Q9709: When I try to compile Exim 4.x on Solaris 2.5.1 I get an error along the + lines of \*no such field in struct as 'value.ui32'*\. + +A9709: Look in the Exim file \(OS/os.h-SunOS5.h)\ for the line + +==> #define LOAD_AVG_FIELD value.ui32 + + and change \"ui32"\ to \"ul"\ (that's u followed by the letter ell, not + the digit one). Solaris 2.5.1 is getting \*very*\ old now... + + + +98. CONFIGURATION COOKBOOK + +Q9801: How do I configure Exim as part of TPC (\?http://www.tpc.int?\)? + +A9801: Suppose you want to accept faxes destined for 1(801)539-*. These are + addressed to the domain //9.3.5.1.0.8.1.tpc.int//. Set up a transport to + handle the delivery: + +==> tpc: + driver = pipe + command = /usr/local/tpc/tpcmailer.pl $local_part@$domain \ + $sender_address + pipe_as_creator + + \(/usr/local/tpc/tpcmailer.pl)\ is the mail processing script that can + be obtained from the TPC distribution. Create a router to route mail + for the TPC domain to that transport. This must be placed before your + other routers: + +==> tpc_router: + driver = accept + transport = tpc + domains = *.9.3.5.1.0.8.1.tpc.int + + Of course, there are other things to do as well before your system is + a functioning TPC server. + + +Q9802: How do I configure Exim so that it sends mail to the outside world only + from a restricted list of our local users? + +A9802: You will need to have a convenient way of checking the list. If it is + only a handful of users, you could just list them inline. Otherwise, you + need to put them in a file or database. Let's suppose you've just got a + list in a file. Put this as your first router: + +==> check_outgoing: + driver = redirect + domains = ! +local_domains + senders = ! : ! lsearch;/etc/permitted/senders + allow_fail + data = :fail: you are not allowed to send outside + + The senders should be listed as complete addresses, with both a local + part and a domain. For a large list, use a DBM or cdb file instead, or + a database. The first item in the \senders\ list is empty, to match the + empty sender. This is necessary because bounce messages have null + senders. + + +Q9803: A site for which I provide secondary MX is down for some time. Is there + a way to run the queue for that destination separately from the main + queue? + +A9803: No, because Exim does not have the concept of ``the queue for that + destination''. It simply has a single pool of messages awaiting delivery + (and some of them may have several destinations). The best approach to + this is to arrange for all messages for the site to be saved somewhere + other than the main spool, either on a separate dedicated MTA, or in + BSMTP files. + + +Q9804: We want to be able to temporarily lock out a user by disabling the + password and moving the home directory to another place. How can we + arrange to reject mail for users in this state? + +A9804: Change the home directory pointer in the passwd file to something + distinctive. For example, we use \(/home/CANCELLED)\ for cancelled users. + Then you can pick up such users with this router, which is placed + immediately after \%system_aliases%\: + +==> cancelled_users: + driver = redirect + check_local_user + condition = ${if eq {$home}{/home/CANCELLED}{yes}{no}} + allow_fail + data = :fail: this account is cancelled + + +Q9805: How can I configure Exim so that all mails addressed to + //something@username.domain.net// get delivered to + \(/var/spool/mail/username)\? + +A9805: Assuming that you have set up //username// as a normal user, with + conventional routing for //username@domain.net// to that mailbox, all + you need to do is set up a redirection, using a router like this: + +==> user_in_domain: + driver = redirect + data = ${if match{$domain}{\N^(.*)\.domain\.net$\N}\ + {$1}fail}@domain.net + + If you set \envelope_to\ in the \%appendfile%\ transport, the original + envelope address is preserved in the message in an ::Envelope-to:: + header line. + + +Q9806: How do I get exim not to add a ::Sender:: header to locally originated + mail? + +A9806: It adds it only if the ::From:: header doesn't correspond to the user + sending the message. You can suppress this by setting + \no_local_from_check\. If your real question is \*How do I submit mail + from UUCP without it adding ::Sender::?*\, see Q1503. + + +Q9807: Is there any way to have messages sent to a specific local address + delayed by - say - 24 hours? + +A9807: Set up a router like this: + +==> delay: + driver = redirect + domains = the.domain + local_parts = thelocalpart + condition = ${if < {$message_age}{86400}{yes}{no}} + allow_defer + data = :defer: message not old enough + no_verify + + Of course, this will also have the effect of setting a retry time for + the address. You may want to set a special retry rule for it. Note the + use of \no_verify\ to ensure that this router is not used when Exim is + verifying addresses. + + +Q9808: I have a mailing list exploder on one host, and three other hosts where + I want to do the actual deliveries from. How can I get Exim to split + a message into groups of recipients between the three hosts? + +A9808: Set up a router that routes all remote addresses to a specific + transport, with a list of your three hosts. For example: + +==> send_to_three: + driver = manualroute + transport = to_three_smtp + route_list = !+local_domains hostA:hostB:hostC + + The transport looks like this: + +==> to_three_smtp: + driver = smtp + hosts_randomize + + By setting \hosts_randomize\, you request that the host list be sorted + randomly each time the transport is called, in order to spread the load. + The number of times the transport is called for each message depends on + the setting of the global option \remote_max_parallel\. If it is set to + 1, the transport is called only once for each message, so only one host + is used, but different messages use different hosts because of the + randomizing. + + The \max_rcpt\ option (default 100) controls the number of addresses + sent in each copy of the message - several copies are sent over the + same connection if necessary. + + If you want individual messages to be split between the three hosts, you + must set the global option \remote_max_parallel\ to 3. This allows Exim + to run 3 separate instances of the transport at once. It will pass + one-third of all the addresses to each instance. Because the host list + is randomized, not round-robinned, there is no guarantee that a single + message will use all three hosts, but on average it should. + + +Q9809: Can I configure Exim so that my gateway host sends a copy of each + incoming message to each of two internal hosts? + +A9809: The easiest way to do this is to make use of the \unseen\ router option, + and set up two separate routers. You need to be able to identify + incoming messages somehow. Typically this can be done by testing the + domain of the recipient address, in which case the configuration should + contain something like this: + +==> r1: + driver = manualroute + domains = ! *.your.domain.example + route_data = * host1.your.domain.example + transport = remote_smtp + unseen + +==> r2: + driver = manualroute + domains = ! *.your.domain.example + route_data = * host2.your.domain.example + transport = remote_smtp + + The \unseen\ setting on \%r1%\ means that after it has accepted an + address, the address is also passed on to \%r2%\, and so two deliveries + occur. + + +Q9810: How can I implement ``SMTP-after-POP'' with Exim? + +A9810: See Q0706. + + +Q9811: I would like to ``tap off'' a proportion of real mail traffic from my + live mail server to use in tests of a new server. I want to preserve the + envelope contents, but to suppress any error notifications to the + original sender. + +A9811: See C046. + + +Q9812: How can I lookup data from a single file using both single IP addresses + and IP address blocks as keys? I want to set \smtp_accept_max_per_host\ + by this means, and also include a default. + +A9812: You cannot do this in a single lookup, because you need separate lookups + for individual addresses and address blocks. However, these lookups can + be nested in a single expansion string. For example, suppose you are + using an lsearch file with entries like this: + +==> 192.168.34.35: 4 + 192.168.34.0/24: 2 + *: 1 + + You can use this setting: + +==> smtp_accept_max_per_host = \ + ${lookup{$sender_host_address}lsearch{/path/to/file}\ + {$value}\ + {\ + ${lookup{${mask:$sender_host_address/24}}lsearch*{/path/to/file}}\ + }} + + Note that the first lookup does \*not*\ have an asterisk on the search + type. If you have blocks of different sizes (/24, /26, etc) you have to + configure it to do a separate lookup for each size, with just the final + one using a default. + + + +99. LIST OF SAMPLE CONFIGURATIONS + +As well as being hyperlinked from the HTML version of this document, each +sample configuration is also available as a file in the \(config.samples)\ +directory, which can be independently downloaded. + +Samples whose names are of the form Cnnn are Exim configurations; those with +names of the form Fnnn are filter file fragments; those with names of the form +Lnnn are sample \^^local_scan()^^\ functions, and those with names of thf form +Snnn are scripts of various kinds. There are other examples of +\^^local_scan()^^\ functions at a number of web sites (for example, +\?http://marc.merlins.org/linux/exim/sa.html?\). + +There are gaps in the C and F numbers because I have omitted the Exim 3 samples +that have not been converted for Exim 4. + +C002: ``Although exim not intended for use in UUCP environment (it doesn't + know anything about bang!path addresses), I'm successfully using it for + delivering mail to UUCP clients.'' + +C006: ``This is how I have configured a PP-inspired vacationnote, there is + (was?) such a feature in PP. The user makes a file \(tripnote)\ in his/her + home directory, the message is passed to the sender once with a short + leading text.'' + +C022: ``This is the Exim configuration file of a machine which delivers mail to + several local domains where the mail is delivered locally, several hairy + domains, handled as described below, and a half-virtual domain, which is + first processed by its special alias file, then processed as other local + domains (including the processing by the global alias file).'' + +C037: An elegant way of using ETRN, which does immediate delivery if the host + is online, but saves mail in a BSMTP file after some time on the queue. + ETRN then re-injects the mail. + +C042: ``Since the Exim 4 configuration needed to get Mailman to work differs a + little bit from Exim 3 and since I still haven't seen a recipe for + Mailman with Exim 4, I'm providing my configuration (based heavily on + \?http://www.exim.org/howto/mailman.html?\).'' + +C043: ``Attached is an Exim 4 config file which is designed for an Exim server + that is put in front of an Exchange 5.5 system but which verifies the + valid addresses that are stored in Exchange via LDAP lookups against the + Exchange server.'' + +C044: ``I thought I'd submit this as an example of an authenticated mail hub + configuration. Several people have asked for it so I thought it + might be of interest.'' + +C045: ``Here it is, for Exim 4.10 and Cyrus IMAPD 2.1.5 using db3/db4-format + mailbox database. This configuration delivers the messages to Cyrus + IMAPD using LMTP over a TCP/IP socket.'' + +C046: ``Deliver a duplicate of some proportion of all messages to a special + machine specified in the file \(/MAIL_TAP_HOST)\, if it exists.'' + +C047: A sample configuration for calling Spamassassin directly from Exim. + +C049: ``I've been seeing a whole bunch of IPs that send me spam or virus mail + and HELOing as one of my own IPs, or as HELO one.of.my.own.domains (or + maybe HELO \primary_hostname\).'' + +C050: A configuration that uses the DNS to implement virtual domains. + +C051: ``I've been working quite hard to come up with a config that reasonably + matches the qmail-ldap setup, without the warts.'' + +F001: ``I thought that the rest of the list may be interested in reviewing our + filter as a starting point for their own system message filter.'' + +F002: ``... program which refused mail from unknown addresses until they mailed + me promising not to spam me ... since I'd already thought through how + to do it in Exim, and knew it'd be slightly easier than falling out of + bed, I went ahead and did it.'' + +F003: ``Here's four checks installed in our system wide filter that knock out + a lot of otherwise hard to detect rubbish.'' + +F004: ``This is an Exim filter snippet to change locally-generated ::Message-Id:: + and ::Resent-Message-Id:: headers to world-unique values.'' + +L001: A \^^local_scan()^^\ function for Exim that calls \^uvscan^\. + +S001: A Perl script for patching the name of the configuration file in an + Exim binary. + +S002: ``When I moved from smail to exim I built a program that took individual + config pieces, stripped all the comments, and built a config file.'' + +*** End of Exim FAQ *** diff --git a/doc/doc-src/filter.src b/doc/doc-src/filter.src new file mode 100644 index 000000000..73dfca9dc --- /dev/null +++ b/doc/doc-src/filter.src @@ -0,0 +1,1644 @@ +. $Cambridge: exim/doc/doc-src/filter.src,v 1.1 2004/10/07 15:04:35 ph10 Exp $ +. +.if !set style +.library "a4ps" +.linelength ~~sys.linelength + 0.2in +.emphasis ~~sys.linelength + 0.1in +.pagedepth ~~sys.pagedepth - 0.2in +.bindfont 53 "atl/Times-Roman" 7 +.set ssspaceb 1.50 +.fi + +.include "markup.sg" + +.set sgcal true +.set html false +.set texinfo false + + +.if ~~sys.fancy +.flag $sm{ "$push$g0$f53" +. +.else +.pagedepth ~~sys.pagedepth - 1ld +.linelength 75em +.emphasis 77em +.footdepth 0 +.disable formfeed +.backspace none +.set chapspaceb 24 +.set sspacea 24 +.flag $sm{ "$push" +.fi + +.macro tabs 6 +.if ~~sys.fancy +.tabset ~~1em +.else +.set temp (~~1 * 5)/4 +.tabset ~~temp em +.fi +.endm + +.macro startitems +.newline +.push +.indent 3em +.endm + +.macro enditems +.newline +.pop +.endm + +.macro item "item" +.newpar +.if ~~sys.leftonpage < 5ld +.newpage +.fi +.tempindent 0 +\~~1\ +.blank +.endm + +.macro index +.endm + +.set contents false +.set displayindent 2em + + +. ====================================================== + + +.if ~~sys.fancy +.footdepth 2ld +.foot +$c[~~sys.pagenumber]$e +.endfoot +.fi + + +.set chapter -1 +.chapter Exim's interfaces to mail filtering +.space -2ld +Exim is a mail transfer agent for Unix-like systems. This document describes +the user interfaces to its in-built mail filtering facilities, and is copyright +(c) University of Cambridge 2004. It corresponds to Exim version 4.40. +.rule + +. --------------------------------------------------------------------------- +. Some clever jiggery-pokery here. The contents list is known to be less than +. one page long, so we arrange for it to get onto the rest of the first page. +. Because we aren't doing any indexing, the z-rawindex file will contain only +. the TOC entries. The Makefile arranges for it to be empty at the start, then +. runs SGCAL twice so on the second pass it gets inserted automatically. + +.if ~~sgcal +.space 1ld +$chead{Contents} +.space 1ld +.tabset 2em 2em +.push +.linedepth ~~sys.linedepth - 1 +.include "z-rawindex" +.newline +.pop +.newpage +.set contents true +.fi +. --------------------------------------------------------------------------- + + +.set chapter 0 +.chapter Forwarding and filtering in Exim + + +.section Introduction +Most Unix mail transfer agents (programs that deliver mail) permit individual +users to specify automatic forwarding of their mail, usually by placing a list +of forwarding addresses in a file called \(.forward)\ in their home directories. +Exim extends this facility by allowing the forwarding instructions to be a set +of rules rather than just a list of addresses, in effect providing `\(.forward)\ +with conditions'. Operating the set of rules is called $it{filtering}, and the +file that contains them is called a $it{filter file}. + +Exim supports two different kinds of filter file. An \*Exim filter*\ contains +instructions in a format that is unique to Exim. A \*Sieve filter*\ contains +instructions in the Sieve format that is defined by RFC 3028. As this is a +standard format, Sieve filter files may already be familiar to some users. +Sieve files should also be portable between different environments. However, +the Exim filtering facility contains more features (such as variable +expansion), and better integration with the host environment (such as the use +of external processes and pipes). + +The choice of which kind of filter to use can be left to the end-user, provided +that the system administrator has configured Exim appropriately for both kinds +of filter. However, if interoperability is important, Sieve is the only +choice. + +The ability to use filtering or traditional forwarding has to be enabled by the +system administrator, and some of the individual facilities can be separately +enabled or disabled. A local document should be provided to describe exactly +what has been enabled. In the absence of this, consult your system +administrator. + +It is important to realize that, in Exim, no deliveries are actually made while +a filter or traditional \(.forward)\ file is being processed. The result of +such processing is a list of destinations to which a message should be +delivered -- the deliveries themselves take place later, along with all other +deliveries for the message. This means that it is not possible to test for +successful deliveries while filtering. It also means that any duplicate +addresses that are generated are dropped, since Exim never delivers the same +message to the same address more than once. + +This document describes how to use a filter file and the format of its +contents. It is intended for use by end-users. Both Sieve filters and Exim +filters are covered. However, for Sieve filters, only issues that relate to the +Exim implementation are discussed, since Sieve itself is described elsewhere. + +The contents of traditional \(.forward)\ files are not described here. They +normally contain just a list of addresses, file names, or pipe commands, +separated by commas or newlines, but other types of item are also available. +The full details can be found in the chapter on the \%redirect%\ router in the +Exim specification, which also describes how the system administrator can set +up and control the use of filtering. + +.section Testing a new filter file +.rset SECTtesting "~~chapter.~~section" +Filter files, especially the more complicated ones, should always be tested, as +it is easy to make mistakes. Exim provides a facility for preliminary testing +of a filter file before installing it. This tests the syntax of the file and +its basic operation, and can also be used with traditional \(.forward)\ files. + +Because a filter can do tests on the content of messages, a test message is +required. Suppose you have a new filter file called \(myfilter)\ and a test +message called \(test-message)\. Assuming that Exim is installed with the +conventional path name \(/usr/sbin/sendmail)\ (some operating systems use +\(/usr/lib/sendmail)\), the following command can be used: +.display asis +/usr/sbin/sendmail -bf myfilter <test-message +.endd +The \-bf-\ option tells Exim that the following item on the command line is the +name of a filter file that is to be tested. There is also a \-bF-\ option, +which is similar, but which is used for testing system filter files, as opposed +to user filter files, and which is therefore of use only to the system +administrator. + +The test message is supplied on the standard input. If there are no +message-dependent tests in the filter, an empty file (\(/dev/null)\) can be +used. A supplied message must start with header lines or the `From' message +separator line which is found in many multi-message folder files. Note that +blank lines at the start terminate the header lines. A warning is given if no +header lines are read. + +The result of running this command, provided no errors are detected in the +filter file, is a list of the actions that Exim would try to take if presented +with the message for real. +For example, for an Exim filter, the output +.display asis +Deliver message to: gulliver@lilliput.fict.example +Save message to: /home/lemuel/mail/archive +.endd +means that one copy of the message would be sent to +\gulliver@@lilliput.fict.example\, and another would be added to the file +\(/home/lemuel/mail/archive)\, if all went well. + +The actions themselves are not attempted while testing a filter file in this +way; there is no check, for example, that any forwarding addresses are valid. +For an Exim filter, +if you want to know why a particular action is being taken, add the \-v-\ +option to the command. This causes Exim to output the results of any +conditional tests and to indent its output according to the depth of nesting of +\"if"\ commands. Further additional output from a filter test can be generated +by the \"testprint"\ command, which is described below. + +When Exim is outputting a list of the actions it would take, if any text +strings are included in the output, non-printing characters therein are +converted to escape sequences. In particular, if any text string contains a +newline character, this is shown as `@\n' in the testing output. + +When testing a filter in this way, Exim makes up an `envelope' for the message. +The recipient is by default the user running the command, and so is the sender, +but the command can be run with the \-f-\ option to supply a different sender. +For example, +.display +.indent 0 +/usr/sbin/sendmail -bf myfilter -f islington@@never.where <test-message +.endd +Alternatively, if the \-f-\ option is not used, but the first line of the +supplied message is a `From' separator from a message folder file (not the same +thing as a \"From:"\ header line), the sender is taken from there. If \-f-\ is +present, the contents of any `From' line are ignored. + +The `return path' is the same as the envelope sender, unless the message +contains a \"Return-path:"\ header, in which case it is taken from there. You +need not worry about any of this unless you want to test out features of a +filter file that rely on the sender address or the return path. + +It is possible to change the envelope recipient by specifying further options. +The \-bfd-\ option changes the domain of the recipient address, while the +\-bfl-\ option changes the `local part', that is, the part before the @@ sign. +An adviser could make use of these to test someone else's filter file. + +The \-bfp-\ and \-bfs-\ options specify the prefix or suffix for the local part. +These are relevant only when support for multiple personal mailboxes is +implemented; see the description in section ~~SECTmbox below. + +.section Installing a filter file +A filter file is normally installed under the name \(.forward)\ in your home +directory -- it is distinguished from a conventional \(.forward)\ file by its +first line (described below). However, the file name is configurable, and some +system administrators may choose to use some different name or location for +filter files. + +.section Testing an installed filter file +Testing a filter file before installation cannot find every potential problem; +for example, it does not actually run commands to which messages are piped. +Some `live' tests should therefore also be done once a filter is installed. + +If at all possible, test your filter file by sending messages from some other +account. If you send a message to yourself from the filtered account, and +delivery fails, the error message will be sent back to the same account, which +may cause another delivery failure. It won't cause an infinite sequence of such +messages, because delivery failure messages do not themselves generate further +messages. However, it does mean that the failure won't be returned to you, and +also that the postmaster will have to investigate the stuck message. + +If you have to test an Exim filter from the same account, a sensible precaution +is to include the line +.display asis +if error_message then finish endif +.endd +as the first filter command, at least while testing. This causes filtering to +be abandoned for a delivery failure message, and since no destinations are +generated, the message goes on to be delivered to the original address. Unless +there is a good reason for not doing so, it is recommended that the above test +be left in all Exim filter files. +(This does not apply to Sieve files.) + + +.section Details of filtering commands +The filtering commands for Sieve and Exim filters are completely different in +syntax and semantics. The Sieve mechanism is defined in RFC 3028; in the next +chapter we describe how it is integrated into Exim. The subsequent chapter +covers Exim filtering commands in detail. + + +. +. +. +. +. +.chapter Sieve filter files +.rset CHAPsievefilter "~~chapter" +The code for Sieve filtering in Exim was contributed by Michael Haardt, and +most of the content of this chapter is taken from the notes he provided. Since +Sieve is a extensible language, it is important to understand `Sieve' in this +context as `the specific implementation of Sieve for Exim'. + +This chapter does not contain a description of Sieve, since that can be found +in RFC 3028, which should be read in conjunction with these notes. + +The Exim Sieve implementation offers the core as defined by RFC 3028, the +\%envelope%\ and the \%fileinto%\ extensions, but not the \%reject%\ extension. +Exim does not support message delivery notifications (MDNs), so adding it just +to the Sieve filter (as required for \%reject%\) makes little sense. + +In order for Sieve to work properly in Exim, the system administrator needs to +make some adjustments to the Exim configuration. These are described in the +chapter on the \%redirect%\ router in the full Exim specification. + +.section Recognition of Sieve filters +A filter file is interpreted as a Sieve filter if its first line is +.display asis +# Sieve filter +.endd +This is what distinguishes it from a conventional \(.forward)\ file or an Exim +filter file. + + +.section Saving to specified folders +If the system administrator has set things up as suggested in the Exim +specification, and you use \%keep%\ or \%fileinto%\ to save a mail into a +folder, absolute files are stored where specified, relative files are stored +relative to \$home$\, and \%inbox%\ goes to the standard mailbox location. + + +.section Strings containing header names +RFC 3028 does not specify what happens if a string denoting a header field does +not contain a valid header name, for example, it contains a colon. This +implementation generates an error instead of ignoring the header field in order +to ease script debugging, which fits in the common picture of Sieve. + + +.section Exists test with empty list of headers +The \%exists%\ test succeeds only if all specified headers exist. RFC 3028 +does not explicitly specify what happens on an empty list of headers. This +implementation evaluates that condition as true, interpreting the RFC in a +strict sense. + + +.section Header test with invalid MIME encoding in header +Some MUAs process invalid base64 encoded data, generating junk. +Others ignore junk after seeing an equal sign in base64 encoded data. +RFC 2047 does not specify how to react in this case, other than stating +that a client must not forbid to process a message for that reason. +RFC 2045 specifies that invalid data should be ignored (apparently +looking at end of line characters). It also specifies that invalid data +may lead to rejecting messages containing them (and there it appears to +talk about true encoding violations), which is a clear contradiction to +ignoring them. + +RFC 3028 does not specify how to process incorrect MIME words. +This implementation treats them literally, as it does if the word is +correct but its character set cannot be converted to UTF-8. + + +.section Address test for multiple addresses per header +A header may contain multiple addresses. RFC 3028 does not explicitly +specify how to deal with them, but since the address test checks if +anything matches anything else, matching one address suffices to +satisfy the condition. That makes it impossible to test if a header +contains a certain set of addresses and no more, but it is more logical +than letting the test fail if the header contains an additional address +besides the one the test checks for. + + +.section Semantics of keep +The \%keep%\ command is equivalent to +.display +fileinto "inbox"; +.endd +It saves the message and resets the implicit keep flag. It does not set the +implicit keep flag; there is no command to set it once it has been reset. + + +.section Semantics of fileinto +RFC 3028 does not specify whether \fileinto\ should try to create a mail folder +if it does not exist. This implementation allows the sysadmin to configure that +aspect using the \%appendfile%\ transport options \create@_directory\, +\create@_file\, and \file@_must@_exist\. See the \%appendfile%\ transport in +the Exim specification for details. + + +.section Semantics of redirect +Sieve scripts are supposed to be interoperable between servers, so this +implementation does not allow mail to be redirected to unqualified addresses, +because the domain would depend on the system being used. On systems with +virtual mail domains, the default domain is probably not what the user expects +it to be. + + +.section String arguments +There has been confusion if the string arguments to \%require%\ are to be +matched case-sensitively or not. This implementation matches them with +the match type \":is"\ (default, see section 2.7.1) and the comparator +\"i;ascii-casemap"\ (default, see section 2.7.3). The RFC defines the +command defaults clearly, so any different implementations violate RFC +3028. The same is valid for comparator names, also specified as strings. + + +.section Number units +There is a mistake in RFC 3028: the suffix G denotes gibi-, not tebibyte. +The mistake is obvious, because RFC 3028 specifies G to denote 2@^30 +(which is gibi, not tebi), and that is what this implementation uses as +scaling factor for the suffix G. + + +.section RFC compliance +Exim requires the first line of a Sieve filter to be +.display asis +# Sieve filter +.endd +Of course the RFC does not specify that line. Do not expect examples to work +without adding it, though. + +RFC 3028 requires the use of CRLF to terminate a line. +The rationale was that CRLF is universally used in network protocols +to mark the end of the line. This implementation does not embed Sieve +in a network protocol, but uses Sieve scripts as part of the Exim MTA. +Since all parts of Exim use LF as newline character, this implementation +does, too, by default, though the system administrator may choose (at Exim +compile time) to use CRLF instead. + +Exim violates RFC 2822, section 3.6.8, by accepting 8-bit header names, so +this implementation repeats this violation to stay consistent with Exim. +This is in preparation to UTF-8 data. + +Sieve scripts cannot contain NUL characters in strings, but mail +headers could contain MIME encoded NUL characters, which could never +be matched by Sieve scripts using exact comparisons. For that reason, +this implementation extends the Sieve quoted string syntax with @\0 +to describe a NUL character, violating @\0 being the same as 0 in +RFC 3028. Even without using @\0, the following tests are all true in +this implementation. Implementations that use C-style strings will only +evaluate the first test as true. +.display asis +Subject: =?iso-8859-1?q?abc=00def + +header :contains "Subject" ["abc"] +header :contains "Subject" ["def"] +header :matches "Subject" ["abc?def"] +.endd + +Note that by considering Sieve to be a MUA, RFC 2047 can be interpreted +in a way that NUL characters truncating strings is allowed for Sieve +implementations, although not recommended. It is further allowed to use +encoded NUL characters in headers, but that's not recommended either. +The above example shows why. + +RFC 3028 states that if an implementation fails to convert a character +set to UTF-8, two strings cannot be equal if one contains octets greater +than 127. Assuming that all unknown character sets are one-byte character +sets with the lower 128 octets being US-ASCII is not sound, so this +implementation violates RFC 3028 and treats such MIME words literally. +That way at least something could be matched. + +The folder specified by \%fileinto%\ must not contain the character +sequence \".."\ to avoid security problems. RFC 3028 does not specify the +syntax of folders apart from \%keep%\ being equivalent to +.display asis +fileinto "INBOX"; +.endd +This implementation uses \"inbox"\ instead. + +Sieve script errors currently cause messages to be silently filed into +\"inbox"\. RFC 3028 requires that the user is notified of that condition. +This may be implemented in future by adding a header line to mails that +are filed into \"inbox"\ due to an error in the filter. + + +. +. +. +. +. +.chapter Exim filter files +.rset CHAPeximfilter "~~chapter" +This chapter contains a full description of the contents of Exim filter files. + +.section Format of Exim filter files +Apart from leading white space, the first text in a filter file must be +.display asis +# Exim filter +.endd +This is what distinguishes it from a conventional \(.forward)\ file or a Sieve +filter file. If the file does not have this initial line (or the equivalent for +a Sieve filter), it is treated as a +conventional \(.forward)\ file, both when delivering mail and when using the +\-bf-\ testing mechanism. The white space in the line is optional, and any +capitalization may be used. Further text on the same line is treated as a +comment. For example, you could have +.display asis +# Exim filter <<== do not edit or remove this line! +.endd +The remainder of the file is a sequence of filtering commands, which consist of +keywords and data values. For example, in the command +.display asis +deliver gulliver@lilliput.fict.example +.endd +the keyword is \"deliver"\ and the data value is +\"gulliver@@lilliput.fict.example"\. +White space or line breaks separate the components of a command, except in the +case of conditions for the \"if"\ command, where round brackets (parentheses) +also act as separators. Complete commands are separated from each other by +white space or line breaks; there are no special terminators. Thus, several +commands may appear on one line, or one command may be spread over a number of +lines. + +If the character @# follows a separator anywhere in a command, everything from +@# up to the next newline is ignored. This provides a way of including comments +in a filter file. + +.section Data values in filter commands +There are two ways in which a data value can be input: +.numberpars $. +If the text contains no white space then it can be typed verbatim. However, if +it is part of a condition, it must also be free of round brackets +(parentheses), as these are used for grouping in conditions. +.nextp +Otherwise, it must be enclosed in double quotation marks. In this case, the +character @\ (backslash) is treated as an `escape character' within the string, +causing the following character or characters to be treated specially: +.display rm +.tabs 8 +@\n $t is replaced by a newline +@\r $t is replaced by a carriage return +@\t $t is replaced by a tab +.endd +Backslash followed by up to three octal digits is replaced by the character +specified by those digits, and @\x followed by up to two hexadecimal digits is +treated similarly. Backslash followed by any other character is replaced +by the second character, so that in particular, @\" becomes " and @\@\ becomes +@\$<. A data item enclosed in double quotes can be continued onto the next line +by ending the first line with a backslash. Any leading white space at the start +of the continuation line is ignored. +.endp +In addition to the escape character processing that occurs when strings are +enclosed in quotes, most data values are also subject to $it{string expansion} +(as described in the next section), in which case the characters \@$\ and \@\\ +are also significant. This means that if a single backslash is actually +required in such a string, and the string is also quoted, @\@\@\@\ has to be +entered. + +The maximum permitted length of a data string, before expansion, is 1024 +characters. + + +.section String expansion +.rset SECTfilterstringexpansion "~~chapter.~~section" +Most data values are expanded before use. Expansion consists of replacing +substrings beginning with \"@$"\ with other text. The full expansion facilities +available in Exim are extensive. If you want to know everything that Exim can +do with strings, you should consult the chapter on string expansion in the Exim +documentation. + +In filter files, by far the most common use of string expansion is the +substitution of the contents of a variable. For example, the substring +.display asis +$reply_address +.endd +is replaced by the address to which replies to the message should be sent. If +such a variable name is followed by a letter or digit or underscore, it must be +enclosed in curly brackets (braces), for example, +.display asis +${reply_address} +.endd +If a \"@$"\ character is actually required in an expanded string, it must be +escaped with a backslash, and because backslash is also an escape character in +quoted input strings, it must be doubled in that case. The following two +examples illustrate two different ways of testing for a \"@$"\ character in a +message: +.display asis +if $message_body contains \$ then ... +if $message_body contains "\\$" then ... +.endd +You can prevent part of a string from being expanded by enclosing it between +two occurrences of \"@\N"\. For example, +.display asis +if $message_body contains \N$$$$\N then ... +.endd +tests for a run of four dollar characters. + +.section Some useful general variables +A complete list of the available variables is given in the Exim documentation. +This shortened list contains the ones that are most likely to be useful in +personal filter files: + +\$body@_linecount$\: The number of lines in the body of the message. + +\$home$\: In conventional configurations, this variable normally contains the +user's home directory. The system administrator can, however, change this. + +\$local@_part$\: The part of the email address that precedes the @@ sign -- +normally the user's login name. If support for multiple personal mailboxes is +enabled (see section ~~SECTmbox below) and a prefix or suffix for the local +part was recognized, it is removed from the string in this variable. + +\$local@_part@_prefix$\: If support for multiple personal mailboxes is enabled +(see section ~~SECTmbox below), and a local part prefix was recognized, +this variable contains the prefix. Otherwise it contains an empty string. + +\$local@_part@_suffix$\: If support for multiple personal mailboxes is enabled +(see section ~~SECTmbox below), and a local part suffix was recognized, +this variable contains the suffix. Otherwise it contains an empty string. + +\$message@_body$\: The initial portion of the body of the message. By default, +up to 500 characters are read into this variable, but the system administrator +can configure this to some other value. Newlines in the body are converted into +single spaces. + +\$message@_body@_end$\: The final portion of the body of the message, formatted +and limited in the same way as \$message@_body$\. + +\$message@_body@_size$\: The size of the body of the message, in bytes. + +\$message@_headers$\: The header lines of the message, concatenated into a +single string, with newline characters between them. + +\$message@_id$\: The message's local identification string, which is unique for +each message handled by a single host. + +\$message@_size$\: The size of the entire message, in bytes. + +\$original@_local@_part$\: When an address that arrived with the message is +being processed, this contains the same value as the variable \$local@_part$\. +However, if an address generated by an alias, forward, or filter file is being +processed, this variable contains the local part of the original address. + +\$reply@_address$\: The contents of the \"Reply-to:"\ header, if the message +has one; otherwise the contents of the \"From:"\ header. It is the address to +which normal replies to the message should be sent. + +\$return@_path$\: The return path -- that is, the sender field that will be +transmitted as part of the message's envelope if the message is sent to another +host. This is the address to which delivery errors are sent. In many cases, +this variable has the same value as \$sender@_address$\, but if, for example, +an incoming message to a mailing list has been expanded, \$return@_path$\ may +have been changed to contain the address of the list maintainer. + +\$sender@_address$\: The sender address that was received in the envelope of +the message. This is not necessarily the same as the contents of the \"From:"\ +or \"Sender:"\ header lines. For delivery error messages (`bounce messages') +there is no sender address, and this variable is empty. + +\$tod@_full$\: A full version of the time and date, for example: Wed, 18 Oct +1995 09:51:40 +0100. The timezone is always given as a numerical offset from +GMT. + +\$tod@_log$\: The time and date in the format used for writing Exim's log files, +without the timezone, for example: 1995-10-12 15:32:29. + +\$tod@_zone$\: The local timezone offset, for example: +0100. + + +.section Header variables +.rset SECTheadervariables "~~chapter.~~section" +There is a special set of expansion variables containing the header lines of +the message being processed. These variables have names beginning with +\"@$header@_"\ followed by the name of the header line, terminated by a colon. +For example, +.display asis +$header_from: +$header_subject: +.endd +The whole item, including the terminating colon, is replaced by the contents of +the message header line. If there is more than one header line with the same +name, their contents are concatenated. For header lines whose data consists of +a list of addresses (for example, ::From:: and ::To::), a comma and newline is +inserted between each set of data. For all other header lines, just a newline +is used. + +Leading and trailing white space is removed from header line data, and if there +are any MIME `words' that are encoded as defined by RFC 2047 (because they +contain non-ASCII characters), they are decoded and translated, if possible, to +a local character set. Translation is attempted only on operating systems that +have the \iconv(@)\ function. This makes the header line look the same as it +would when displayed by an MUA. The default character set is ISO-8859-1, but +this can be changed by means of the \"headers"\ command (see below). + +If you want to see the actual characters that make up a header line, you can +specify \"@$rheader@_"\ instead of \"@$header@_"\. This inserts the `raw' +header line, unmodified. + +There is also an intermediate form, requested by \"@$bheader@_"\, which removes +leading and trailing space and decodes MIME `words', but does not do any +character translation. If an attempt to decode what looks superficially like a +MIME `word' fails, the raw string is returned. If decoding produces a binary +zero character, it is replaced by a question mark. + +The capitalization of the name following \"@$header@_"\ is not significant. +Because any printing character except colon may appear in the name of a +message's header (this is a requirement of RFC 2822, the document that +describes the format of a mail message) curly brackets must $it{not} be used in +this case, as they will be taken as part of the header name. Two shortcuts are +allowed in naming header variables: +.numberpars $. +The initiating \"@$header@_"\, \"@$rheader@_"\, or \"@$bheader@_"\ can be +abbreviated to \"@$h@_"\, \"@$rh@_"\, or \"@$bh@_"\, respectively. +.nextp +The terminating colon can be omitted if the next character is white space. The +white space character is retained in the expanded string. However, this is not +recommended, because it makes it easy to forget the colon when it really is +needed. +.endp +If the message does not contain a header of the given name, an empty string is +substituted. Thus it is important to spell the names of headers correctly. Do +not use \"@$header@_Reply@_to"\ when you really mean \"@$header@_Reply-to"\. + +.section User variables +There are ten user variables with names \$n0$\ -- \$n9$\ that can be +incremented by the \"add"\ command (see section ~~SECTadd). These can be used +for `scoring' messages in various ways. If Exim is configured to run a `system +filter' on every message, the values left in these variables are copied into +the variables \$sn0$\ -- \$sn9$\ at the end of the system filter, thus making +them available to users' filter files. How these values are used is entirely up +to the individual installation. + +.section Current directory +The contents of your filter file should not make any assumptions about the +current directory. It is best to use absolute paths for file names; you +can normally make use of the \$home$\ variable to refer to your home directory. +The \save\ command automatically inserts \$home$\ at the start of non-absolute +paths. + + + +.section Significant deliveries +When in the course of delivery a message is processed by a filter file, what +happens next, that is, after the whole filter file has been processed, depends +on whether the filter has set up any $it{significant deliveries} or not. If +there is at least one significant delivery, the filter is considered to +have handled the entire delivery arrangements for the current address, and no +further processing of the address takes place. If, however, no significant +deliveries have been set up, Exim continues processing the current address as +if there were no filter file, and typically sets up a delivery of a copy of the +message into a local mailbox. In particular, this happens in the special case +of a filter file containing only comments. + +The delivery commands \"deliver"\, \"save"\, and \"pipe"\ are by default +significant. However, if such a command is preceded by the word \"unseen"\, its +delivery is not considered to be significant. In contrast, other commands such +as \"mail"\ and \"vacation"\ do not count as significant deliveries unless +preceded by the word \"seen"\. + + +.section Filter commands +The filter commands which are described in subsequent sections are listed +below, with the section in which they are described in brackets: +.display rm +.tabs 15 +\add\ $t increment a user variable (section ~~SECTadd) +\deliver\ $t deliver to an email address (section ~~SECTdeliver) +\fail\ $t force delivery failure (sysadmin use) (section ~~SECTfail) +\finish\ $t end processing (section ~~SECTfinish) +\freeze\ $t freeze message (sysadmin use) (section ~~SECTfreeze) +\headers\ $t set the header character set (section ~~SECTheaders) +\if\ $t test condition(s) (section ~~SECTif) +\logfile\ $t define log file (section ~~SECTlog) +\logwrite\ $t write to log file (section ~~SECTlog) +\mail\ $t send a reply message (section ~~SECTmail) +\pipe\ $t pipe to a command (section ~~SECTpipe) +\save\ $t save to a file (section ~~SECTsave) +\testprint\ $t print while testing (section ~~SECTtestprint) +\vacation\ $t tailored form of \mail\ (section ~~SECTmail) +.endd +In addition, when Exim's filtering facilities are being used as a system +filter, the \"fail"\, \"freeze"\, and \"headers"\ commands are available. +However, since they are usable only by the system administrator and not by +ordinary users, they are described in the main Exim specification rather than +in this document. + +.section The add command +.rset SECTadd "~~chapter.~~section" +.display + add <<number>> to <<user variable>> +e.g. add 2 to n3 +.endd +There are 10 user variables of this type, and their values can be obtained by +the normal expansion syntax (for example \$n3$\) in other commands. At the +start of filtering, these variables all contain zero. Both arguments of the +\"add"\ command are expanded before use, making it possible to add variables to +each other. Subtraction can be obtained by adding negative numbers. + + +.section The deliver command +.rset SECTdeliver "~~chapter.~~section" +.display + deliver <<mail address>> +e.g. deliver "Dr Livingstone <David@@somewhere.africa.example>" +.endd +This provides a forwarding operation. The message is sent on to the given +address, exactly as happens if the address had appeared in a traditional +\(.forward)\ file. If you want to deliver the message to a number of different +addresses, you can use more than one \"deliver"\ command (each one may have +only one address). However, duplicate addresses are discarded. + +To deliver a copy of the message to your normal mailbox, your login name can be +given as the address. Once an address has been processed by the filtering +mechanism, an identical generated address will not be so processed again, so +doing this does not cause a loop. + +However, if you have a mail alias, you should $it{not} refer to it here. For +example, if the mail address \"L.Gulliver"\ is aliased to \"lg103"\ then all +references in Gulliver's \(.forward)\ file should be to \"lg103"\. A reference +to the alias will not work for messages that are addressed to that alias, +since, like \(.forward)\ file processing, aliasing is performed only once on an +address, in order to avoid looping. + +Following the new address, an optional second address, preceded by +\"errors@_to"\ may appear. This changes the address to which delivery errors on +the forwarded message will be sent. Instead of going to the message's original +sender, they go to this new address. For ordinary users, the only value that is +permitted for this address is the user whose filter file is being processed. +For example, the user \"lg103"\ whose mailbox is in the domain +\lilliput.example\ could have a filter file that contains +.display asis + deliver jon@elsewhere.example errors_to lg103@lilliput.example +.endd +Clearly, using this feature makes sense only in situations where not all +messages are being forwarded. In particular, bounce messages must not be +forwarded in this way, as this is likely to create a mail loop if something +goes wrong. + + +.section The save command +.rset SECTsave "~~chapter.~~section" +.display + save <<file name>> +e.g. save @$home/mail/bookfolder +.endd +This causes a copy of the message to be appended to the given file (that is, +the file is used as a mail folder). More than one \"save"\ command may appear; +each one causes a copy of the message to be written to its argument file, +provided they are different (duplicate \"save"\ commands are ignored). + +If the file name does not start with a / character, the contents of the +\$home$\ variable are prepended, unless it is empty. In conventional +configurations, this variable is normally set in a user filter to the user's +home directory, but the system administrator may set it to some other path. In +some configurations, \$home$\ may be unset, in which case a non-absolute path +name may be generated. Such configurations convert this to an absolute path +when the delivery takes place. In a system filter, \$home$\ is never set. + +The user must of course have permission to write to the file, and the writing +of the file takes place in a process that is running as the user, under the +user's primary group. Any secondary groups to which the user may belong are not +normally taken into account, though the system administrator can configure Exim +to set them up. In addition, the ability to use this command at all is +controlled by the system administrator -- it may be forbidden on some systems. + +An optional mode value may be given after the file name. The value for the mode +is interpreted as an octal number, even if it does not begin with a zero. For +example: +.display + save /some/folder 640 +.endd +This makes it possible for users to override the system-wide mode setting for +file deliveries, which is normally 600. If an existing file does not have the +correct mode, it is changed. + +An alternative form of delivery may be enabled on your system, in which each +message is delivered into a new file in a given directory. If this is the case, +this functionality can be requested by giving the directory name terminated by +a slash after the \"save"\ command, for example +.display + save separated/messages/ +.endd +There are several different formats for such deliveries; check with your system +administrator or local documentation to find out which (if any) are available +on your system. If this functionality is not enabled, the use of a path name +ending in a slash causes an error. + + +.section The pipe command +.rset SECTpipe "~~chapter.~~section" +.display + pipe <<command>> +e.g. pipe "@$home/bin/countmail @$sender@_address" +.endd +This command sets up delivery to a specified command using a pipe. Remember, +however, that no deliveries are done while the filter is being processed. All +deliveries happen later on. Therefore, the result of running the pipe is not +available to the filter. + +When the deliveries are done, a separate process is run, and a copy of the +message is passed on its standard input. The process runs as the user, under +the user's primary group. Any secondary groups to which the user may belong are +not normally taken into account, though the system administrator can configure +Exim to set them up. More than one \"pipe"\ command may appear; each one causes +a copy of the message to be written to its argument pipe, provided they are +different (duplicate \"pipe"\ commands are ignored). + +When the time comes to transport the message, +the command supplied to \"pipe"\ is split up by Exim into a command name and a +number of arguments. These are delimited by white space except for arguments +enclosed in double quotes, in which case backslash is interpreted as an escape, +or in single quotes, in which case no escaping is recognized. Note that as the +whole command is normally supplied in double quotes, a second level of quoting +is required for internal double quotes. For example: +.display asis + pipe "$home/myscript \"size is $message_size\"" +.endd +String expansion is performed on the separate components after the line has +been split up, and the command is then run directly by Exim; it is not run +under a shell. Therefore, substitution cannot change the number of arguments, +nor can quotes, backslashes or other shell metacharacters in variables cause +confusion. + +Documentation for some programs that are normally run via this kind of pipe +often suggest that the command should start with +.display asis +IFS=" " +.endd +This is a shell command, and should $it{not} be present in Exim filter files, +since it does not normally run the command under a shell. + +However, there is an option that the administrator can set to cause a shell to +be used. In this case, the entire command is expanded as a single string and +passed to the shell for interpretation. It is recommended that this be avoided +if at all possible, since it can lead to problems when inserted variables +contain shell metacharacters. + +The default \\PATH\\ set up for the command is determined by the system +administrator, usually containing at least \/usr/bin\ so that common commands +are available without having to specify an absolute file name. However, it is +possible for the system administrator to restrict the pipe facility so that the +command name must not contain any / characters, and must be found in one of the +directories in the configured \\PATH\\. It is also possible for the system +administrator to lock out the use of the \"pipe"\ command altogether. + +When the command is run, a number of environment variables are set up. The +complete list for pipe deliveries may be found in the Exim reference manual. +Those that may be useful for pipe deliveries from user filter files are: +.display +.tabs 20 +DOMAIN $t $rm{the domain of the address} +HOME $t $rm{your home directory} +LOCAL@_PART $t $rm{see below} +LOCAL@_PART@_PREFIX $t $rm{see below} +LOCAL@_PART@_SUFFIX $t $rm{see below} +LOGNAME $t $rm{your login name} +MESSAGE@_ID $t $rm{the message's unique id} +PATH $t $rm{the command search path} +RECIPIENT $t $rm{the complete recipient address} +SENDER $t $rm{the sender of the message} +SHELL $t $bf{/bin/sh} +USER $t $rm{see below} +.endd +\\LOCAL@_PART\\, \\LOGNAME\\, and \\USER\\ are all set to the same value, +namely, your login id. \\LOCAL@_PART@_PREFIX\\ and \\LOCAL@_PART@_SUFFIX\\ may +be set if Exim is configured to recognize prefixes or suffixes in the local +parts of addresses. For example, a message addressed to +\*pat-suf2@@domain.example*\ may cause user \*pat*\'s filter file to be run. If +this sets up a pipe delivery, \\LOCAL@_PART@_SUFFIX\\ is \"-suf2"\ when the +pipe command runs. The system administrator has to configure Exim specially for +this feature to be available. + +If you run a command that is a shell script, be very careful in your use of +data from the incoming message in the commands in your script. RFC 2822 is very +generous in the characters that are legally permitted to appear in mail +addresses, and in particular, an address may begin with a vertical bar or a +slash. For this reason you should always use quotes round any arguments that +involve data from the message, like this: +.display asis +/some/command '$SENDER' +.endd +so that inserted shell meta-characters do not cause unwanted effects. + +Remember that, as was explained earlier, the pipe command is not run at the +time the filter file is interpreted. The filter just defines what deliveries +are required for one particular addressee of a message. The deliveries +themselves happen later, once Exim has decided everything that needs to be done +for the message. + +A consequence of this is that you cannot inspect the return code from the pipe +command from within the filter. Nevertheless, the code returned by the command +is important, because Exim uses it to decide whether the delivery has succeeded +or failed. + +The command should return a zero completion code if all has gone well. Most +non-zero codes are treated by Exim as indicating a failure of the pipe. This is +treated as a delivery failure, causing the message to be returned to its +sender. However, there are some completion codes which are treated as temporary +errors. The message remains on Exim's spool disk, and the delivery is tried +again later, though it will ultimately time out if the delivery failures go on +too long. The completion codes to which this applies can be specified by the +system administrator; the default values are 73 and 75. + +The pipe command should not normally write anything to its standard output or +standard error file descriptors. If it does, whatever is written is normally +returned to the sender of the message as a delivery error, though this action +can be varied by the system administrator. + + +.section Mail commands +.rset SECTmail "~~chapter.~~section" +There are two commands which cause the creation of a new mail message, neither +of which count as a significant delivery unless the command is preceded by the +word \"seen"\. This is a powerful facility, but it should be used with care, +because of the danger of creating infinite sequences of messages. The system +administrator can forbid the use of these commands altogether. + +To help prevent runaway message sequences, these commands have no effect when +the incoming message is a delivery error message, and messages sent by this +means are treated as if they were reporting delivery errors. Thus they should +never themselves cause a delivery error message to be returned. The basic +mail-sending command is +.display + mail [to <<address-list>>] + [cc <<address-list>>] + [bcc <<address-list>>] + [from <<address>>] + [reply@_to <<address>>] + [subject <<text>>] + [extra@_headers <<text>>] + [text <<text>>] + [[expand] file <<filename>>] + [return message] + [log <<log file name>>] + [once <<note file name>>] + [once@_repeat <<time interval>>] +.blank +e.g. mail text "Your message about @$h@_subject: has been received" +.endd + +Each <<address-list>> can contain a number of addresses, separated by commas, +in the format of a ::To:: or ::Cc:: header line. In fact, the text you supply +here is copied exactly into the appropriate header line. Thus, it may contain +additional information as well as email addresses. For example: +.display asis +mail to "Julius Caesar <jc@rome.example>, \ + <ma@rome.example> (Mark A.)" +.endd +Similarly, the texts supplied for ::From:: and ::Reply-to:: are copied into +their respective header lines. + +As a convenience for use in one common case, there is also a command called +\vacation\. It behaves in the same way as \mail\, except that the defaults for +the +\"subject"\, +\"file"\, \"log"\, \"once"\, and \"once@_repeat"\ options are +.display +subject "On vacation" +expand file .vacation.msg +log .vacation.log +once .vacation +once@_repeat 7d +.endd +respectively. These are the same file names and repeat period used by the +traditional Unix \"vacation"\ command. The defaults can be overridden by +explicit settings, but if a file name is given its contents are expanded only +if explicitly requested. + +\**Warning**\: The \"vacation"\ command should always be used conditionally, +subject to at least the \"personal"\ condition (see section ~~SECTpersonal +below) so as not to send automatic replies to non-personal messages from +mailing lists or elsewhere. Sending an automatic response to a mailing list or +a mailing list manager is an Internet Sin. + +For both commands, the key/value argument pairs can appear in any order. At +least one of \"text"\ or \"file"\ must appear (except with \"vacation"\); if +both are present, the text string appears first in the message. If \"expand"\ +precedes \"file"\, each line of the file is subject to string expansion as +it is included in the message. + +Several lines of text can be supplied to \"text"\ by including the escape +sequence `@\n' in the string where newlines are required. If the command is +output during filter file testing, newlines in the text are shown as `@\n'. + +Note that the keyword for creating a \"Reply-To:"\ header is \reply@_to\, +because Exim keywords may contain underscores, but not hyphens. If the \"from"\ +keyword is present and the given address does not match the user who owns the +forward file, Exim normally adds a \"Sender:"\ header to the message, +though it can be configured not to do this. + +The \extra@_headers\ keyword allows you to add custom header lines to the +message. The text supplied must be one or more syntactically valid RFC 2882 +header lines. You can use `@\n' within quoted text to specify newlines between +headers, and also to define continued header lines. For example: +.display asis +extra_headers "h1: first\nh2: second\n continued\nh3: third" +.endd +No newline should appear at the end of the final header line. + +If no \"to"\ argument appears, the message is sent to the address in the +\"@$reply@_address"\ variable (see section ~~SECTfilterstringexpansion above). +An \"In-Reply-To:"\ header is automatically included in the created message, +giving a reference to the message identification of the incoming message. + +If \"return message"\ is specified, the incoming message that caused the filter +file to be run is added to the end of the message, subject to a maximum size +limitation. + +If a log file is specified, a line is added to it for each message sent. + +If a \"once"\ file is specified, it is used to hold a database for remembering +who has received a message, and no more than one message is ever sent to any +particular address, unless \"once@_repeat"\ is set. This specifies a time +interval after which another copy of the message is sent. The interval is +specified as a sequence of numbers, each followed by the initial letter of one +of `seconds', `minutes', `hours', `days', or `weeks'. For example, +.display asis +once_repeat 5d4h +.endd +causes a new message to be sent if 5 days and 4 hours have elapsed since the +last one was sent. There must be no white space in a time interval. + +Commonly, the file name specified for \"once"\ is used as the base name for +direct-access (DBM) file operations. There are a number of different DBM +libraries in existence. Some operating systems provide one as a default, but +even in this case a different one may have been used when building Exim. With +some DBM libraries, specifying \"once"\ results in two files being created, +with the suffixes \".dir"\ and \".pag"\ being added to the given name. With +some others a single file with the suffix \".db"\ is used, or the name is used +unchanged. + +Using a DBM file for implementing the \"once"\ feature means that the file +grows as large as necessary. This is not usually a problem, but some system +administrators want to put a limit on it. The facility can be configured not to +use a DBM file, but instead, to use a regular file with a maximum size. The +data in such a file is searched sequentially, and if the file fills up, the +oldest entry is deleted to make way for a new one. This means that some +correspondents may receive a second copy of the message after an unpredictable +interval. Consult your local information to see if your system is configured +this way. + +More than one \"mail"\ or \"vacation"\ command may be obeyed in a single filter +run; they are all honoured, even when they are to the same recipient. + + +.section Logging commands +.rset SECTlog "~~chapter.~~section" +A log can be kept of actions taken by a filter file. This facility is normally +available in conventional configurations, but there are some situations where +it might not be. Also, the system administrator may choose to disable it. Check +your local information if in doubt. + +Logging takes place while the filter file is being interpreted. It does not +queue up for later like the delivery commands. The reason for this is so that a +log file need be opened only once for several write operations. There are two +commands, neither of which constitutes a significant delivery. The first +defines a file to which logging output is subsequently written: +.display + logfile <<file name>> +e.g. logfile @$home/filter.log +.endd +The file name must be fully qualified. You can use \$home$\, as in this +example, to refer to your home directory. The file name may optionally be +followed by a mode for the file, which is used if the file has to be created. +For example, +.display + logfile @$home/filter.log 0644 +.endd +The number is interpreted as octal, even if it does not begin with a zero. +The default for the mode is 600. It is suggested that the \"logfile"\ command +normally appear as the first command in a filter file. Once \"logfile"\ has +been obeyed, the \"logwrite"\ command can be used to write to the log file: +.display + logwrite "<<some text string>>" +e.g. logwrite "@$tod@_log @$message@_id processed" +.endd +It is possible to have more than one \"logfile"\ command, to specify writing to +different log files in different circumstances. Writing takes place at the end +of the file, and a newline character is added to the end of each string if +there isn't one already there. Newlines can be put in the middle of the string +by using the `@\n' escape sequence. Lines from simultaneous deliveries may get +interleaved in the file, as there is no interlocking, so you should plan your +logging with this in mind. However, data should not get lost. + + +.section The finish command +.rset SECTfinish "~~chapter.~~section" +The command \"finish"\, which has no arguments, causes Exim to stop +interpreting the filter file. This is not a significant action unless preceded +by \"seen"\. A filter file containing only \"seen finish"\ is a black hole. + +.section The testprint command +.rset SECTtestprint "~~chapter.~~section" +It is sometimes helpful to be able to print out the values of variables when +testing filter files. The command +.display + testprint <<text>> +e.g. testprint "home=@$home reply@_address=@$reply@_address" +.endd +does nothing when mail is being delivered. However, when the filtering code is +being tested by means of the \-bf-\ option (see section ~~SECTtesting above), +the value of the string is written to the standard output. + +.section The fail command +.rset SECTfail "~~chapter.~~section" +When Exim's filtering facilities are being used as a system filter, the +\"fail"\ command is available, to force delivery failure. Because this command +is normally usable only by the system administrator, and not enabled for use by +ordinary users, it is described in more detail in the main Exim specification +rather than in this document. + +.section The freeze command +.rset SECTfreeze "~~chapter.~~section" +When Exim's filtering facilities are being used as a system filter, the +\"freeze"\ command is available, to freeze a message on the queue. Because this +command is normally usable only by the system administrator, and not enabled +for use by ordinary users, it is described in more detail in the main Exim +specification rather than in this document. + + +.section The headers command +.rset SECTheaders "~~chapter.~~section" +The \"headers"\ command can be used to change the target character set which is +used when translating the contents of encoded header lines for insertion by the +\"@$header@_"\ mechanism (see section ~~SECTheadervariables above). The default +can be set in the Exim configuration; if not specified, ISO-8859-1 is used. The +only currently supported format for the \"headers"\ command is as in this +example: +.display asis +headers charset "UTF-8" +.endd +That is, \"headers"\ is followed by the word \"charset"\ and then the name of a +character set. This particular example would be useful if you wanted to compare +the contents of a header to a UTF-8 string. + + +.section Obeying commands conditionally +.rset SECTif "~~chapter.~~section" +Most of the power of filtering comes from the ability to test conditions and +obey different commands depending on the outcome. The \"if"\ command is used to +specify conditional execution, and its general form is +.display +if <<condition>> +then <<commands>> +elif <<condition>> +then <<commands>> +else <<commands>> +endif +.endd +There may be any number of \"elif"\ and \"then"\ sections (including none) and +the \"else"\ section is also optional. Any number of commands, including nested +\"if"\ commands, may appear in any of the <<commands>> sections. + +Conditions can be combined by using the words \"and"\ and \"or"\, and round +brackets (parentheses) can be used to specify how several conditions are to +combine. Without brackets, \"and"\ is more binding than \"or"\. +For example, +.display asis +if + $h_subject: contains "Make money" or + $h_precedence: is "junk" or + ($h_sender: matches ^\\d{8}@ and not personal) or + $message_body contains "this is spam" +then + seen finish +endif +.endd +A condition can be preceded by \"not"\ to negate it, and there are also some +negative forms of condition that are more English-like. + + + +.section String testing conditions +There are a number of conditions that operate on text strings, using the words +`begins', `ends', `is', `contains' and `matches'. + +Note that if you want to apply the same test to more than one header line, you +can easily concatenate them into a single string for testing, as in this +example: +.display asis +if "$h_to:, $h_cc:" contains me@domain.example then ... +.endd + +If any of the condition names are written in lower case, the testing of letters +is done without regard to case; if they are written in upper case (for example, +`CONTAINS') then the case of letters is significant. +.display + <<text1>> begins <<text2>> + <<text1>> does not begin <<text2>> +e.g. @$header@_from: begins "Friend@@" +.endd +A `begins' test checks for the presence of the second string at the start of +the first, both strings having been expanded. +.display + <<text1>> ends <<text2>> + <<text1>> does not end <<text2>> +e.g. @$header@_from: ends "@public.com.example" +.endd +An `ends' test checks for the presence of the second string at the end of +the first, both strings having been expanded. +.display + <<text1>> is <<text2>> + <<text1>> is not <<text2>> +e.g. @$local@_part@_suffix is "-foo" +.endd +An `is' test does an exact match between the strings, having first expanded +both strings. +.display + <<text1>> contains <<text2>> + <<text1>> does not contain <<text2>> +e.g. @$header@_subject: contains "evolution" +.endd +A `contains' test does a partial string match, having expanded both strings. +.display + <<text1>> matches <<text2>> + <<text1>> does not match <<text2>> +e.g. @$sender@_address matches "(bill|john)@@" +.endd +For a `matches' test, after expansion of both strings, the second one is +interpreted as a regular expression. Exim uses the PCRE regular expression +library, which provides regular expressions that are compatible with Perl. + +.em +The match succeeds if the regular expression matches any part of the first +string. If you want a regular expression to match only at the start or end of +the subject string, you must encode that requirement explicitly, using the @^ +or @$ metacharacters. The above example, which is not so constrained, matches +all these addresses: +.display asis +bill@test.example +john@some.example +spoonbill@example.com +littlejohn@example.com +.endd +To match only the first two, you could use this: +.display asis +if $sender_address matches "^(bill|john)@" then ... +.endd +.nem + +Care must be taken if you need a backslash in a regular expression, because +backslashes are interpreted as escape characters both by the string expansion +code and by Exim's normal processing of strings in quotes. For example, if you +want to test the sender address for a domain ending in \".com"\ the regular +expression is +.display asis +\.com$ +.endd +The backslash and dollar sign in that expression have to be escaped when used +in a filter command, as otherwise they would be interpreted by the expansion +code. Thus what you actually write is +.display asis +if $sender_address matches \\.com\$ +.endd +An alternative way of handling this is to make use of the \"@\N"\ expansion +flag for suppressing expansion: +.display asis +if $sender_address matches \N\.com$\N +.endd +Everything between the two occurrences of \"@\N"\ is copied without change by +the string expander (and in fact you do not need the final one, because it is +at the end of the string). + +If the regular expression is given in quotes (mandatory only if it contains +white space) you have to write either +.display asis +if $sender_address matches "\\\\.com\\$" +.endd +or +.display asis +if $sender_address matches "\\N\\.com$\\N" +.endd + + +If the regular expression contains bracketed sub-expressions, numeric +variable substitutions such as \$1$\ can be used in the subsequent actions +after a successful match. If the match fails, the values of the numeric +variables remain unchanged. Previous values are not restored after \"endif"\ -- +in other words, only one set of values is ever available. If the condition +contains several sub-conditions connected by \"and"\ or \"or"\, it is the +strings extracted from the last successful match that are available in +subsequent actions. Numeric variables from any one sub-condition are also +available for use in subsequent sub-conditions, since string expansion of a +condition occurs just before it is tested. + +.section Numeric testing conditions +The following conditions are available for performing numerical tests: +.display + <<number1>> is above <<number2>> + <<number1>> is not above <<number2>> + <<number1>> is below <<number2>> + <<number1>> is not below <<number2>> +e.g. @$message@_size is not above 10k +.endd +The <<number>> arguments must expand to strings of digits, optionally followed +by one of the letters K or M (upper case or lower case) which cause +multiplication by 1024 and 1024x1024 respectively. + +.section Testing for significant deliveries +Whether or not any previously obeyed filter commands have resulted in a +significant delivery can be tested by the condition \"delivered"\, for example: +.display asis +if not delivered then save mail/anomalous endif +.endd + +.section Testing for error messages +The condition \"error@_message"\ is true if the incoming message is a mail +delivery error message (bounce message). Putting the command +.display asis +if error_message then finish endif +.endd +at the head of your filter file is a useful insurance against things going +wrong in such a way that you cannot receive delivery error reports, and is +highly recommended. Note that \"error@_message"\ is a condition, not an +expansion variable, and therefore is not preceded by \@$\. + +.section Testing for personal mail +.rset SECTpersonal "~~chapter.~~section" +A common requirement is to distinguish between incoming personal mail and mail +from a mailing list, +or from a robot or other automatic process (for example, a bounce message). +In particular, this test is normally required for so-called `vacation +messages'. The condition +.display + personal +.endd +is a shorthand for +.display + not error@_message and + @$header@_to: contains "@$local@_part@@@$domain" and + @$header@_from: does not contain "@$local@_part@@@$domain" and + @$header@_from: does not contain "server@@" and + @$header@_from: does not contain "daemon@@" and + @$header@_from: does not contain "root@@" and + @$header@_auto-submitted: does not contain "auto-" and + @$header@_subject: does not contain "circular" and + @$header@_precedence: does not contain "bulk" and + @$header@_precedence: does not contain "list" and + @$header@_precedence: does not contain "junk" +.endd +The variable \$local@_part$\ contains the local part of the mail address of +the user whose filter file is being run -- it is normally your login id. The +\$domain$\ variable contains the mail domain. This condition tests for the +appearance of the current user in the \"To:"\ header, checks that the sender is +not the current user or one of a number of common daemons, and checks the +content of the \"Subject:"\ and \"Precedence:"\ headers. + +If prefixes or suffixes are in use for local parts -- something which depends +on the configuration of Exim (see section ~~SECTmbox below) -- the first two +tests above are also done with +.display asis +$local_part_prefix$local_part$local_part_suffix +.endd +instead of just \$local@_part$\. If the system is configured to rewrite local +parts of mail addresses, for example, to rewrite `dag46' as `Dirk.Gently', +the rewritten form of the address is also used in the tests. + +This example shows the use of \"personal"\ in a filter file that is sending out +vacation messages: +.display asis +if personal then + mail + to $reply_address + subject "Re: $h_subject:" + file $home/vacation/message + once $home/vacation/once + once_repeat 10d +endif +.endd + +It is quite common for people who have mail accounts on a number of different +systems to forward all their mail to one system, and in this case a check for +personal mail should test all their various mail addresses. To allow for this, +the \"personal"\ condition keyword can be followed by +.display +alias <<address>> +.endd +any number of times, for example +.display asis +if personal alias smith@else.where.example + alias jones@other.place.example +then ... +.endd +This causes messages containing the alias addresses in any places where the +local address is tested to be treated as personal. + +.section Testing delivery status +There are two conditions which are intended mainly for use in system filter +files, but which are available in users' filter files as well. The condition +\"first@_delivery"\ is true if this is the first attempt to deliver the +message, and false otherwise. +.em +This indicator is not reset until the first delivery process successfully +terminates; if there is a crash or a power failure (for example), the next +delivery attempt is also a `first delivery'. +.nem + +In a user filter file it will be false only if +there was previously an error in the filter, or if a delivery for the user +failed owing to, for example, a quota error, or forwarding to a remote +address that was deferred for some reason. + +The condition \"manually@_thawed"\ is true only if the message was `frozen' for +some reason, and was subsequently released by the system administrator. It is +unlikely to be of use in users' filter files. + +.section Testing a list of addresses +There is a facility for looping through a list of addresses and applying a +condition to each of them. It takes the form +.display +foranyaddress <<string>> (<<condition>>) +.endd +where <<string>> is interpreted as a list of RFC 2822 addresses, as in a +typical header line, and <<condition>> is any valid filter condition or +combination of conditions. The `group' syntax that is defined for certain +header lines that contain addresses is supported. + +The parentheses surrounding the condition are mandatory, to delimit it from +possible further sub-conditions of the enclosing \"if"\ command. Within the +condition, the expansion variable \$thisaddress$\ is set to the non-comment +portion of each of the addresses in the string in turn. For example, if the +string is +.display asis +B.Simpson <bart@sfld.example>, lisa@sfld.example (his sister) +.endd +then \$thisaddress$\ would take on the values \"bart@@sfld.example"\ and +\"lisa@@sfld.example"\ in turn. + +If there are no valid addresses in the list, the whole condition is false. If +the internal condition is true for any one address, the overall condition is +true and the loop ends. If the internal condition is false for all addresses in +the list, the overall condition is false. This example tests for the presence +of an eight-digit local part in any address in a \To:\ header: +.display asis +if foranyaddress $h_to: ( $thisaddress matches ^\\d{8}@ ) then ... +.endd +When the overall condition is true, the value of \$thisaddress$\ in the +commands that follow \"then"\ is the last value it took on inside the loop. At +the end of the \"if"\ command, the value of \$thisaddress$\ is reset to what it +was before. It is best to avoid the use of multiple occurrences of +\"foranyaddress"\, nested or otherwise, in a single \"if"\ command, if the +value of \$thisaddress$\ is to be used afterwards, because it isn't always +clear what the value will be. Nested \"if"\ commands should be used instead. + +Header lines can be joined together if a check is to be applied to more than +one of them. For example: +.display asis +if foranyaddress $h_to:,$h_cc: .... +.endd +scans through the addresses in both the \To:\ and the \Cc:\ headers. + +.section Multiple personal mailboxes +.rset SECTmbox "~~chapter.~~section" +The system administrator can configure Exim so that users can set up variants +on their email addresses and handle them separately. Consult your system +administrator or local documentation to see if this facility is enabled on your +system, and if so, what the details are. + +The facility involves the use of a prefix or a suffix on an email address. For +example, all mail addressed to \lg103-<<something>>\ would be the property of +user \lg103\, who could determine how it was to be handled, depending on the +value of <<something>>. + +There are two possible ways in which this can be set up. The first possibility +is the use of multiple \(.forward)\ files. In this case, mail to \lg103-foo\, +for example, is handled by looking for a file called \.forward-foo\ in +\lg103's\ home directory. If such a file does not exist, delivery fails and the +message is returned to its sender. + +The alternative approach is to pass all messages through a single \(.forward)\ +file, which must be a filter file in order to distinguish between the different +cases by referencing the variables \$local@_part@_prefix$\ or +\$local@_part@_suffix$\, as in the final example in section ~~SECTex below. If +the filter file does not handle a prefixed or suffixed address, delivery fails +and the message is returned to its sender. + +It is possible to configure Exim to support both schemes at once. In this case, +a specific \.forward-foo\ file is first sought; if it is not found, the basic +\(.forward)\ file is used. + +The \"personal"\ test (see section ~~SECTpersonal) includes prefixes and +suffixes in its checking. + + +.section Ignoring delivery errors +As was explained above, filtering just sets up addresses for delivery -- no +deliveries are actually done while a filter file is active. If any of the +generated addresses subsequently suffers a delivery failure, an error message +is generated in the normal way. However, if the filter command which sets up a +delivery is preceded by the word \"noerror"\, errors for that delivery, +$it{and any deliveries consequent on it} (that is, from alias, forwarding, or +filter files it invokes) are ignored. + + +.section Examples of Exim filter commands +.rset SECTex "~~chapter.~~section" +Simple forwarding: +.display asis +# Exim filter +deliver baggins@rivendell.middle-earth.example +.endd +Vacation handling using traditional means, assuming that the \.vacation.msg\ +and other files have been set up in your home directory: +.display asis +# Exim filter +unseen pipe "/usr/ucb/vacation \"$local_part\"" +.endd +Vacation handling inside Exim, having first created a file called +\.vacation.msg\ in your home directory: +.display asis +# Exim filter +if personal then vacation endif +.endd +File some messages by subject: +.display asis +# Exim filter +if $header_subject: contains "empire" or + $header_subject: contains "foundation" +then + save $home/mail/f+e +endif +.endd +Save all non-urgent messages by weekday: +.display asis +# Exim filter +if $header_subject: does not contain "urgent" and + $tod_full matches "^(...)," +then + save $home/mail/$1 +endif +.endd +Throw away all mail from one site, except from postmaster: +.display asis +# Exim filter +if $reply_address contains "@spam.site.example" and + $reply_address does not contain "postmaster@" +then + seen finish +endif +.endd +.if ~~sgcal +.if ~~sys.leftonpage < 6ld +.newpage +.fi +.fi +Handle multiple personal mailboxes +.display asis +# Exim filter +if $local_part_suffix is "-foo" +then + save $home/mail/foo +elif $local_part_suffix is "-bar" +then + save $home/mail/bar +endif +.endd + +. End of filter diff --git a/doc/doc-src/markup.sg b/doc/doc-src/markup.sg new file mode 100644 index 000000000..43e8853ac --- /dev/null +++ b/doc/doc-src/markup.sg @@ -0,0 +1,86 @@ +. $Cambridge: exim/doc/doc-src/markup.sg,v 1.1 2004/10/07 15:04:35 ph10 Exp $ +. +. SGCAL markup that is used for the Exim manual, and also for +. the Filter document. + +. Flags for both plain and fancy + +.flag __ "@_$S0" + +.flag \\ "$sc{" "}" +.flag ---- "@-@-@-@-" + +. Markup User for PostScript/PDF Text Info HTML +. ------------------------------------------------------------------------------ +. \\...\\ SMTP, build small caps caps caps small caps +. \(...)\ file name bold plain @file->`...' italic +. \?...?\ URL bold plain plain URL +. \%...%\ driver name bold "quoted" "quoted" bold +. ::...:: header name bold: "quoted:" "quoted:" italic: +. \...\ option bold "quoted" "quoted" fixed-pitch +. \$...$\ variable $bold $plain $plain $fixed-pitch +. \-...-\ cmd option -bold -plain -plain -italic +. <<...>> data type <italic> <plain> <plain> <italic> +. \*...*\ defn, emph, italic "quoted" @dfn->"..." italic +. domain, user +. \"..."\ literal fixed-pitch "quoted" @file->`...' fixed-pitch +. \**...**\ warn, item bold plain plain bold + +.if ~~sys.fancy +.flag \ "$bf{" "}" +.flag \" "$tt{" +.flag "\ "}" +.flag \( "$bf{" +.flag )\ "}" +.flag \? "$bf{" +.flag ?\ "}" +.flag \$ "$bf{@$" +.flag $\ "}" +.flag \% "$bf{" +.flag %\ "} +.flag :: "$it{" ":}" +.flag \- "$bf{-" +.flag -\ "}" +.flag << "<$it{" +.flag >> "}>" +.flag \** "$bf{" +.flag **\ "}" +.flag \* "$it{" +.flag *\ "}" +.flag $*$ "$D2*$U2" +.flag $**$ "$rm{$=178}" +. +.else +.pagedepth ~~sys.pagedepth - 1ld +.linelength 78em +.emphasis 79em +.footdepth 0 +.disable formfeed +.backspace none +.set chapspaceb 24 +.set sspacea 24 +.flag \ """" +.flag \" """" +.flag "\ """" +.flag \( "" +.flag )\ "" +.flag \? "" +.flag ?\ "" +.flag \$ "@$" +.flag $\ "" +.flag \% "" +.flag %\ "" +.flag :: "" ":" +.flag \- "@-" +.flag -\ "" +.flag << "<" +.flag >> ">" +.flag \** "" +.flag **\ "" +.flag \* """" +.flag *\ """" +.flag $*$ "*" +.flag $**$ "*" +.flag --$< "-" +.fi + diff --git a/doc/doc-src/spec.src b/doc/doc-src/spec.src new file mode 100644 index 000000000..41a2ba13b --- /dev/null +++ b/doc/doc-src/spec.src @@ -0,0 +1,27935 @@ +. $Cambridge: exim/doc/doc-src/spec.src,v 1.1 2004/10/07 15:04:35 ph10 Exp $ +. +.set version "4.40" +.set previousversion "4.30" +.set versionmonth "July" +.set versionyear "2004" +.set ACL "ACL" + +. The last of those is to make ACL index entries easier to type. It is put +. up here so that it gets picked up by the HTML converter, which otherwise +. skips to the first chapter. A longer version is set below for use in the +. printed index. + +.set sgcal true +.set html false +.set texinfo false + +.if !set style +.library "a4ps" +.linelength ~~sys.linelength + 0.2in +.set newlinelength ~~sys.linelength +.emphasis ~~sys.linelength + 0.1in +.pagedepth ~~sys.pagedepth - 0.2in +.bindfont 51 "atl/Times-Bold" 9 +.bindfont 52 "atl/Times-Roman" 9 +.bindfont 53 "atl/Times-Roman" 7 +.bindfont 54 "atl/Courier" 9 +.bindfont 55 "atl/Courier-Bold" ~~maintypesize +.bindfont 56 "atl/Times-Italic" 7 +.bindfont 57 "atl/Times-Bold" 7 +.bindfont 58 "atl/Symbol" 7 +.set ssspaceb 1.50 + +.if ~~sgcal +. Used for the "small print" incorporated code stuff. Only rm, it, bf, sp are +. actually used at present. +. rm it sl bf bi ss tt sp sc +.fontgroup 9 = 53 56 0 57 0 0 0 58 0 +.fi +.fi + +.if !~~sys.fancy +.fontgroup 9 = 0 0 0 0 0 0 0 0 0 +.fi + +.include "markup.sg" + +.if ~~sys.fancy +.flag $smc{ "$push$g0$f54" +.flag $sm{ "$push$g0$f53" +.flag $smi{ "$push$g0$f56" +.flag $as{ "$push$g0$f52" +.flag $ab{ "$push$g0$f51" +.flag $cb{ "$push$g0$f55" +. +.else +.flag $smc{ "$push" +.flag $sm{ "$push" +.flag $smi{ "$push" +.flag $cb{ "$push" +.fi + +.macro isunderscore "string" +.set string "~~1" +.set length length "~~1" +.undrec 1 +.endm + +.macro undrec "offset" +.if ~~1 > ~~length +.set underscore false +.else +.set sub "~~string"(1,~~1) +.if "~~sub" == "_" +.set underscore true +.else +.set next ~~1 + 1 +.undrec ~~next +.fi +.fi +.endm + +.macro testunderscore "string" +.isunderscore "~~1" +.newline +.endm + +.macro tabs 6 +.if ~~sys.fancy +.tabset ~~1em +.else +.set temp (~~1 * 5)/4 +.tabset ~~temp em +.fi +.endm + +.macro startoptions +.newline +.push +.if ~~sys.fancy +.indent 6em +.else +.indent 7em +.fi +.endm + +.macro endoptions +.newline +.pop +.endm + +.macro option "option" "" +.newpar +.index \-~~1-\ option +.tempindent 0 +\-~~1-\~~2#$i +.nosep +.endm + +.macro startitems +.newline +.push +.indent 3em +.endm + +.macro enditems +.newline +.pop +.endm + +.macro item "item" "6" +.newpar +.if ~~sys.leftonpage < ~~2ld +.newpage +.fi +.tempindent 0 +\**~~1**\ +.blank +.endm + +.macro startconf +.newline +.push +.if ~~sys.fancy +.indent 2em +.tabset 9em +.else +.indent 4em +.tabset 13em +.fi +.endm + +.macro endconf +.newline +.pop +.endm + +.macro conf "option" "type" "default" "6" +.newpar +.if ~~sys.leftonpage < ~~4ld +.newpage +.fi +.testunderscore "~~1" +.if ~~underscore +.index \~~1\ +.else +.index \~~1\ option +.fi +.tempindent 0 +\**~~1**\ $c $rm{Type:} $it{~~2} $e $rm{Default:} $it{~~3} +.blank +.endm + +.set contents true +.set figurenumber -1 +.set displayindent 2em + +.index @$1, @$2, etc. $it{see numerical variables} +.index address||rewriting $it{see rewriting} +.index CR character $it{see carriage return} +.index CRL $it{see certificate revocation list} +.index delivery||failure report $it{see bounce message} +.index dialup $it{see intermittently connected hosts} +.index failover $it{see fallback} +.index fallover $it{see fallback} +.index filter||Sieve $it{see Sieve filter} +.index ident $it{see RFC 1413} +.index LF character $it{see linefeed} +.index maximum $it{see limit} +.index NUL $it{see binary zero} +.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 SSL $it{see TLS} +.index string||expansion $it{see expansion} +.index top bit $it{see 8-bit characters} +.index variables $it{see expansion, variables} +.index zero, binary $it{see binary zero} + +. This is used for the printed index. See setting above for +. the HTML index value. + +.set ACL "access control lists (ACLs)" + +. ====================================================== + +.push +.disable filling +.justify centre +.nofoot +.space 8ld +$chead{University of Cambridge Computing Service} +.space 2ld +$chead{Specification of the Exim Mail Transfer Agent} +.space 3ld +by +.space 1ld +Philip Hazel +.space ~~sys.leftonpage - 15*~~sys.linedepth +.justify left +University Computing Service +New Museums Site +Pembroke Street +Cambridge CB2 3QH +United Kingdom +.blank +.tabs 6 +$it{phone:} $t +44 1223 334600 +$it{fax:} $t +44 1223 334679 +$it{email:} $t ph10 $it{at} cus.cam.ac.uk +.blank +Edition for Exim ~~version, ~~versionmonth ~~versionyear +.space 2ld +.if ~~sgcal +.fontgroup 1 +.fi +$c$rm{Copyright (c) University of Cambridge ~~versionyear} + + +.if ~~sgcal +.fontgroup 0 +.font 0 +.fi + +.pop +.newpage + +. Blank verso for title page +.space 1ld +.newpage + + +. Set up for actual text pages +.page 1 +. The first one to prevent a warning from sgfr +. set runningfoot "~~chapter" +.set runningfoot "" + +.if ~~sys.fancy +.footdepth 2ld +.foot +.if "~~runningfoot" == "" +.set rhs "" +.else +.set rhs "~~runningfoot (~~chapter)" +.fi +.set lhs "Exim ~~version" +.linelength ~~newlinelength +$it{~~lhs}$c[~~sys.pagenumber]$e$it{~~rhs} +.endfoot +.fi + + + + +. +. +. +. +. ============================================================================ +.chapter Introduction +.set runningfoot "introduction" + +.if ~~sys.fancy +$c$bi{If I have seen further it is by standing on the shoulders of giants.}##(Isaac Newton) +.elif !~~html +$c"If I have seen further it is by standing on the shoulders of giants." +.newline +$e (Isaac Newton) +.else +\*If I have seen further it is by standing on the shoulders of giants.*\ +(Isaac Newton). +.fi +.blank 4 + +Exim is a mail transfer agent (MTA) for hosts that are running Unix or +Unix-like operating systems. It was designed on the assumption that it would be +run on hosts that are permanently connected to the Internet. However, it can be +used on intermittently connected hosts with suitable configuration adjustments. + +Configuration files currently exist for the following operating systems: AIX, +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. + +There are also configuration files for compiling Exim in the Cygwin environment +that can be installed on systems running Windows. However, this document does +not contain any information about running Exim in the Cygwin environment. + +The terms and conditions for the use and distribution of Exim are contained in +the file \(NOTICE)\. Exim is distributed under the terms of the GNU General +Public Licence, a copy of which may be found in the file \(LICENCE)\. + +The use, supply or promotion of Exim for the purpose of sending bulk, +unsolicited electronic mail is incompatible with the basic aims of the program, +which revolve around the free provision of a service that enhances the quality +of personal communications. The author of Exim regards indiscriminate +mass-mailing as an antisocial, irresponsible abuse of the Internet. + +Exim owes a great deal to Smail 3 and its author, Ron Karr. Without the +experience of running and working on the Smail 3 code, I could never have +contemplated starting to write a new MTA. Many of the ideas and user interfaces +were originally taken from Smail 3, though the actual code of Exim is entirely +new, and has developed far beyond the initial concept. + +Many people, both in Cambridge and around the world, have contributed to the +development and the testing of Exim, and to porting it to various operating +systems. I am grateful to them all. The distribution now contains a file called +\(ACKNOWLEDGMENTS)\, in which I have started recording the names of +contributors. + +.section Exim documentation +.index documentation +.em +This edition of the Exim specification applies to version ~~version of Exim. +Substantive changes from the ~~previousversion edition are marked by bars in +the right-hand margin in the PostScript, PDF, and plain text versions of the +document, and by green text in the HTML version, as shown by this paragraph. +Changes are not marked in the Texinfo version, because Texinfo doesn't support +change bars. Minor corrections and rewordings are not marked. +.nem + +This document is very much a reference manual; it is not a tutorial. The reader +is expected to have some familiarity with the SMTP mail transfer protocol and +with general Unix system administration. Although there are some discussions +and examples in places, the information is mostly organized in a way that makes +it easy to look up, rather than in a natural order for sequential reading. +Furthermore, the manual aims to cover every aspect of Exim in detail, including +a number of rarely-used, special-purpose features that are unlikely to be of +very wide interest. + +.index books about Exim +An `easier' discussion of Exim which provides more in-depth explanatory, +introductory, and tutorial material can be found in a book entitled +.if ~~html +[(A HREF="http://www.uit.co.uk/exim-book/")] +$it{The Exim SMTP Mail Server}, +[(/A)] +published by UIT Cambridge. +.else +$it{The Exim SMTP Mail Server}, published by UIT Cambridge +(\?http://www.uit.co.uk/exim-book/?\). +.fi + +This book also contains a chapter that gives a general introduction to SMTP and +Internet mail. Inevitably, however, the book is unlikely to be fully up-to-date +with the latest release of Exim. (Note that the earlier book about Exim, +published by O'Reilly, covers Exim 3, and many things have changed in Exim 4.) + +.index \(doc/NewStuff)\ +.index \(doc/ChangeLog)\ +.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)\. + +.index \(doc/spec.txt)\ +This specification itself is available as an ASCII file in \(doc/spec.txt)\ so +that it can easily be searched with a text editor. Other files in the \(doc)\ +directory are: +.display rm +.tabs 18 +\(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} +\(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} +\(Exim3.upgrade)\ $t $rm{upgrade notes from release 2 to release 3} +\(Exim4.upgrade)\ $t $rm{upgrade notes from release 3 to release 4} +.endd +The main specification and the specification of the filtering language are also +available in other formats (HTML, PostScript, PDF, and Texinfo). Section +~~SECTavail below tells you how to get hold of these. + + +.section FTP and web sites, and mailing list +.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 +.index FAQ +.if ~~html +[(A HREF="FAQ.html")] +.fi +FAQ +.if ~~html +[(/A)] +.fi +online there, as well as other relevant material. + +.index mailing lists||for Exim users +Energis Squared also provide resources for the following mailing lists: +.display rm +.tabs 28 +$it{exim-users@@exim.org} $t general discussion list +$it{exim-announce@@exim.org} $t moderated, low volume announcements list +.endd +You can subscribe to these lists, change your existing subscriptions, and view +or search the archives via the +.if ~~html +[(A HREF="http://www.exim.org/maillist.html")] +.fi +mailing lists +.if ~~html +[(/A)] +.fi +link on the Exim home page. The $it{exim-users} mailing list is also forwarded +to \?http://www.egroups.com/list/exim-users?\, an archiving system with +searching capabilities. + +.section Exim training +.index training courses +From time to time (approximately annually at the time of writing), +lecture-based training courses are run by the author of Exim in Cambridge, UK. +Details can be found on the web site +.if ~~html +[(A HREF="http://www-tus.csx.cam.ac.uk/courses/exim/")] +.fi +\?http://www-tus@.csx@.cam@.ac.uk/courses/exim/?\. +.if ~~html +[(/A)] +.fi + +.section Bug reports +.index bug reports +.index reporting bugs +Reports of obvious bugs should be emailed to \*bugs@@exim.org*\. However, if +you are unsure whether some behaviour is a bug or not, the best thing to do is +to post a message to the $it{exim-users} mailing list and have it discussed. + + +.section Where to find the Exim distribution +.rset SECTavail "~~chapter.~~section" +.index FTP site +.index distribution||ftp site +The master ftp site for the Exim distribution is +.display rm +.if ! ~~sys.fancy +.indent 0 +.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 +.display rm +.if ! ~~sys.fancy +.indent 0 +.fi +\?ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/Mirrors?\ +.endd +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)\ +.endd +where $it{n.nn} is the highest such version number in the directory. The two +files contain identical data; the only difference is the type of compression. +The \(.bz2)\ file is usually a lot smaller than the \(.gz)\ file. +.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: +.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. + +.index documentation||available formats +The main distribution contains ASCII versions of this specification and other +documentation; other formats of the documents are available in separate files +inside the \(exim4)\ directory of the FTP site: +.display rm +\(exim-html-$it{n.nn}.tar.gz)\ +\(exim-pdf-$it{n.nn}.tar.gz)\ +\(exim-postscript-$it{n.nn}.tar.gz)\ +\(exim-texinfo-$it{n.nn}.tar.gz)\ +.endd +These tar files contain only the \(doc)\ directory, not the complete +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 +.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?\ +.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 +at \(index.html)\. The HTML version of the FAQ (which is also included in the +HTML documentation tarbundle) includes a keyword-in-context index, which is +often the most convenient way of finding your way around. + +.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. + + +.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. + + +.section Limitations +.index limitations of Exim +.numberpars $. +Exim is designed for use as an Internet MTA, and therefore handles addresses +in RFC 2822 domain format only. +.index bang paths||not handled by Exim +It cannot handle UUCP `bang paths', though simple two-component bang paths can +be converted by a straightforward rewriting configuration. This restriction +does not prevent Exim from being interfaced to UUCP as a transport mechanism, +provided that domain addresses are used. +.nextp +.index domainless addresses +.index address||without domain +Exim insists that every address it handles has a domain attached. For incoming +local messages, domainless addresses are automatically qualified with a +configured domain value. Configuration options specify from which remote +systems unqualified addresses are acceptable. These are then qualified on +arrival. +.nextp +.index transport||external +.index external transports +The only external transport currently implemented is an SMTP transport over a +TCP/IP network (using sockets, including support for IPv6). However, a pipe +transport is available, and there are facilities for writing messages to files +and pipes, optionally in \*batched SMTP*\ format; these facilities can be used +to send messages to some other transport mechanism such as UUCP, provided it +can handle domain-style addresses. Batched SMTP input is also catered for. +.nextp +Exim is not designed for storing mail for dial-in hosts. When the volumes of +such mail are large, it is better to get the messages `delivered' into files +(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. +.endp + + + +.section Run time configuration +Exim's run time configuration is held in a single text file that is divided +into a number of sections. The entries in this file consist of keywords and +values, in the style of Smail 3 configuration files. A default configuration +file which is suitable for simple online installations is provided in the +distribution, and is described in chapter ~~CHAPdefconfil below. + + +.section Calling interface +.index Sendmail compatibility||command line interface +Like many MTAs, Exim has adopted the Sendmail command line interface so that it +can be a straight replacement for \(/usr/lib/sendmail)\ or +\(/usr/sbin/sendmail)\ when sending mail, but you do not need to know anything +about Sendmail in order to run Exim. For actions other than sending messages, +Sendmail-compatible options also exist, but those that produce output (for +example, \-bp-\, which lists the messages on the queue) do so in Exim's own +format. There are also some additional options that are compatible with Smail +3, and some further options that are new to Exim. Chapter ~~CHAPcommandline +documents all Exim's command line options. This information is automatically +made into the man page that forms part of the Exim distribution. + +Control of messages on the queue can be done via certain privileged command +line options. There is also an optional monitor program called \*eximon*\, which +displays current information in an X window, and which contains a menu +interface to Exim's command line administration options. + + +.section Terminology +.index terminology definitions +.index body of message||definition of +The \*body*\ of a message is the actual data that the sender wants to transmit. +It is the last part of a message, and is separated from the \*header*\ (see +below) by a blank line. + +.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. + +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 +also qualify an action which is taken unless a configuration setting specifies +otherwise. + +The term \*defer*\ is used when the delivery of a message to a specific +destination cannot immediately take place for some reason (a remote host may be +down, or a user's local mailbox may be full). Such deliveries are \*deferred*\ +until a later time. + +The word \*domain*\ is sometimes used to mean all but the first component of a +host's name. It is $it{not} used in that sense here, where it normally +refers to the part of an email address following the @@ sign. + +.index envelope, definition of +.index sender||definition of +A message in transit has an associated \*envelope*\, as well as a header and a +body. The envelope contains a sender address (to which bounce messages should +be delivered), and any number of recipient addresses. References to the +sender or the recipients of a message usually mean the addresses in the +envelope. An MTA uses these addresses for delivery, and for returning bounce +messages, not the addresses that appear in the header lines. + +.index message||header, definition of +.index header section||definition of +The \*header*\ of a message is the first part of a message's text, consisting +of a number of lines, each of which has a name such as ::From::, ::To::, +::Subject::, etc. Long header lines can be split over several text lines by +indenting the continuations. The header is separated from the body by a blank +line. + +.index local part||definition of +.index domain||definition of +The term \*local part*\, which is taken from RFC 2822, is used to refer to that +part of an email address that precedes the @@ sign. The part that follows the +@@ sign is called the \*domain*\ or \*mail domain*\. + +.index local delivery||definition of +.index remote delivery, definition of +The terms \*local delivery*\ and \*remote delivery*\ are used to distinguish +delivery to a file or a pipe on the local host from delivery by SMTP over +TCP/IP to a remote host. + +.index return path||definition of +\*Return path*\ is another name that is used for the sender address in a +message's envelope. + +.index queue||definition of +The term \*queue*\ is used to refer to the set of messages awaiting delivery, +because this term is in widespread use in the context of MTAs. However, in +Exim's case the reality is more like a pool than a queue, because there is +normally no ordering of waiting messages. + +.index queue runner||definition of +The term \*queue runner*\ is used to describe a process that scans the queue +and attempts to deliver those messages whose retry times have come. This term +is used by other MTAs, and also relates to the command \runq\, but in Exim +the waiting messages are normally processed in an unpredictable order. + +.index spool directory||definition of +The term \*spool directory*\ is used for a directory in which Exim keeps the +messages on its queue -- that is, those that it is in the process of +delivering. This should not be confused with the directory in which local +mailboxes are stored, which is called a `spool directory' by some people. In +the Exim documentation, `spool' is always used in the first sense. + + + +. +. +. +. +. ============================================================================ +.chapter Incorporated code +.set runningfoot "incorporated code" +.index incorporated code +.index regular expressions||library +.index PCRE +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?\. + +.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: +.rule +.push +.if ~~sgcal +.fontgroup 9 +.font 0 +.fi +Copyright (c) 1998 Nigel Metheringham, Planet Online Ltd + +This program is free software; you can redistribute it and/or modify it under +the terms of the GNU General Public License as published by the Free Software +Foundation; either version 2 of the License, or (at your option) any later +version. + +This code implements Dan Bernstein's Constant DataBase (cdb) spec. Information, +the spec and sample code for cdb can be obtained from +\?http://www.pobox.com/@~djb/cdb.html?\. This implementation borrows some code +from Dan Bernstein's implementation (which has no license restrictions applied +to it). +.newline +.pop +.rule +The implementation is completely contained within the code of Exim. +It does not link against an external cdb library. +.space 1ld +.nextp +.index SPA authentication +.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 +Tom Kistner. This includes code taken from the Samba project, which is released +under the Gnu GPL. + +.space 1ld +.nextp +.index Cyrus +.index \*pwcheck*\ daemon +.index \*pwauthd*\ daemon +Support for calling the Cyrus \*pwcheck*\ and \*saslauthd*\ daemons is provided +by code taken from the Cyrus-SASL library and adapted by Alexander S. +Sabourenkov. The permission notice appears below, in accordance with the +conditions expressed therein. + +.rule +.push +.if ~~sgcal +.fontgroup 9 +.font 0 +.fi +Copyright (c) 2001 Carnegie Mellon University. All rights reserved. + +Redistribution and use in source and binary forms, with or without +modification, are permitted provided that the following conditions +are met: + +.if ~~sgcal +.cancelflag $npbracket +.flag $npbracket "" "." +.fi +.numberpars +Redistributions of source code must retain the above copyright +notice, this list of conditions and the following disclaimer. +.nextp +Redistributions in binary form must reproduce the above copyright +notice, this list of conditions and the following disclaimer in +the documentation and/or other materials provided with the +distribution. +.nextp +The name `Carnegie Mellon University' must not be used to +endorse or promote products derived from this software without +prior written permission. For permission or any other legal +details, please contact +.display rm +Office of Technology Transfer +Carnegie Mellon University +5000 Forbes Avenue +Pittsburgh, PA 15213-3890 +(412) 268-4387, fax: (412) 268-7395 +tech-transfer@@andrew.cmu.edu +.endd +.nextp +Redistributions of any form whatsoever must retain the following +acknowledgment: +.newline +.push +.indent ~~sys.indent + 3em +.justify left +$it{This product includes software developed by Computing Services +at Carnegie Mellon University (\?http://www.cmu.edu/computing/?\).} +.newline +.pop +.endp +.if ~~sgcal +.cancelflag $npbracket +.flag $npbracket "(" ")" +.fi + +CARNEGIE MELLON UNIVERSITY DISCLAIMS ALL WARRANTIES WITH REGARD TO +THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY +AND FITNESS, IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY BE LIABLE +FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN +AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING +OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +.newline +.pop +.rule + +.space 1ld +.nextp +.index monitor +.index X-windows +.index Athena +The Exim Monitor program, which is an X-Window application, includes +modified versions of the Athena StripChart and TextPop widgets. +This code is copyright by DEC and MIT, and their permission notice appears +below, in accordance with the conditions expressed therein. + +.rule +.push +.if ~~sgcal +.fontgroup 9 +.font 0 +.fi +Copyright 1987, 1988 by Digital Equipment Corporation, Maynard, Massachusetts, +and the Massachusetts Institute of Technology, Cambridge, Massachusetts. +.blank +$c All Rights Reserved +.blank +Permission to use, copy, modify, and distribute this software and its +documentation for any purpose and without fee is hereby granted, +provided that the above copyright notice appear in all copies and that +both that copyright notice and this permission notice appear in +supporting documentation, and that the names of Digital or MIT not be +used in advertising or publicity pertaining to distribution of the +software without specific, written prior permission. + +DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING +ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL +DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR +ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, +WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, +ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS +SOFTWARE. +.newline +.pop +.rule +.endp + + + +. +. +. +. +. ============================================================================ +.chapter How Exim receives and delivers mail +.set runningfoot "receiving & delivering mail" + +.section Overall philosophy +.index design philosophy +Exim is designed to work efficiently on systems that are permanently connected +to the Internet and are handling a general mix of mail. In such circumstances, +most messages can be delivered immediately. Consequently, Exim does not +maintain independent queues of messages for specific domains or hosts, though +it does try to send several messages in a single SMTP connection after a host +has been down, and it also maintains per-host retry information. + + +.section Policy control +.index policy control||overview +Policy controls are now an important feature of MTAs that are connected to the +Internet. Perhaps their most important job is to stop MTAs being abused as +`open relays' by misguided individuals who send out vast amounts of unsolicited +junk, and want to disguise its source. Exim provides flexible facilities for +specifying policy controls on incoming mail: +.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 +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 +case, the only available actions are to accept or deny the entire message. +.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 +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. +.endp + +.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 +.if ~~html +[(A HREF="filter_toc.html")] +.fi +\*Exim's interfaces to mail filtering*\ +.if ~~html +[(/A)] +.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 +RFC 3028. +.nextp +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. + + +.section Message identification +.rset SECTmessiden "~~chapter.~~section" +.index message||ids, details of format +.index format||of message id +.index id of message +.index base62 +.index base36 +.index Darwin +.index Cygwin +Every message handled by Exim is given a \*message id*\ which is sixteen +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 +id is used to construct file names, and the names of files in those systems are +not case-sensitive. + +.index pid (process id)||re-use of +The detail of the contents of the message id have changed as Exim has evolved. +Earlier versions relied on the operating system not re-using a process id (pid) +within one second. On modern operating systems, this assumption can no longer +be made, so the algorithm had to be changed. To retain backward compatibility, +the format of the message id was retained, which is why the following rules are +somewhat eccentric: +.numberpars $. +The first six characters of the message id are the time at which the message +started to be received, to a granularity of one second. That is, this field +contains the number of seconds since the start of the epoch (the normal Unix +way of representing the date and time of day). +.nextp +After the first hyphen, the next six characters are the id of the process that +received the message. +.nextp +There are two different possibilities for the final two characters: +.numberpars alpha +.index \localhost@_number\ +If \localhost@_number\ is not set, this value is the fractional part of the +time of reception, normally in units of 1/2000 of a second, but for systems +that must use base 36 instead of base 62 (because of case-insensitive file +systems), the units are 1/1000 of a second. +.nextp +If \localhost@_number\ is set, it is multiplied by 200 (100) and added to +the fractional part of the time, which in this case is in units of 1/200 +(1/100) of a second. +.endp +.endp +After a message has been received, Exim waits for the clock to tick at the +appropriate resolution before proceeding, so that if another message is +received by the same process, or by another process with the same (re-used) +pid, it is guaranteed that the time will be different. In most cases, the clock +will already have ticked while the message was being received. + +.section Receiving mail +.index receiving mail +.index message||reception +The only way Exim can receive mail from a remote host is using SMTP over +TCP/IP, in which case the sender and recipient addresses are tranferred using +SMTP commands. However, from a locally running process (such as a user's MUA), +there are several possibilities: +.numberpars $. +If the process runs Exim with the \-bm-\ option, the message is read +non-interactively (usually via a pipe), with the recipients taken from the +command line, or from the body of the message if \-t-\ is also used. +.nextp +If the process runs Exim with the \-bS-\ option, the message is also read +non-interactively, but in this case the recipients are listed at the start of +the message in a series of SMTP \\RCPT\\ commands, terminated by a \\DATA\\ +command. This is so-called `batch SMTP' format, +but it isn't really SMTP. The SMTP commands are just another way of passing +envelope addresses in a non-interactive submission. +.nextp +If the process runs Exim with the \-bs-\ option, the message is read +interactively, using the SMTP protocol. A two-way pipe is normally used for +passing data between the local process and the Exim process. +This is `real' SMTP and is handled in the same way as SMTP over TCP/IP. For +example, the ACLs for SMTP commands are used for this form of submission. +.nextp +A local process may also make a TCP/IP call to the host's loopback address +(127.0.0.1) or any other of its IP addresses. When receiving messages, Exim +does not treat the loopback address specially. It treats all such connections +in the same way as connections from other hosts. +.endp + +.index message||sender, constructed by Exim +.index sender||constructed by Exim +In the three cases that do not involve TCP/IP, the sender address is +constructed from the login name of the user that called Exim and a default +qualification domain (which can be set by the \qualify@_domain\ configuration +option). For local or batch SMTP, a sender address that is passed using the +SMTP \\MAIL\\ command is ignored. However, the system administrator may allow +certain users (`trusted users') to specify a different sender address +unconditionally, or all users to specify certain forms of different sender +address. The \-f-\ option or the SMTP \\MAIL\\ command is used to specify these +different addresses. See section ~~SECTtrustedadmin for details of trusted +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 +requirements are not met. The \*local@_scan()*\ function (see chapter +~~CHAPlocalscan) is run for all incoming messages. + +Exim can be configured not to start a delivery process when a message is +received; this can be unconditional, or depend on the number of incoming SMTP +connections or the system load. In these situations, new messages wait on the +queue until a queue runner process picks them up. However, in standard +configurations under normal conditions, delivery is started as soon as a +message is received. + + + + +.section Handling an incoming message +.index spool directory||files that hold a message +.index file||how a message is held +When Exim accepts a message, it writes two files in its spool directory. The +first contains the envelope information, the current status of the message, +and the header lines, and the second contains the body of the message. The +names of the two spool files consist of the message id, followed by $tt{-H} for +the file containing the envelope and header, and $tt{-D} for the data file. + +.index spool directory||\(input)\ sub-directory +By default all these message files are held in a single directory called +\(input)\ inside the general Exim spool directory. Some operating systems do +not perform very well if the number of files in a directory gets very large; to +improve performance in such cases, the \split@_spool@_directory\ option can be +used. This causes Exim to split up the input files into 62 sub-directories +whose names are single letters or digits. + +The envelope information consists of the address of the message's sender and +the addresses of the recipients. This information is entirely separate from +any addresses contained in the header lines. The status of the message includes +a list of recipients who have already received the message. The format of the +first spool file is described in chapter ~~CHAPspool. + +.index rewriting||addresses +Address rewriting that is specified in the rewrite section of the configuration +(see chapter ~~CHAPrewrite) is done once and for all on incoming addresses, +both in the header lines and the envelope, at the time the message is accepted. +If during the course of delivery additional addresses are generated (for +example, via aliasing), these new addresses are rewritten as soon as they are +generated. At the time a message is actually delivered (transported) further +rewriting can take place; because this is a transport option, it can be +different for different forms of delivery. It is also possible to specify the +addition or removal of certain header lines at the time the message is +delivered (see chapters ~~CHAProutergeneric and ~~CHAPtransportgeneric). + + +.section Life of a message +.index message||life of +.index message||frozen +A message remains in the spool directory until it is completely delivered to +its recipients or to an error address, or until it is deleted by an +administrator or by the user who originally created it. In cases when delivery +cannot proceed -- for example, when a message can neither be delivered to its +recipients nor returned to its sender, the message is marked `frozen' on the +spool, and no more deliveries are attempted. + +.index frozen messages||thawing +.index message||thawing frozen +An administrator can `thaw' such messages when the problem has been corrected, +and can also freeze individual messages by hand if necessary. In addition, an +administrator can force a delivery error, causing a bounce message to be sent. + +.index \auto@_thaw\ +There is an option called \auto@_thaw\, which can be used to cause Exim to +retry frozen messages after a certain time. When this is set, no message will +remain on the queue for ever, because the delivery timeout will eventually be +reached. Delivery failure reports (bounce messages) that reach this timeout are +discarded. +.index \timeout@_frozen@_after\ +There is also an option called \timeout@_frozen@_after\, which discards frozen +messages after a certain time. + +.index message||log file for +.index log||file for each message +While Exim is working on a message, it writes information about each delivery +attempt to the main log file. This includes successful, unsuccessful, and +delayed deliveries for each recipient (see chapter ~~CHAPlog). The log lines +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 +\no@_message@_logs\; this might give an improvement in performance on very +busy systems. + +.index journal file +.index file||journal +All the information Exim itself needs to set up a delivery is kept in the first +spool file, along with the header lines. When a successful delivery occurs, the +address is immediately written at the end of a journal file, whose name is the +message id followed by $tt{-J}. At the end of a delivery run, if there are some +addresses left to be tried again later, the first spool file (the $tt{-H} file) +is updated to indicate which these are, and the journal file is then deleted. +Updating the spool file is done by writing a new file and renaming it, to +minimize the possibility of data loss. + +Should the system or the program crash after a successful delivery but before +the spool file has been updated, the journal is left lying around. The next +time Exim attempts to deliver the message, it reads the journal file and +updates the spool file before proceeding. This minimizes the chances of double +deliveries caused by crashes. + + +.section Processing an address for delivery +.rset SECTprocaddress "~~chapter.~~section" +.index drivers||definition of +.index router||definition of +.index transport||definition of +The main delivery processing elements of Exim are called $it{routers} and +$it{transports}, and collectively these are known as $it{drivers}. Code for a +number of them is provided in the source distribution, and compile-time options +specify which ones are included in the binary. Run time options specify which +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 +option values that might specify different ports or different timeouts. Each +instance has its own identifying name. In what follows we will normally use the +instance name when discussing one particular instance (that is, one specific +configuration of the driver), and the generic driver name when discussing +the driver's features in general. + +A $it{router} is a driver that operates on an address, either determining how +its delivery should happen, by routing it to a specific transport, or +converting the address into one or more new addresses (for example, via an +alias file). A router may also explicitly choose to fail an address, causing it +to be bounced. + +A $it{transport} is a driver that transmits a copy of the message from Exim's +spool to some destination. There are two kinds of transport: for a $it{local} +transport, the destination is a file or a pipe on the local host, whereas for a +$it{remote} transport the destination is some other host. A message is passed +to a specific transport as a result of successful routing. If a message has +several recipients, it may be passed to a number of different transports. + +.index preconditions||definition of +An address is processed by passing it to each configured router instance in +turn, subject to certain preconditions, until a router accepts the address or +specifies that it should be bounced. We will describe this process in more +detail shortly. As a simple example, the diagram below illustrates how each +recipient address in a message is processed in a small configuration of three +routers that are configured in various ways. + +.if ~~sys.fancy +.figure "Routing an address" rm +.indent 0 +.call aspic +centre ~~sys.linelength; +magnify 0.8; +boundingbox 30; + ibox depth 14 "address"; +B: arrow down 44; + textdepth 14; +A: box width 100 "first router" "conditions ok?"; + arrow right "yes"; +C: box width 100 "run" "first router"; + arrow down "fail"; +D: ibox depth 20 "address bounces"; + + arc clockwise from right of C "accept"; + arrow down 10; + ibox "queue for" "transport"; + + arrow down from A align bottom of D plus (0,-20) "no"(-6,20)/r; +E: box width 100 "second router" "conditions ok?"; + arrow right "yes"; +F: box width 100 "run" "second router"; + line right 100 "redirect"; + line up align middle of B; + arrow left to middle of B "new addresses"; + + line down 20 from bottom left of F plus (30,0); + arrow left align centre of E "decline"; + + line down 20 from bottom right of F plus (-30,0); + arrow right "fail"; + ibox width 64 "address" "bounces"; + + arrow down 64 from E "no"(-6,20)/r; +G: box width 100 "third router" "conditions ok?"; + arrow right "yes"; +H: box width 100 "run" "third router"; + arc clockwise from right of H "accept"; + arrow down 10; + ibox "queue for" "transport"; + + line down 20 from bottom of H; + arrow left align centre of G "decline"; + arrow down 64 from G "no"(-6,20)/r; + + ibox "no more routers" "address bounces"; +.endcall +.endfigure +.elif !~~html +.display asis + + address + | + |<------------- new addresses ----------------------------- + V | + ----------------- ----------------- | + | first router |----- yes ----->| run |--- accept | + | conditions ok?| | first router | | | + ----------------- ----------------- | | + | | V | + no | fail | queue for | + | V transport | + | address bounces | + | | + V | + ----------------- ----------------- | + | second router |----- yes ----->| run |----redirect ---- + | conditions ok?| | second router | + ----------------- ----------------- + | | | + no | | | + |<-------- decline ----------- --- fail ---> address + | bounces + V + ----------------- ----------------- + | third router |----- yes ----->| run |--- accept + | conditions ok?| | third router | | + ----------------- ----------------- | + | | V + no | | queue for + |<-------- decline --------------- transport + | + V + no more routers + address bounces +.endd +.else +[(img src="routing.gif" alt="Routing an address")][(br)] +.fi +To make this a more concrete example, we'll describe it in terms of some actual +routers, but remember, this is only an example. You can configure Exim's +routers in many different ways, and there may be any number of routers in a +configuration. + +The first router that is specified in a configuration is often one that handles +addresses in domains that are not recognized specially by the local host. These +are typically addresses for arbitrary domains on the Internet. A precondition +is set up which looks for the special domains known to the host (for example, +its own domain name), and the router is run for addresses that do $it{not} +match. Typically, this is a router that looks up domains in the DNS in order to +find the hosts to which this address routes. If it succeeds, the address is +queued for a suitable SMTP transport; if it does not succeed, the router is +configured to fail the address. + +The example pictured could be a configuration of this type. The second and +third routers can only be run for addresses for which the preconditions for +the first router are not met. If one of these preconditions checks the +domain, the second and third routers are run only for domains that are somehow +special to the local host. + +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 +address is passed to the next router. + +The final router in many configurations is one that checks to see if the +address belongs to a local mailbox. The precondition may involve a check to +see if the local part is the name of a login account, or it may look up the +local part in a file or a database. If its preconditions are not met, or if +the router declines, we have reached the end of the routers. When this happens, +the address is bounced. + + +.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 +\-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 +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 +would be set for such a router, causing it to be skipped in verify mode. + + + +.section Running an individual router +.rset SECTrunindrou "~~chapter.~~section" +.index router||running details +.index preconditions||checking +.index router||result of running +As explained in the example above, a number of preconditions are checked before +running a router. If any are not met, the router is skipped, and the address is +passed to the next router. When all the preconditions on a router $it{are} met, +the router is run. What happens next depends on the outcome, which is one of +the following: +.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, +.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, +for keeping archive copies of messages). When \unseen\ is set, the address is +passed to the next router. Normally, however, an \*accept*\ return marks the +end of routing. + +.index case of local parts +.index address||duplicate, discarding +If child addresses are generated, Exim checks to see whether they are +duplicates of any existing recipient addresses. During this check, local parts +are treated as case-sensitive. Duplicate addresses are discarded. Each of the +remaining child addresses is then processed independently, starting with the +first router by default. It is possible to change this by setting the +\redirect@_router\ option to specify which router to start at for child +addresses. Unlike \pass@_router\ (see below) the router specified by +\redirect@_router\ may be anywhere in the router configuration. +.nextp +\*pass*\: The router recognizes the address, but cannot handle it itself. It +requests that the address be passed to another router. By default the address +is passed to the next router, but this can be changed by setting the +\pass@_router\ option. However, (unlike \redirect@_router\) the named router +must be below the current router (to avoid loops). +.nextp +\*decline*\: The router declines to accept the address because it does not +recognize it at all. By default, the address is passed to the next router, but +this can be prevented by setting the \no@_more\ option. When \no@_more\ is set, +all the remaining routers are skipped. +.nextp +\*fail*\: The router determines that the address should fail, and queues it for +the generation of a bounce message. There is no further processing of the +original address unless \unseen\ is set on the router. +.nextp +\*defer*\: The router cannot handle the address at the present time. (A database +may be offline, or a DNS lookup may have timed out.) No further processing of +the address happens in this delivery attempt. It is tried again next time the +message is considered for delivery. +.nextp +\*error*\: There is some error in the router (for example, a syntax error in +its configuration). The action is as for defer. +.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 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' +facility for this purpose. + + + +.section Router preconditions +.rset SECTrouprecon "~~chapter.~~section" +.index router||preconditions, order of processing +.index preconditions||order of processing +The preconditions that are tested for each router are listed below, in the +order in which they are tested. The individual configuration options are +described in more detail in chapter ~~CHAProutergeneric. +.numberpars $. +The \local@_part@_prefix\ and \local@_part@_suffix\ options can specify that +the local parts handled by the router may or must have certain prefixes and/or +suffixes. If a mandatory affix (prefix or suffix) is not present, the router is +skipped. These conditions are tested first. When an affix is present, it is +removed from the local part before further processing, including the evaluation +of any other conditions. +.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 +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 +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 +possible to use \-bt-\ to test subsequent delivery routing without having to +simulate the effect of the scanner. +.nextp +Routers can be designated for use only when verifying an address, as +opposed to routing it for delivery. The \verify@_only\ option controls this. +.nextp +Certain routers can be explicitly skipped when running the routers to check an +address given in the SMTP \\EXPN\\ command (see the \expn\ option). +.nextp +If the \domains\ option is set, the domain of the address must be in the set of +domains that it defines. +.nextp +If the \local@_parts\ option is set, the local part of the address must be in +the set of local parts that it defines. If \local@_part@_prefix\ or +\local@_part@_suffix\ is in use, the prefix or suffix is removed from the local +part before this check. If you want to do precondition tests on local parts +that include affixes, you can do so by using a \condition\ option (see below) +that uses the variables \$local@_part$\, \$local@_part@_prefix$\, and +\$local@_part@_suffix$\ as necessary. +.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 +\$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 +could lead to confusion. +.nextp +If the \senders\ option is set, the envelope sender address must be in the set +of addresses that it defines. +.nextp +If the \require@_files\ option is set, the existence or non-existence of +specified files is tested. +.nextp +.index customizing||precondition +If the \condition\ option is set, it is evaluated and tested. This option uses +an expanded string to allow you to set up your own custom preconditions. +Expanded strings are described in chapter ~~CHAPexpand. +.endp + +Note that \require@_files\ comes near the end of the list, so you cannot use it +to check for the existence of a file in which to lookup up a domain, local +part, or sender. However, as these options are all expanded, you can use the +\exists\ expansion condition to make such tests within each condition. The +\require@_files\ option is intended for checking files that the router may be +going to use internally, or which are needed by a specific transport (for +example, \(.procmailrc)\). + + +.section Delivery in detail +.index delivery||in detail +When a message is to be delivered, the sequence of events is as follows: +.numberpars $. +If a system-wide filter file is specified, the message is passed to it. The +filter may add recipients to the message, replace the recipients, discard the +message, cause a new message to be generated, or cause the message delivery to +fail. The format of the system filter file is the same as for Exim user filter +files, described in the separate document entitled +.if ~~html +[(A HREF="filter.html")] +.fi +\*Exim's interfaces to mail filtering*\. +.if ~~html +[(/A)] +.fi +.index Sieve filter||not available for system filter +(\**Note**\: Sieve cannot be used for system filter files.) +Some additional features are available in system filters -- see chapter +~~CHAPsystemfilter for details. Note that a message is passed to the system +filter only once per delivery attempt, however many recipients it has. However, +if there are several delivery attempts because one or more addresses could not +be immediately delivered, the system filter is run each time. The filter +condition \first@_delivery\ can be used to detect the first run of the system +filter. +.nextp +Each recipient address is offered to each configured router in turn, subject to +its preconditions, until one is able to handle it. If no router can handle +the address, that is, if they all decline, the address is failed. Because +routers can be targeted at particular domains, several locally handled domains +can be processed entirely independently of each other. +.nextp +.index routing||loops in +.index loop||while routing +A router that accepts an address may set up a local or a remote transport for +it. However, the transport is not run at this time. Instead, the address is +placed on a list for the particular transport, to be run later. Alternatively, +the router may generate one or more new addresses (typically from alias, +forward, or filter files). New addresses are fed back into this process from +the top, but in order to avoid loops, a router ignores any address which has an +identically-named ancestor that was processed by itself. +.nextp +When all the routing has been done, addresses that have been successfully +handled are passed to their assigned transports. When local transports are +doing real local deliveries, they handle only one address at a time, but if a +local transport is being used as a pseudo-remote transport (for example, to +collect batched SMTP messages for transmission by some other means) multiple +addresses can be handled. Remote transports can always handle more than one +address at a time, but can be configured not to do so, or to restrict multiple +addresses to the same domain. +.nextp +Each local delivery to a file or a pipe runs in a separate process under a +non-privileged uid, and these deliveries are run one at a time. Remote +deliveries also run in separate processes, normally under a uid that is private +to Exim (`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 +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 +database to see if there has been a previous temporary delivery failure for the +address before running the local transport. If there was a previous failure, +Exim does not attempt a new delivery until the retry time for the address is +reached. However, this happens only for delivery attempts that are part of a +queue run. Local deliveries are always attempted when delivery immediately +follows message reception, even if retry times are set for them. This makes for +better behaviour if one particular message is causing problems (for example, +causing quota overflow, or provoking an error in a filter file). +.nextp +.index delivery||retry in remote transports +Remote transports do their own retry handling, since an address may be +deliverable to one of a number of hosts, each of which may have a different +retry time. If there have been previous temporary failures and no host has +reached its retry time, no delivery is attempted, whether in a queue run or +not. See chapter ~~CHAPretry for details of retry strategies. +.nextp +If there were any permanent errors, a bounce message is returned to an +appropriate address (the sender in the common case), with details of the error +for each failing address. Exim can be configured to send copies of bounce +messages to other addresses. +.nextp +.index delivery||deferral +If one or more addresses suffered a temporary failure, the message is left on +the queue, to be tried again later. Delivery of these addresses is said to be +\*deferred*\. +.nextp +When all the recipient addresses have either been delivered or bounced, +handling of the message is complete. The spool files and message log are +deleted, though the message log can optionally be preserved if required. +.endp + + +.section Retry mechanism +.index delivery||retry mechanism +.index retry||description of mechanism +.index queue runner +Exim's mechanism for retrying messages that fail to get delivered at the first +attempt is the queue runner process. You must either run an Exim daemon that +uses the \-q-\ option with a time interval to start queue runners at regular +intervals, or use some other means (such as \*cron*\) to start them. If you do +not arrange for queue runners to be run, messages that fail temporarily at the +first attempt will remain on your queue for ever. A queue runner process works +it way through the queue, one message at a time, trying each delivery that has +passed its retry time. +You can run several queue runners at once. + +Exim uses a set of configured rules to determine when next to retry the failing +address (see chapter ~~CHAPretry). These rules also specify when Exim should +give up trying to deliver to the address, at which point it generates a bounce +message. If no retry rules are set for a particular host, address, and error +combination, no retries are attempted, and temporary errors are treated as +permanent. + + +.section Temporary delivery failure +.index delivery||temporary failure +There are many reasons why a message may not be immediately deliverable to a +particular address. Failure to connect to a remote machine (because it, or the +connection to it, is down) is one of the most common. Temporary failures may be +detected during routing as well as during the transport stage of delivery. +Local deliveries may be delayed if NFS files are unavailable, or if a mailbox +is on a file system where the user is over quota. Exim can be configured to +impose its own quotas on local mailboxes; where system quotas are set they will +also apply. + +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, +.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 +for the same host. If any are found, they are sent over the same SMTP +connection, subject to a configuration limit as to the maximum number in any +one connection. + + + +.section Permanent delivery failure +.index delivery||permanent failure +.index bounce message||when generated +When a message cannot be delivered to some or all of its intended recipients, a +bounce message is generated. Temporary delivery failures turn into permanent +errors when their timeout expires. All the addresses that fail in a given +delivery attempt are listed in a single message. If the original message has +many recipients, it is possible for some addresses to fail in one delivery +attempt and others to fail subsequently, giving rise to more than one bounce +message. The wording of bounce messages can be customized by the administrator. +See chapter ~~CHAPemsgcust for details. + +.index ::X-Failed-Recipients:: header line +Bounce messages contain an ::X-Failed-Recipients:: header line that lists the +failed addresses, for the benefit of programs that try to analyse such messages +automatically. + +.index bounce message||recipient of +A bounce message is normally sent to the sender of the original message, as +obtained from the message's envelope. For incoming SMTP messages, this is the +address given in the \\MAIL\\ command. However, when an address is +expanded via a forward or alias file, an alternative address can be specified +for delivery failures of the generated addresses. For a mailing list expansion +(see section ~~SECTmailinglists) it is common to direct bounce messages to the +manager of the list. + + + +.section Failures to deliver bounce messages +.index bounce message||failure to deliver +If a bounce message (either locally generated or received from a remote host) +itself suffers a permanent delivery failure, the message is left on the queue, +but it is frozen, awaiting the attention of an administrator. There are options +which can be used to make Exim discard such failed messages, or to keep them +for only a short time (see \timeout@_frozen@_after\ and +\ignore@_bounce@_errors@_after\). + + + +. +. +. +. +. ============================================================================ +.chapter Building and installing Exim +.set runningfoot "building/installing" + +.index building Exim +.section Unpacking +Exim is distributed as a gzipped or bzipped tar file which, when upacked, +creates a directory with the name of the current release (for example, +\(exim-~~version)\) into which the following files are placed: +.display rm +.if !~~sys.fancy && ~~sgcal +.tabs 16 +.else +.tabs 22 +.fi +\(ACKNOWLEDGMENTS)\ $t contains some acknowledgments +.newline +\(CHANGES)\ $t contains a reference to where changes are documented +\(LICENCE)\ $t the GNU General Public Licence +\(Makefile)\ $t top-level make file +\(NOTICE)\ $t conditions for the use of Exim +\(README)\ $t list of files, directories and simple build instructions +.endd +Other files whose names begin with \(README)\ may also be present. The +following subdirectories are created: +.display rm +.if !~~sys.fancy && ~~sgcal +.tabs 16 +.else +.tabs 22 +.fi +\(Local)\ $t an empty directory for local configuration files +\(OS)\ $t OS-specific files +\(doc)\ $t documentation files +\(exim@_monitor)\$t source files for the Exim monitor +\(scripts)\ $t scripts used in the build process +\(src)\ $t remaining source files +\(util)\ $t independent utilities +.endd +The main utility programs are contained in the \(src)\ directory, and are built +with the Exim binary. The \(util)\ directory contains a few optional scripts +that may be useful to some sites. + +.section Multiple machine architectures and operating systems +.index building Exim||multiple OS/architectures +The building process for Exim is arranged to make it easy to build binaries for +a number of different architectures and operating systems from the same set of +source files. Compilation does not take place in the \(src)\ directory. Instead, +a \*build directory*\ is created for each architecture and operating system. +.index symbolic link||to build directory +Symbolic links to the sources are installed in this directory, which is where +the actual building takes place. + +In most cases, Exim can discover the machine architecture and operating system +for itself, but the defaults can be overridden if necessary. + +.section DBM libraries +.rset SECTdb "~~chapter.~~section" +.index DBM||libraries, discussion of +.index hints database||DBM files used for +Even if you do not use any DBM files in your configuration, Exim still needs a +DBM library in order to operate, because it uses indexed files for its hints +databases. Unfortunately, there are a number of DBM libraries in existence, and +different operating systems often have different ones installed. + +.index Solaris||DBM library for +.index IRIX, DBM library for +.index BSD, DBM library for +.index Linux, DBM library for +If you are using Solaris, IRIX, one of the modern BSD systems, or a modern +Linux distribution, the DBM configuration should happen automatically, and you +may be able to ignore this section. Otherwise, you may have to learn more than +you would like about DBM libraries from what follows. + +.index \*ndbm*\ DBM library +Licensed versions of Unix normally contain a library of DBM functions operating +via the \*ndbm*\ interface, and this is what Exim expects by default. Free +versions of Unix seem to vary in what they contain as standard. In particular, +some early versions of Linux have no default DBM library, and different +distributors have chosen to bundle different libraries with their packaged +versions. However, the more recent releases seem to have standardised on the +Berkeley DB library. + +Different DBM libraries have different conventions for naming the files they +use. When a program opens a file called \(dbmfile)\, there are four +possibilities: +.numberpars +A traditional \*ndbm*\ implementation, such as that supplied as part of +Solaris, operates on two files called \(dbmfile.dir)\ and \(dbmfile.pag)\. +.nextp +.index \*gdbm*\ DBM library +The GNU library, \*gdbm*\, operates on a single file. If used via its \*ndbm*\ +compatibility interface it makes two different hard links to it with names +\(dbmfile.dir)\ and \(dbmfile.pag)\, but if used via its native interface, the +file name is used unmodified. +.nextp +.index Berkeley DB library +The Berkeley DB package, if called via its \*ndbm*\ compatibility interface, +operates on a single file called \(dbmfile.db)\, but otherwise looks to the +programmer exactly the same as the traditional \*ndbm*\ implementation. +.nextp +If the Berkeley package is used in its native mode, it operates on a single +file called \(dbmfile)\; the programmer's interface is somewhat different to +the traditional \*ndbm*\ interface. +.nextp +To complicate things further, there are several very different versions of the +Berkeley DB package. Version 1.85 was stable for a very long time, releases +2.$it{x} and 3.$it{x} were current for a while, but the latest versions are now +numbered 4.$it{x}. Maintenance of some of the earlier releases has ceased. All +versions of Berkeley DB can be obtained from +.display rm +\?http://www.sleepycat.com/?\ +.endd +.nextp +.index \*tdb*\ DBM library +Yet another DBM library, called \*tdb*\, has become available from +.display rm +\?http://download.sourceforge.net/tdb?\ +.endd +It has its own interface, and also operates on a single file. +.endp +.index \\USE@_DB\\ +.index DBM||libraries, configuration for building +Exim and its utilities can be compiled to use any of these interfaces. In order +to use any version of the Berkeley DB package in native mode, you must set +\\USE@_DB\\ in an appropriate configuration file (typically +\(Local/Makefile)\). For example: +.display asis +USE_DB=yes +.endd +Similarly, for gdbm you set \\USE@_GDBM\\, and for tdb you set \\USE@_TDB\\. An +error is diagnosed if you set more than one of these. + +At the lowest level, the build-time configuration sets none of these options, +thereby assuming an interface of type (1). However, some operating system +configuration files (for example, those for the BSD operating systems and +Linux) assume type (4) by setting \\USE@_DB\\ as their default, and the +configuration files for Cygwin set \\USE@_GDBM\\. Anything you set in +\(Local/Makefile)\, however, overrides these system defaults. + +As well as setting \\USE@_DB\\, \\USE@_GDBM\\, or \\USE@_TDB\\, it may also be +necessary to set \\DBMLIB\\, to cause inclusion of the appropriate library, as +in one of these lines: +.display asis +DBMLIB = -ldb +DBMLIB = -ltdb +.endd +Settings like that will work if the DBM library is installed in the standard +place. Sometimes it is not, and the library's header file may also not be in +the default path. You may need to set \\INCLUDE\\ to specify where the header +file is, and to specify the path to the library more fully in \\DBMLIB\\, as in +this example: +.display asis +INCLUDE=-I/usr/local/include/db-4.1 +DBMLIB=/usr/local/lib/db-4.1/libdb.a +.endd + +There is further detailed discussion about the various DBM libraries in the +file \(doc/dbm.discuss.txt)\ in the Exim distribution. + + +.section Pre-building configuration +.index building Exim||pre-building configuration +.index configuration for building Exim +.index \(Local/Makefile)\ +.index \(src/EDITME)\ +Before building Exim, a local configuration file that specifies options +independent of any operating system has to be created with the name +\(Local/Makefile)\. A template for this file is supplied as the file +\(src/EDITME)\, and it contains full descriptions of all the option settings +therein. These descriptions are therefore not repeated here. If you are +building Exim for the first time, the simplest thing to do is to copy +\(src/EDITME)\ to \(Local/Makefile)\, then read it and edit it appropriately. + +There are three settings that you must supply, because Exim will not build +without them. They are the location of the run time configuration file +(\\CONFIGURE@_FILE\\), the directory in which Exim binaries will be installed +(\\BIN@_DIRECTORY\\), and the identity of the Exim user (\\EXIM@_USER\\ and +maybe \\EXIM@_GROUP\\ as well). The value of \\CONFIGURE@_FILE\\ can in fact be +a colon-separated list of file names; Exim uses the first of them that exists. + +There are a few other parameters that can be specified either at build time or +at run time, to enable the same binary to be used on a number of different +machines. However, if the locations of Exim's spool directory and log file +directory (if not within the spool directory) are fixed, it is recommended that +you specify them in \(Local/Makefile)\ instead of at run time, so that errors +detected early in Exim's execution (such as a malformed configuration file) can +be logged. + +.index \(Local/eximon.conf)\ +.index \(exim@_monitor/EDITME)\ +If you are going to build the Exim monitor, a similar configuration process is +required. The file \(exim@_monitor/EDITME)\ must be edited appropriately for +your installation and saved under the name \(Local/eximon.conf)\. If you are +happy with the default settings described in \(exim@_monitor/EDITME)\, +\(Local/eximon.conf)\ can be empty, but it must exist. + +This is all the configuration that is needed in straightforward cases for known +operating systems. However, the building process is set up so that it is easy +to override options that are set by default or by operating-system-specific +configuration files, for example to change the name of the C compiler, which +defaults to \gcc\. See section ~~SECToverride below for details of how to do +this. + + +.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 +(default ISO-8859-1). The translation is possible only if the operating system +supports the \*iconv()*\ function. + +However, some of the operating systems that supply \*iconv()*\ do not support +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 +.display asis +HAVE_ICONV=yes +.endd +to your \(Local/Makefile)\ and rebuild Exim. + + +.section Including TLS/SSL encryption support +.rset SECTinctlsssl "~~chapter.~~section" +.index TLS||including support for TLS +.index encryption||including support for +.index \\SUPPORT@_TLS\\ +.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). + +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. + +If OpenSSL is installed, you should set +.display asis +SUPPORT_TLS=yes +TLS_LIBS=-lssl -lcrypto +.endd +in \(Local/Makefile)\. You may also need to specify the locations of the +OpenSSL library and include files. For example: +.display asis +SUPPORT_TLS=yes +TLS_LIBS=-L/usr/local/openssl/lib -lssl -lcrypto +TLS_INCLUDE=-I/usr/local/openssl/include/ +.endd + +If GnuTLS is installed, you should set +.index \\USE@_GNUTLS\\ +.display asis +SUPPORT_TLS=yes +USE_GNUTLS=yes +TLS_LIBS=-lgnutls -ltasn1 -lgcrypt +.endd +in \(Local/Makefile)\, and again you may need to specify the locations of the +library and include files. For example: +.display asis +SUPPORT_TLS=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 +are given in chapter ~~CHAPTLS. + + + +.section Use of tcpwrappers +.index tcpwrappers, building Exim to support +.index \\USE@_TCP@_WRAPPERS\\ +Exim can be linked with the \*tcpwrappers*\ library in order to check incoming +SMTP calls using the \*tcpwrappers*\ control files. This may be a convenient +alternative to Exim's own checking facilities for installations that are +already making use of \*tcpwrappers*\ for other purposes. To do this, you should +set \\USE@_TCP@_WRAPPERS\\ in \(Local/Makefile)\, arrange for the file +\(tcpd.h)\ to be available at compile time, and also ensure that the library +\(libwrap.a)\ is available at link time, typically by including \-lwrap-\ in +\\EXTRALIBS@_EXIM\\. For example, if \*tcpwrappers*\ is installed in +\(/usr/local)\, you might have +.display +USE@_TCP@_WRAPPERS=yes +CFLAGS=-O -I/usr/local/include +.newline +EXTRALIBS@_EXIM=-L/usr/local/lib -lwrap +.endd +in \(Local/Makefile)\. The name to use in the \*tcpwrappers*\ control files is +`exim'. For example, the line +.display +exim : LOCAL 192.168.1. .friendly.domain.example +.endd +in your \(/etc/hosts.allow)\ file allows connections from the local host, from +the subnet 192.168.1.0/24, and from all hosts in \*friendly.domain.example*\. +All other connections are denied. Consult the \*tcpwrappers*\ documentation for +further details. + + +.section Including support for IPv6 +.index IPv6||including support for +Exim contains code for use on systems that have IPv6 support. Setting +\\HAVE@_IPV6=YES\\ in \(Local/Makefile)\ causes the IPv6 code to be included; +it may also be necessary to set \\IPV6@_INCLUDE\\ and \\IPV6@_LIBS\\ on systems +where the IPv6 support is not fully integrated into the normal include and +library files. + +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)\. + + +.section The building process +.index build directory +Once \(Local/Makefile)\ (and \(Local/eximon.conf)\, if required) have been +created, run \*make*\ at the top level. It determines the architecture and +operating system types, and creates a build directory if one does not exist. +For example, on a Sun system running Solaris 8, the directory +\(build-SunOS5-5.8-sparc)\ is created. +.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 +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 +\(Local)\ directory. The new make file is then passed to another instance of +\*make*\. This does the real work, building a number of utility scripts, and +then compiling and linking the binaries for the Exim monitor (if configured), a +number of utility programs, and finally Exim itself. The command \*make +makefile*\ can be used to force a rebuild of the make file in the build +directory, should this ever be necessary. + +If you have problems building Exim, check for any comments there may be in the +\(README)\ file concerning your operating system, and also take a look at the +.if ~~html +[(A HREF="FAQ.html")] +.fi +FAQ, +.if ~~html +[(/A)] +.fi +where some common problems are covered. + + + +.section Overriding build-time options for Exim +.index build-time options, overriding +.rset SECToverride "~~chapter.~~section" +The main make file that is created at the beginning of the building process +consists of the concatenation of a number of files which set configuration +values, followed by a fixed set of \*make*\ instructions. If a value is set +more than once, the last setting overrides any previous ones. This provides a +convenient way of overriding defaults. The files that are concatenated are, in +order: +.display rm +\(OS/Makefile-Default)\ +\(OS/Makefile-)\<<ostype>> +\(Local/Makefile)\ +\(Local/Makefile-)\<<ostype>> +\(Local/Makefile-)\<<archtype>> +\(Local/Makefile-)\<<ostype>>-<<archtype>> +\(OS/Makefile-Base)\ +.endd +.index \(Local/Makefile)\ +where <<ostype>> is the operating system type and <<archtype>> is the +.index building Exim||operating system type +.index building Exim||architecture type +architecture type. \(Local/Makefile)\ is required to exist, and the building +process fails if it is absent. The other three \(Local)\ files are optional, +and are often not needed. + +The values used for <<ostype>> and <<archtype>> are obtained from scripts +called \(scripts/os-type)\ and \(scripts/arch-type)\ respectively. If either of +the environment variables \\EXIM@_OSTYPE\\ or \\EXIM@_ARCHTYPE\\ is set, their +values are used, thereby providing a means of forcing particular settings. +Otherwise, the scripts try to get values from the \uname\ command. If this +fails, the shell variables \\OSTYPE\\ and \\ARCHTYPE\\ are inspected. A number +of $it{ad hoc} transformations are then applied, to produce the standard names +that Exim expects. You can run these scripts directly from the shell in order +to find out what values are being used on your system. + + +\(OS/Makefile-Default)\ contains comments about the variables that are set +therein. Some (but not all) are mentioned below. If there is something that +needs changing, review the contents of this file and the contents of the make +file for your operating system (\(OS/Makefile-<<ostype>>)\) to see what the +default values are. + + +.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 +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 +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 +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 +these lines directly into \(Local/Makefile)\. + +Keeping all your local configuration settings separate from the distributed +files makes it easy to transfer them to new versions of Exim simply by copying +the contents of the \(Local)\ directory. + + +.index NIS lookup type||including support for +.index NIS@+ lookup type||including support for +.index LDAP||including support for +.index lookup||inclusion in binary +Exim contains support for doing LDAP, NIS, NIS+, and other kinds of file +lookup, but not all systems have these components installed, so the default is +not to include the relevant code in the binary. All the different kinds of file +and database lookup that Exim supports are implemented as separate code modules +which are included only if the relevant compile-time options are set. In the +case of LDAP, NIS, and NIS+, the settings for \(Local/Makefile)\ are: +.display asis +LOOKUP_LDAP=yes +LOOKUP_NIS=yes +LOOKUP_NISPLUS=yes +.endd +and similar settings apply to the other lookup types. They are all listed in +\(src/EDITME)\. In most cases the relevant include files and interface +libraries need to be installed before compiling Exim. +.index cdb||including support for +However, in the case of cdb, which is included in the binary only if +.display asis +LOOKUP_CDB=yes +.endd +is set, the code is entirely contained within Exim, and no external include +files or libraries are required. When a lookup type is not included in the +binary, attempts to configure Exim to use it cause run time configuration +errors. + +.index Perl||including support for +Exim can be linked with an embedded Perl interpreter, allowing Perl +subroutines to be called during string expansion. To enable this facility, +.display asis +EXIM_PERL=perl.o +.endd +must be defined in \(Local/Makefile)\. Details of this facility are given in +chapter ~~CHAPperl. + +.index X11 libraries, location of +The location of the X11 libraries is something that varies a lot between +operating systems, and of course there are different versions of X11 to cope +with. Exim itself makes no use of X11, but if you are compiling the Exim +monitor, the X11 libraries must be available. +The following three variables are set in \(OS/Makefile-Default)\: +.display asis +X11=/usr/X11R6 +XINCLUDE=-I$(X11)/include +XLFLAGS=-L$(X11)/lib +.endd +These are overridden in some of the operating-system configuration files. For +example, in \(OS/Makefile-SunOS5)\ there is +.display asis +X11=/usr/openwin +XINCLUDE=-I$(X11)/include +XLFLAGS=-L$(X11)/lib -R$(X11)/lib +.endd +If you need to override the default setting for your operating system, place a +definition of all three of these variables into your +\(Local/Makefile-<<ostype>>)\ file. + +.index \\EXTRALIBS\\ +If you need to add any extra libraries to the link steps, these can be put in a +variable called \\EXTRALIBS\\, which appears in all the link commands, but by +default is not defined. In contrast, \\EXTRALIBS@_EXIM\\ is used only on the +command for linking the main Exim binary, and not for any associated utilities. +.index DBM||libraries, configuration for building +There is also \\DBMLIB\\, which appears in the link commands for binaries that +use DBM functions (see also section ~~SECTdb). Finally, there is +\\EXTRALIBS@_EXIMON\\, which appears only in the link step for the Exim monitor +binary, and which can be used, for example, to include additional X11 +libraries. + +.index configuration file||editing +The make file copes with rebuilding Exim correctly if any of the configuration +files are edited. However, if an optional configuration file is deleted, it is +necessary to touch the associated non-optional file (that is, \(Local/Makefile)\ +or \(Local/eximon.conf)\) before rebuilding. + +.section OS-specific header files +.index \(os.h)\ +.index building Exim||OS-specific C header files +The \(OS)\ directory contains a number of files with names of the form +\(os.h-<<ostype>>)\. These are system-specific C header files that should not +normally need to be changed. There is a list of macro settings that are +recognized in the file \(OS/os.configuring)\, which should be consulted if you +are porting Exim to a new operating system. + + +.section Overriding build-time options for the monitor +.index building Eximon||overriding default options +A similar process is used for overriding things when building the Exim monitor, +where the files that are involved are +.display rm +\(OS/eximon.conf-Default)\ +\(OS/eximon.conf-)\<<ostype>> +\(Local/eximon.conf)\ +\(Local/eximon.conf-)\<<ostype>> +\(Local/eximon.conf-)\<<archtype>> +\(Local/eximon.conf-)\<<ostype>>-<<archtype>> +.endd +.index \(Local/eximon.conf)\ +As with Exim itself, the final three files need not exist, and in this case the +\(OS/eximon.conf-<<ostype>>)\ file is also optional. The default values in +\(OS/eximon.conf-Default)\ can be overridden dynamically by setting environment +variables of the same name, preceded by \\EXIMON@_\\. For example, setting +\\EXIMON@_LOG@_DEPTH\\ in the environment overrides the value of +\\LOG@_DEPTH\\ at run time. + + + +.section Installing Exim binaries and scripts +.index installing Exim +.index \\BIN@_DIRECTORY\\ +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)\. + +Exim's run time configuration file is named by the \\CONFIGURE@_FILE\\ setting +.index \\CONFIGURE@_FILE\\ +in \(Local/Makefile)\. If this names a single file, and the file does not +exist, the default configuration file \(src/configure.default)\ is copied there +by the installation script. If a run time configuration file already exists, it +is left alone. If \\CONFIGURE@_FILE\\ is a colon-separated list, naming several +alternative files, no default is installed. + +.index system aliases file +.index \(/etc/aliases)\ +One change is made to the default configuration file when it is installed: the +default configuration contains a router that references a system aliases file. +The path to this file is set to the value specified by +\\SYSTEM@_ALIASES@_FILE\\ in \(Local/Makefile)\ (\(/etc/aliases)\ by default). +If the system aliases file does not exist, the installation script creates it, +and outputs a comment to the user. + +The created file contains no aliases, but it does contain comments about the +aliases a site should normally have. Mail aliases have traditionally been +kept in \(/etc/aliases)\. However, some operating systems are now using +\(/etc/mail/aliases)\. You should check if yours is one of these, and change +Exim's configuration if necessary. + +The default configuration uses the local host's name as the only local domain, +and is set up to do local deliveries into the shared directory \(/var/mail)\, +running as the local user. System aliases and \(.forward)\ files in users' home +directories are supported, but no NIS or NIS+ support is configured. Domains +other than the name of the local host are routed using the DNS, with delivery +over SMTP. + +The install script copies files only if they are newer than the files they are +going to replace. The Exim binary is required to be owned by root and have the +\*setuid*\ bit set, +.index setuid||installing Exim with +for normal configurations. Therefore, you must run \*make install*\ as root so +that it can set up the Exim binary in this way. However, in some special +situations (for example, if a host is doing no local deliveries) it may be +possible to run Exim without making the binary setuid root (see chapter +~~CHAPsecurity for details). + +It is possible to install Exim for special purposes (such as building a binary +distribution) in a private part of the file system. You can do this by a +command such as +.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 +configuration. (If a default alias file is created, its name \*is*\ modified.) +For backwards compatibility, \\ROOT\\ is used if \\DESTDIR\\ is not set, +but this usage is deprecated. + +.index installing Exim||what is not installed +Running \*make install*\ does not copy the Exim 4 conversion script +\*convert4r4*\, or the \*pcretest*\ test program. You will probably run the +first of these only once (if you are upgrading from Exim 3), and the second +isn't really part of Exim. None of the documentation files in the \(doc)\ +directory are copied, except for the info files when you have set +\\INFO@_DIRECTORY\\, as described in section ~~SECTinsinfdoc below. + +For the utility programs, old versions are renamed by adding the suffix \(.O)\ +to their names. The Exim binary itself, however, is handled differently. It is +installed under a name that includes the version number and the compile number, +for example \(exim-~~version-1)\. The script then arranges for a symbolic link +called \(exim)\ to point to the binary. If you are updating a previous version +of Exim, the script takes care to ensure that the name \(exim)\ is never absent +from the directory (as seen by other processes). + +.index installing Exim||testing the script +If you want to see what the \*make install*\ will do before running it for +real, you can pass the \-n-\ option to the installation script by this command: +.display asis +make INSTALL_ARG=-n install +.endd +The contents of the variable \\INSTALL@_ARG\\ are passed to the installation +script. You do not need to be root to run this test. Alternatively, you can run +the installation script directly, but this must be from within the build +directory. For example, from the top-level Exim directory you could use this +command: +.display +(cd build-SunOS5-5.5.1-sparc; ../scripts/exim@_install -n) +.endd + +.index installing Exim||install script options +There are two other options that can be supplied to the installation script. +.numberpars $. +\-no@_chown-\ bypasses the call to change the owner of the installed binary +to root, and the call to make it a setuid binary. +.nextp +\-no@_symlink-\ bypasses the setting up of the symbolic link \(exim)\ to the +installed binary. +.endp +\\INSTALL@_ARG\\ can be used to pass these options to the script. For example: +.display asis +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, +without creating the symbolic link, you could use: +.display asis +make INSTALL_ARG='-no_symlink exim' install +.endd + + +.section Installing info documentation +.rset SECTinsinfdoc "~~chapter.~~section" +.index installing Exim||\*info*\ documentation +Not all systems use the GNU \*info*\ system for documentation, and for this +reason, the Texinfo source of Exim's documentation is not included in the main +distribution. Instead it is available separately from the ftp site (see section +~~SECTavail). + +If you have defined \\INFO@_DIRECTORY\\ in \(Local/Makefile)\ and the Texinfo +source of the documentation is found in the source tree, running \*make +install*\ automatically builds the info files and installs them. + + +.section Setting up the spool directory +.index spool directory||creating +When it starts up, Exim tries to create its spool directory if it does not +exist. The Exim uid and gid are used for the owner and group of the spool +directory. Sub-directories are automatically created in the spool directory as +necessary. + + + +.section Testing +.index testing||installation +Having installed Exim, you can check that the run time configuration file is +syntactically valid by running the following command, which assumes that the +Exim binary directory is within your \\PATH\\ environment variable: +.display +exim -bV +.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 +other optional code modules are included in the binary. +Some simple routing tests can be done by using the address testing option. For +example, +.display +exim -bt <<local username>> +.endd +should verify that it recognizes a local mailbox, and +.display +exim -bt <<remote address>> +.endd +a remote one. Then try getting it to deliver mail, both locally and remotely. +This can be done by passing messages directly to Exim, without going through a +user agent. For example: +.display +exim -v postmaster@@your.domain.example +From: user@@your.domain.example +To: postmaster@@your.domain.example +Subject: Testing Exim + +This is a test message. +^D +.endd +The \-v-\ option causes Exim to output some verification of what it is doing. +In this case you should see copies of three log lines, one for the message's +arrival, one for its delivery, and one containing `Completed'. + +.index delivery||problems with +If you encounter problems, look at Exim's log files (\*mainlog*\ and +\*paniclog*\) to see if there is any relevant information there. Another source +of information is running Exim with debugging turned on, by specifying the +\-d-\ option. If a message is stuck on Exim's spool, you can force a delivery +with debugging turned on by a command of the form +.display +exim -d -M <<message-id>> +.endd +You must be root or an `admin user' in order to do this. The \-d-\ option +produces rather a lot of output, but you can cut this down to specific areas. +For example, if you use \-d-all+route-\ only the debugging information relevant +to routing is included. (See the \-d-\ option in chapter ~~CHAPcommandline for +more details.) + +.index `sticky' bit +.index lock files +One specific problem that has shown up on some sites is the inability to do +local deliveries into a shared mailbox directory, because it does not have the +`sticky bit' set on it. By default, Exim tries to create a lock file before +writing to a mailbox file, and if it cannot create the lock file, the delivery +is deferred. You can get round this either by setting the `sticky bit' on the +directory, or by setting a specific group for local deliveries and allowing +that group to create files in the directory (see the comments above the +\%local@_delivery%\ transport in the default configuration file). Another +approach is to configure Exim not to use lock files, but just to rely on +\*fcntl()*\ locking instead. However, you should do this only if all user +agents also use \*fcntl()*\ locking. For further discussion of locking issues, +see chapter ~~CHAPappendfile. + +One thing that cannot be tested on a system that is already running an MTA is +the receipt of incoming SMTP mail on the standard SMTP port. However, the +\-oX-\ option can be used to run an Exim daemon that listens on some other +port, or \*inetd*\ can be used to do this. The \-bh-\ option and the +\*exim@_checkaccess*\ utility can be used to check out policy controls on +incoming SMTP mail. + +Testing a new version on a system that is already running Exim can most easily +be done by building a binary with a different \\CONFIGURE@_FILE\\ setting. From +within the run time configuration, all other file and directory names +that Exim uses can be altered, in order to keep it entirely clear of the +production version. + +.section Replacing another MTA with Exim +.index replacing another MTA +Building and installing Exim for the first time does not of itself put it in +general use. The name by which the system's MTA is called by mail user agents +is either \(/usr/sbin/sendmail)\, or \(/usr/lib/sendmail)\ (depending on the +operating system), and it is necessary to make this name point to the \*exim*\ +binary in order to get the user agents to pass messages to Exim. This is +normally done by renaming any existing file and making \(/usr/sbin/sendmail)\ +or \(/usr/lib/sendmail)\ +.index symbolic link||to \*exim*\ binary +a symbolic link to the \*exim*\ binary. It is a good idea to remove any setuid +privilege and executable status from the old MTA. It is then necessary to stop +and restart the mailer daemon, if one is running. + +.index FreeBSD, MTA indirection +.index \(/etc/mail/mailer.conf)\ +Some operating systems have introduced alternative ways of switching MTAs. For +example, if you are running FreeBSD, you need to edit the file +\(/etc/mail/mailer.conf)\ instead of setting up a symbolic link as just +described. A typical example of the contents of this file for running Exim is +as follows: +.display asis +sendmail /usr/exim/bin/exim +send-mail /usr/exim/bin/exim +mailq /usr/exim/bin/exim -bp +newaliases /usr/bin/true +.endd + +Once you have set up the symbolic link, or edited \(/etc/mail/mailer.conf)\, +your Exim installation is `live'. Check it by sending a message from your +favourite user agent. + +You should consider what to tell your users about the change of MTA. Exim may +have different capabilities to what was previously running, and there are +various operational differences such as the text of messages produced by +command line options and in bounce messages. If you allow your users to make +use of Exim's filtering capabilities, you should make the document entitled +.if ~~html +[(A HREF="filter.html")] +.fi +\*Exim's interface to mail filtering*\ +.if ~~html +[(/A)] +.fi +available to them. + + +.section Upgrading Exim +.index upgrading Exim +If you are already running Exim on your host, building and installing a new +version automatically makes it available to MUAs, or any other programs that +call the MTA directly. However, if you are running an Exim daemon, you do need +to send it a HUP signal, to make it re-exec itself, and thereby pick up the new +binary. You do not need to stop processing mail in order to install a new +version of Exim. + + +.section Stopping the Exim daemon on Solaris +.index Solaris||stopping Exim on +The standard command for stopping the mailer daemon on Solaris is +.display +/etc/init.d/sendmail stop +.endd +If \(/usr/lib/sendmail)\ has been turned into a symbolic link, this script +fails to stop Exim because it uses the command \*ps -e*\ and greps the output +for the text `sendmail'; this is not present because the actual program name +(that is, `exim') is given by the \*ps*\ command with these options. A solution +is to replace the line that finds the process id with something like +.display asis +pid=`cat /var/spool/exim/exim-daemon.pid` +.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 +(the normal case), deliveries will still occur. + + +. +. +. +. +. ============================================================================ +.chapter The Exim command line +.set runningfoot "command line" +.rset CHAPcommandline ~~chapter +.index command line||options +.index options||command line + +Exim's command line takes the standard Unix form of a sequence of options, +each starting with a hyphen character, followed by a number of arguments. The +options are compatible with the main options of Sendmail, and there are also +some additional options, some of which are compatible with Smail 3. Certain +combinations of options do not make sense, and provoke an error if used. +The form of the arguments depends on which options are set. + +.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 +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 +\(/usr/sbin/sendmail)\ or \(/usr/lib/sendmail)\. + +.index \*rsmtp*\ +If Exim is called under the name \*rsmtp*\ it behaves as if the option \-bS-\ +were present before any other options, for compatibility with Smail. The \-bS-\ +option is used for reading in a number of messages in batched SMTP format. + +.index \*rmail*\ +If Exim is called under the name \*rmail*\ it behaves as if the \-i-\ and +\-oee-\ options were present before any other options, for compatibility with +Smail. The name \*rmail*\ is used as an interface by some UUCP systems. + +.index \*runq*\ +.index queue runner +If Exim is called under the name \*runq*\ it behaves as if the option \-q-\ were +present before any other options, for compatibility with Smail. The \-q-\ +option causes a single queue runner process to be started. + +.index \*newaliases*\ +.index alias file||building +.index Sendmail compatibility||calling Exim as \*newaliases*\ +If Exim is called under the name \*newaliases*\ it behaves as if the option +\-bi-\ were present before any other options, for compatibility with Sendmail. +This option is used for rebuilding Sendmail's alias file. Exim does not have +the concept of a single alias file, but can be configured to run a given +command if called with the \-bi-\ option. + +.section Trusted and admin users +.rset SECTtrustedadmin "~~chapter.~~section" +Some Exim options are available only to \*trusted users*\ and others are +available only to \*admin users*\. In the description below, the phrases `Exim +user' and `Exim group' mean the user and group defined by \\EXIM@_USER\\ and +\\EXIM@_GROUP\\ in \(Local/Makefile)\ or set by the \exim@_user\ and +\exim@_group\ options. These do not necessarily have to use the name `exim'. + +.numberpars $. +.index trusted user||definition of +.index user||trusted, definition of +The trusted users are root, the Exim user, any user listed in the +\trusted@_users\ configuration option, and any user whose current group or any +supplementary group is one of those listed in the \trusted@_groups\ +configuration option. Note that the Exim group is not automatically trusted. + +.index `From' line +.index envelope sender +Trusted users are always permitted to use the \-f-\ option or a leading `From ' +line to specify the envelope sender of a message that is passed to Exim through +the local interface (see the \-bm-\ and \-f-\ options below). See the +\untrusted@_set@_sender\ option for a way of permitting non-trusted users to +set envelope senders. +.index ::From:: header line +.index ::Sender:: header line +For a trusted user, there is never any check on the contents of the ::From:: +header line, and a ::Sender:: line is never added. Furthermore, any existing +::Sender:: line in incoming local (non-TCP/IP) messages is not removed. + +Trusted users may also specify a host name, host address, interface address, +protocol name, ident value, and authentication data when submitting a message +locally. Thus, they are able to insert messages into Exim's queue locally that +have the characteristics of messages received from a remote host. Untrusted +users may in some circumstances use \-f-\, but can never set the other values +that are available to trusted users. +.nextp +.index user||admin, definition of +.index admin user||definition of +The admin users are root, the Exim user, and any user that is a member of the +Exim group or of any group listed in the \admin@_groups\ configuration option. +The current group does not have to be one of these groups. + +Admin users are permitted to list the queue, and to carry out certain +operations on messages, for example, to force delivery failures. It is also +necessary to be an admin user in order to see the full information provided by +the Exim monitor, and full debugging output. + +By default, the use of the \-M-\, \-q-\, \-R-\, and \-S-\ options to cause Exim +to attempt delivery of messages on its queue is restricted to admin users. +However, this restriction can be relaxed by setting the \prod@_requires@_admin\ +option false (that is, specifying \no@_prod@_requires@_admin\). + +Similarly, the use of the \-bp-\ option to list all the messages in the queue +is restricted to admin users unless \queue@_list@_requires@_admin\ is set +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 +~~CHAPconf. + + + +.section Command line options +The command options are described in alphabetical order below. + +.startoptions + +.option @- +.index options||command line, terminating +This is a pseudo-option whose only purpose is to terminate the options and +therefore to cause subsequent command line items to be treated as arguments +rather than options, even if they begin with hyphens. + +.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 +no arguments. + +.option B <<type>> +.index 8-bit characters +.index Sendmail compatibility||8-bit characters +This is a Sendmail option for selecting 7 or 8 bit processing. Exim is 8-bit +clean; it ignores this option. + +.option bd +.index daemon +.index SMTP listener +.index queue runner +This option runs Exim as a daemon, awaiting incoming SMTP connections. Usually +the \-bd-\ option is combined with the \-q-\<<time>> option, to specify that +the daemon should also initiate periodic queue runs. + +The \-bd-\ option can be used only by an admin user. If either of the \-d-\ +(debugging) or \-v-\ (verifying) options are set, the daemon does not +disconnect from the controlling terminal. When running this way, it can be +stopped by pressing ctrl-C. + +By default, Exim listens for incoming connections to the standard SMTP port on +all the host's running interfaces. However, it is possible to listen on other +ports, on multiple ports, and only on specific interfaces. Chapter +~~CHAPinterfaces contains a description of the options that control this. + +.index daemon||process id (pid) +.index pid (process id)||of daemon +When a listening daemon is started without the use of \-oX-\ (that is, without +overriding the normal configuration), it writes its process id to a file called +\(exim-daemon.pid)\ in Exim's spool directory. This location can be overridden +by setting \\PID@_FILE@_PATH\\ in \(Local/Makefile)\. The file is written while +Exim is still running as root. + +When \-oX-\ is used on the command line to start a listening daemon, the +process id is not written to the normal pid file path. However, \-oP-\ can be +used to specify a path on the command line if a pid file is required. + +.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 +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. + +.option bdf +This option has the same effect as \-bd-\ except that it never disconnects from +the controlling terminal, even when no debugging is specified. + +.option be +.index testing||string expansion +.index expansion||testing +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. + +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 testing||system filter +This option is the same as \-bf-\ except that it assumes that the filter being +tested is a system filter. The additional commands that are available only in +system filters are recognized. + +.option bf #<<filename>> +.index filter||testing +.index testing||filter file +.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 +.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 +description of the possible contents of non-filter redirection lists. + +The result of an Exim command that uses \-bf-\, provided no errors are +detected, is a list of the actions that Exim would try to take if presented +with the message for real. More details of filter testing are given in the +separate document entitled \*Exim's interfaces to mail filtering*\. + +.index `From' line +.index envelope sender +.index \-f-\ option||for filter testing +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 +suffix stripped, because that is how it appears to the filter when a message is +actually being delivered. + +.option bh #<<IP address>> +.index testing||incoming SMTP +.index SMTP||testing incoming +.index testing||relay control +.index relaying||testing configuration +.index policy control||testing +.index debugging||\-bh-\ option +This option runs a fake SMTP session as if from the given IP address, using the +standard input and output. The IP address may include a port number at the end, +after a full stop. For example: +.display asis +exim -bh 10.9.8.7.1234 +exim -bh fe80::a00:20ff:fe86:a061.5678 +.endd +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 +test your relay controls using \-bh-\. + +.index RFC 1413 +\**Warning 1**\: You cannot test features of the configuration that rely on +ident (RFC 1413) callouts. These cannot be done when testing using +\-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, +use \-bhc-\ instead. + +Messages supplied during the testing session are discarded, and nothing is +written to any of the real log files. There may be pauses when DNS (and other) +lookups are taking place, and of course these may time out. The \-oMi-\ option +can be used to specify a specific IP interface and port if this is important. + +The \*exim@_checkaccess*\ utility is a `packaged' version of \-bh-\ whose +output just states whether a given recipient address from a given host 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. + +.option bi +.index alias file||building +.index building alias file +.index Sendmail compatibility||\-bi-\ option +Sendmail interprets the \-bi-\ option as a request to rebuild its alias file. +Exim does not have the concept of a single alias file, and so it cannot mimic +this behaviour. However, calls to \(/usr/lib/sendmail)\ with the \-bi-\ option +tend to appear in various scripts such as NIS make files, so the option must be +recognized. + +If \-bi-\ is encountered, the command specified by the \bi@_command\ +configuration option is run, under the uid and gid of the caller of Exim. If +the \-oA-\ option is used, its value is passed to the command as an argument. +The command set by \bi@_command\ may not contain arguments. The command can use +the \*exim@_dbmbuild*\ utility, or some other means, to rebuild alias files if +this is required. If the \bi@_command\ option is not set, calling Exim with +\-bi-\ is a no-op. + +.option bm +.index local message reception +This option runs an Exim receiving process that accepts an incoming, +locally-generated message on the current input. The recipients are given as the +command arguments (except when \-t-\ is also present -- see below). Each +argument can be a comma-separated list of RFC 2822 addresses. This is the +default option for selecting the overall action of an Exim call; it is assumed +if no other conflicting option is present. + +If any addresses in the message are unqualified (have no domain), they are +qualified by the values of the \qualify@_domain\ or \qualify@_recipient\ +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 +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 +action is controlled by the \-oe$it{x}-\ option setting -- see below. + +.index message||format +.index format||message +.index `From' line +.index UUCP||`From' line +.index Sendmail compatibility||`From' line +The format of the message must be as defined in RFC 2822, except that, for +compatibility with Sendmail and Smail, a line in one of the forms +.display +From sender Fri Jan 5 12:55 GMT 1997 +From sender Fri, 5 Jan 97 12:55:01 +.endd +(with the weekday optional, and possibly with additional text after the date) +is permitted to appear at the start of the message. There appears to be no +authoritative specification of the format of this line. Exim recognizes it by +matching against the regular expression defined by the \uucp@_from@_pattern\ +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 +preference to the address taken from the message. The caller of Exim must be a +trusted user for the sender of a message to be set in this way. + +.option bnq +.index address||qualification, suppressing +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 +defaults to the value of \qualify@_domain\). + +Sometimes, qualification is not wanted. For example, if \-bS-\ (batch SMTP) is +being used to re-submit messages that originally came from remote hosts after +content scanning, you probably do not want to qualify unqualified addresses in +header lines. (Such lines will be present only if you have not enabled a header +syntax check in the appropriate ACL.) + +The \-bnq-\ option suppresses all qualification of unqualified addresses in +messages that originate on the local host. When this is used, unqualified +addresses in the envelope provoke errors (causing message rejection) and +unqualified addresses in header lines are left alone. + + +.option bP +.index configuration options, extracting +.index options||configuration, extracting +If this option is given with no arguments, it causes the values of all Exim's +main configuration options to be written to the standard output. The values +of one or more specific options can be requested by giving their names as +arguments, for example: +.display +exim -bP qualify@_domain hold@_domains +.endd +However, any option setting that is preceded by the word `hide' in the +configuration file is not shown in full, except to an admin user. For other +users, the output is as in this example: +.display asis +mysql_servers = <value not displayable> +.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 +is the name of the file that was actually used. + +.index daemon||process id (pid) +.index pid (process id)||of daemon +If \log__file__path\ or \pid@_file@_path\ are given, the names of the +directories where log files and daemon pid files are written are output, +respectively. If these values are unset, log files are written in a +sub-directory of the spool directory called \log\, and the pid file is written +directly into the spool directory. + +If \-bP-\ is followed by a name preceded by \"+"\, for example, +.display asis +exim -bP +local_domains +.endd +it searches for a matching named list of any type (domain, host, address, or +local part) and outputs what it finds. + +.index options||router, extracting +.index options||transport, extracting +If one of the words \router\, \transport\, or \authenticator\ is given, +followed by the name of an appropriate driver instance, the option settings for +that driver are output. For example: +.display +exim -bP transport local@_delivery +.endd +The generic driver options are output first, followed by the driver's private +options. A list of the names of drivers of a particular type can be obtained by +using one of the words \router@_list\, \transport@_list\, or +\authenticator@_list\, and a complete list of all drivers with their option +settings can be obtained by using \routers\, \transports\, or \authenticators\. + + +.option bp +.index queue||listing messages on +.index listing||messages on the queue +This option requests a listing of the contents of the mail queue on the +standard output. If the \-bp-\ option is followed by a list of message ids, +just those messages are listed. By default, this option can be used only by an +admin user. However, the \queue__list__requires__admin\ option can be set false +to allow any user to see the queue. + +Each message on the queue is displayed as in the following example: +.display +25m 2.9K 0t5C6f-0000c8-00 <alice@@wonderland.fict.example> + red.king@@looking-glass.fict.example + <<other addresses>> +.endd +.index message||size in queue listing +.index size||of message +The first line contains the length of time the message has been on the queue +(in this case 25 minutes), the size of the message (2.9K), the unique local +identifier for the message, and the message sender, as contained in the +envelope. For bounce messages, the sender address is empty, and appears as +`<>'. If the message was submitted locally by an untrusted user who overrode +the default sender address, the user's login name is shown in parentheses +before the sender address. +.index frozen messages||in queue listing +If the message is frozen (attempts to deliver it are suspended) then the text +`$*$$*$$*$ frozen $*$$*$$*$' is displayed at the end of this line. + +The recipients of the message (taken from the envelope, not the headers) are +displayed on subsequent lines. Those addresses to which the message has already +been delivered are marked with the letter D. If an original address gets +expanded into several addresses via an alias or forward file, the original is +displayed with a D only when deliveries for all of its child addresses are +complete. + + +.option bpa +This option operates like \-bp-\, but in addition it shows delivered addresses +that were generated from the original top level address(es) in each message by +alias or forwarding operations. These addresses are flagged with `+D' instead +of just `D'. + + +.option bpc +.index queue||count of messages on +This option counts the number of messages on the queue, and writes the total +to the standard output. It is restricted to admin users, unless +\queue__list__requires__admin\ is set false. + + +.option bpr +This option operates like \-bp-\, but the output is not sorted into +chronological order of message arrival. This can speed it up when there are +lots of messages on the queue, and is particularly useful if the output is +going to be post-processed in a way that doesn't need the sorting. + +.option bpra +This option is a combination of \-bpr-\ and \-bpa-\. + +.option bpru +This option is a combination of \-bpr-\ and \-bpu-\. + + +.option bpu +This option operates like \-bp-\ but shows only undelivered top-level addresses +for each message displayed. Addresses generated by aliasing or forwarding are +not shown, unless the message was deferred after processing by a router with +the \one@_time\ option set. + + +.option brt +.index testing||retry configuration +.index retry||configuration testing +This option is for testing retry rules, and it must be followed by up to three +arguments. It causes Exim to look for a retry rule that matches the values +and to write it to the standard output. For example: +.display asis +exim -brt bach.comp.mus.example +Retry rule: *.comp.mus.example F,2h,15m; F,4d,30m; +.endd +See chapter ~~CHAPretry for a description of Exim's retry rules. The first +argument, which is required, can be a complete address in the form +\*local@_part@@domain*\, or it can be just a domain name. The second argument is +an optional second domain name; if no retry rule is found for the first +argument, the second is tried. This ties in with Exim's behaviour when looking +for retry rules for remote hosts -- if no rule is found that matches the host, +one that matches the mail domain is sought. The final argument is the name of a +specific delivery error, as used in setting up retry rules, for example +`quota@_3d'. + +.option brw +.index testing||rewriting +.index rewriting||testing +This option is for testing address rewriting rules, and it must be followed by +a single argument, consisting of either a local part without a domain, or a +complete address with a fully qualified domain. Exim outputs how this address +would be rewritten for each possible place it might appear. See chapter +~~CHAPrewrite for further details. + +.option bS +.index SMTP||batched incoming +.index batched SMTP input +This option is used for batched SMTP input, which is an alternative interface +for non-interactive local message submission. A number of messages can be +submitted in a single run. However, despite its name, this is not really SMTP +input. Exim reads each message's envelope from SMTP commands on the standard +input, but generates no responses. If the caller is trusted, or +\untrusted@_set@_sender\ is set, the senders in the SMTP \\MAIL\\ commands are +believed; otherwise the sender is always the caller of Exim. + +The message itself is read from the standard input, in SMTP format (leading +dots doubled), terminated by a line containing just a single dot. An error is +provoked if the terminating dot is missing. A further message may then follow. + +As for other local message submissions, the contents of incoming batch SMTP +messages can be checked using the non-SMTP ACL (see chapter ~~CHAPACL). +Unqualified addresses are automatically qualified using \qualify@_domain\ and +\qualify@_recipient\, as appropriate, unless the \-bnq-\ option is used. + +Some other SMTP commands are recognized in the input. \\HELO\\ and \\EHLO\\ act +as \\RSET\\; \\VRFY\\, \\EXPN\\, \\ETRN\\, and \\HELP\\ act as \\NOOP\\; +\\QUIT\\ quits, ignoring the rest of the standard input. + +If any error is encountered, reports are written to the standard output and +error streams, and Exim gives up immediately. +.index return code||for \-bS-\ +The return code is 0 if no error was detected; it is 1 if one or more messages +were accepted before the error was detected; otherwise it is 2. + +More details of input using batched SMTP are given in section +~~SECTincomingbatchedSMTP. + +.option bs +.index SMTP||local input +.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. + +Some user agents use this interface as a way of passing locally-generated +messages to the MTA. +.index sender||source of +In this usage, if the caller of Exim is trusted, or \untrusted@_set@_sender\ is +set, the senders of messages are taken from the SMTP \\MAIL\\ commands. +Otherwise the content of these commands is ignored and the sender is set up as +the calling user. Unqualified addresses are automatically qualified using +\qualify@_domain\ and \qualify@_recipient\, as appropriate, unless the \-bnq-\ +option is used. + +.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 +the listening daemon. + +.option bt +.index testing||addresses +.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. + +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. + +.index return code||for \-bt-\ +The return code is 2 if any address failed outright; it is 1 if no address +failed outright but at least one could not be resolved for some reason. Return +code 0 is given only when all addresses succeed. + +\**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, +.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 +default qualifying domain. However, if you have set up (for example) routers +whose behaviour depends on the contents of an incoming message, you cannot test +those conditions using \-bt-\. The \-N-\ option provides a possible way of +doing such tests. + +.option bV +.index version number of Exim, verifying +This option causes Exim to write the current version number, compilation +number, and compilation date of the \*exim*\ binary to the standard output. +It also lists the DBM library this is being used, the optional modules (such as +specific lookup types), the drivers that are included in the binary, and the +name of the run time configuration file that is in use. + +.option bv +.index verifying||address, using \-bv-\ +.index address||verification +This option runs Exim in address verification mode, in which each argument is +taken as an address to be verified. During normal operation, verification +happens mostly as a consequence processing a \verify\ condition in an ACL (see +chapter ~~CHAPACL). If you want to test an entire ACL, see the \-bh-\ option. + +If verification fails, and the caller is not an admin user, no details of the +failure are output, because these might contain sensitive information such as +usernames and passwords for database lookups. + +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. + +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 +latter case. Otherwise, more details are given of how the address has been +handled, and in the case of address redirection, all the generated addresses +are also considered. Without \-v-\, generating more than one address by +redirection causes verification to end sucessfully. + +.index return code||for \-bv-\ +The return code is 2 if any address failed outright; it is 1 if no address +failed outright but at least one could not be resolved for some reason. Return +code 0 is given only when all addresses succeed. + +If any of the routers in the configuration makes any tests on the sender +address of a message, you should use the \-f-\ option to set an appropriate +sender when running \-bv-\ tests. Without it, the sender is assumed to be the +calling user at the default qualifying domain. + +.option bvs +This option acts like \-bv-\, but verifies the address as a sender rather +than a recipient address. This affects any rewriting and qualification that +might happen. + +.option C #<<filelist>> +.index configuration file||alternate +.index \\CONFIGURE@_FILE\\ +.index alternate configuration file +This option causes Exim to find the run time configuration file from the given +list instead of from the list specified by the \\CONFIGURE@_FILE\\ +compile-time setting. Usually, the list will consist of just a single file +name, but it can be a colon-separated list of names. In this case, the first +file that exists is used. Failure to open an existing file stops Exim from +proceeding any further along the list, and an error is generated. + +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. + +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 +\-odq-\, and another to do the delivery, using \-M-\). + +If \\ALT@_CONFIG@_PREFIX\\ is defined \(in Local/Makefile)\, it specifies a +prefix string with which any file named in a \-C-\ command line option +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 +unset, any file name can be used with \-C-\. + +\\ALT@_CONFIG@_PREFIX\\ can be used to confine alternative configuration files +to a directory to which only root has access. This prevents someone who has +broken into the Exim account from running a privileged Exim with an arbitrary +configuration file. + +The \-C-\ facility is useful for ensuring that configuration files are +syntactically correct, but cannot be used for test deliveries, unless the +caller is privileged, or unless it is an exotic configuration that does not +require privilege. No check is made on the owner or group of the files +specified by this option. + +.option D <<macro>>=<<value>> +.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. +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 +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 +example: +.display asis +exim '-D ABC = something' ... +.endd +\-D-\ may be repeated up to 10 times on a command line. + +.option d <<debug options>> +.index debugging||list of selectors +.index debugging||\-d-\ option +This option causes debugging information to be written to the standard +error stream. It is restricted to admin users because debugging output may show +database queries that contain password information. Also, the details of users' +filter files should be protected. When \-d-\ is used, \-v-\ is assumed. If +\-d-\ is given on its own, a lot of standard debugging data is output. This can +be reduced, or increased to include some more rarely needed information, by +following \-d-\ with a string made up of names preceded by plus or minus +characters. These add or remove sets of debugging data, respectively. For +example, \-d+filter-\ adds filter debugging, whereas \-d-all+filter-\ selects +only filter debugging. The available debugging categories are: +.display flow +.tabs 21 +. +. The odd formatting of the lines below is deliberate. It does not affect the +. SGCAL output, but by putting in the space it keeps things aligned in the man +. page that is automatically generated from this text. +. +acl $t $rm{ACL interpretation} +auth $t $rm{authenticators} +deliver $t $rm{general delivery logic} +dns $t $rm{DNS lookups (see also resolver)} +dnsbl $t $rm{DNS black list (aka RBL) code} +exec $t $rm{arguments for \execv@(@)\ calls} +expand $t $rm{detailed debugging for string expansions} +filter $t $rm{filter handling} +hints@_lookup $t $rm{hints data lookups} +host@_lookup $t $rm{all types of name-to-IP address handling} +ident $t $rm{ident lookup} +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)} +lookup $t $rm{general lookup code and all lookups} +memory $t $rm{memory handling} +pid $t $rm{add pid to debug output lines} +process@_info $t $rm{setting info for the process log} +queue@_run $t $rm{queue runs} +receive $t $rm{general message reception logic} +resolver $t $rm{turn on the DNS resolver's debugging output} +retry $t $rm{retry handling} +rewrite $t $rm{address rewriting} +route $t $rm{address routing} +timestamp $t $rm{add timestamp to debug output lines} +tls $t $rm{TLS logic} +transport $t $rm{transports} +uid $t $rm{changes of uid/gid and looking up uid/gid} +verify $t $rm{address verification logic} + +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 +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"\. +However, the \"pid"\ selector is forced when debugging is turned on for a +daemon, which then passes it on to any re-executed Exims. Exim also +automatically adds the pid to debug lines when several remote deliveries are +run in parallel. + +The \"timestamp"\ selector causes the current time to be inserted at the start +of all debug output lines. This can be useful when trying to track down delays +in processing. + +If the \debug@_print\ option is set in any driver, it produces output whenever +any debugging is selected, or if \-v-\ is used. + +.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 +described in section ~~SECTlineendings. + + +.option E +.index bounce message||generating +This option specifies that an incoming message is a locally-generated delivery +failure report. It is used internally by Exim when handling delivery failures +and is not intended for external use. Its only effect is to stop Exim +generating certain messages to the postmaster, as otherwise message cascades +could occur in some situations. As part of the same option, a message id may +follow the characters \-E-\. If it does, the log entry for the receipt of the +new message contains the id, following `R=', as a cross-reference. + +.option e$it{x} +There are a number of Sendmail options starting with \-oe-\ which seem to be +called by various programs without the leading \o\ in the option. For example, +the \vacation\ program uses \-eq-\. Exim treats all options of the form +\-e$it{x}-\ as synonymous with the corresponding \-oe$it{x}-\ options. + +.option F #<<string>> +.index sender||name +.index name||of sender +This option sets the sender's full name for use when a locally-generated +message is being accepted. In the absence of this option, the user's \*gecos*\ +entry from the password data is used. As users are generally permitted to alter +their \*gecos*\ entries, no security considerations are involved. White space +between \-F-\ and the <<string>> is optional. + +.option f #<<address>> +.index sender||address +.index address||sender +.index trusted user +.index envelope sender +.index user||trusted +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. + +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: +.display asis +exim -f '<>' user@domain +exim -f "" user@domain +.endd +In addition, the use of \-f-\ is not restricted when testing a filter file with +\-bf-\ or when testing or verifying addresses using the \-bt-\ or \-bv-\ +options. + +Allowing untrusted users to change the sender address does not of itself make +it possible to send anonymous mail. Exim still checks that the ::From:: header +refers to the local user, and if it does not, it adds a ::Sender:: header, +though this can be overridden by setting \no@_local@_from@_check\. + +.index `From' line +White space between \-f-\ and the <<address>> is optional +(that is, they can be given as two arguments or one combined argument). +The sender of a locally-generated message can also be set (when permitted) by +an initial `From ' line in the message -- see the description of \-bm-\ above +-- but if \-f-\ is also present, it overrides `From'. + +.option G +.index Sendmail compatibility||\-G-\ option ignored +This is a Sendmail option which is ignored by Exim. + +.option h #<<number>> +.index Sendmail compatibility||\-h-\ option ignored +This option is accepted for compatibility with Sendmail, but has no effect. (In +Sendmail it overrides the `hop count' obtained by counting ::Received:: +headers.) + +.option i +.index Solaris||\*mail*\ command +.index dot||in incoming, non-SMTP message +This option, which has the same effect as \-oi-\, specifies that a dot on a +line by itself should not terminate an incoming, non-SMTP message. I can find +no documentation for this option in Solaris 2.4 Sendmail, but the \*mailx*\ +command in Solaris 2.4 uses it. See also \-ti-\. + +.option M #<<message id>>#<<message id>> ... +.index forcing delivery +.index delivery||forcing attempt +.index frozen messages||forcing delivery +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. +.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 +been reached. This option requires the caller to be an admin user. However, +there is an option called \prod@_requires@_admin\ which can be set false to +relax this restriction (and also the same requirement for the \-q-\, \-R-\, and +\-S-\ options). + + +.option Mar #<<message id>>#<<address>>#<<address>> ... +.index message||adding recipients +.index recipient||adding +This option requests Exim to add the addresses to the list of recipients of the +message (`ar' for `add recipients'). The first argument must be a message id, +and the remaining ones must be email addresses. However, if the message is +active (in the middle of a delivery attempt), it is not altered. This option +can be used only by an admin user. + +.index SMTP||passed connection +.index SMTP||multiple deliveries +.index multiple SMTP deliveries +.option MC #<<transport>>#<<hostname>>#<<sequence number>>#<<message id>> +This option is not intended for use by external callers. It is used internally +by Exim to invoke another instance of itself to deliver a waiting message using +an existing SMTP connection, which is passed as the standard input. Details are +given in chapter ~~CHAPSMTP. This must be the final option, and the caller must +be root or the Exim user in order to use it. + +.option MCA +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 connection +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 +which Exim is connected supports pipelining. + +.option MCQ #<<process id>> <<pipe fd>> +This option is not intended for use by external callers. It is used internally +by Exim in conjunction with the \-MC-\ option when the original delivery was +started by a queue runner. It passes on the process id of the queue runner, +together with the file descriptor number of an open pipe. Closure of the pipe +signals the final completion of the sequence of processes that are passing +messages through the same SMTP connection. + +.option MCS +This option is not intended for use by external callers. It is used internally +by Exim in conjunction with the \-MC-\ option, and passes on the fact that the +SMTP \\SIZE\\ option should be used on messages delivered down the existing +connection. + +.option MCT +This option is not intended for use by external callers. It is used internally +by Exim in conjunction with the \-MC-\ option, and passes on the fact that the +host to which Exim is connected supports TLS encryption. + +.option Mc #<<message id>>#<<message id>> ... +.index hints database||not overridden by \-Mc-\ +.index delivery||manually started, not forced +This option requests Exim to run a delivery attempt on each message in turn, +but unlike the \-M-\ option, it does check for retry hints, and respects any +that are found. This option is not very useful to external callers. It is +provided mainly for internal use by Exim when it needs to re-invoke itself in +order to regain root privilege for a delivery (see chapter ~~CHAPsecurity). +However, \-Mc-\ can be useful when testing, in order to run a delivery that +respects retry times and other options such as \hold@_domains\ that are +overridden when \-M-\ is used. Such a delivery does not count as a queue run. +If you want to run a specific delivery as if in a queue run, you should use +\-q-\ with a message id argument. A distinction between queue run deliveries +and other deliveries is made in one or two places. + +.option Mes #<<message id>>#<<address>> +.index message||changing sender +.index sender||changing +This option requests Exim to change the sender address in the message to the +given address, which must be a fully qualified address or `<>' (`es' for `edit +sender'). There must be exactly two arguments. The first argument must be a +message id, and the second one an email address. However, if the message is +active (in the middle of a delivery attempt), its status is not altered. This +option can be used only by an admin user. + +.option Mf #<<message id>>#<<message id>> ... +.index freezing messages +.index message||manually freezing +This option requests Exim to mark each listed message as `frozen'. This +prevents any delivery attempts taking place until the message is `thawed', +either manually or as a result of the \auto@_thaw\ configuration option. +However, if any of the messages are active (in the middle of a delivery +attempt), their status is not altered. This option can be used only by an admin +user. + +.option Mg #<<message id>>#<<message id>> ... +.index giving up on messages +.index message||abandoning delivery attempts +.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. +For non-bounce messages, a delivery error message is sent to the sender, +containing the text `cancelled by administrator'. Bounce messages are just +discarded. +This option can be used only by an admin user. + +.option Mmad #<<message id>>#<<message id>> ... +.index delivery||cancelling all +This option requests Exim to mark all the recipient addresses in the messages +as already delivered (`mad' for `mark all delivered'). However, if any message +is active (in the middle of a delivery attempt), its status is not altered. +This option can be used only by an admin user. + +.option Mmd #<<message id>>#<<address>>#<<address>> ... +.index delivery||cancelling by address +.index recipient||removing +.index removing recipients +This option requests Exim to mark the given addresses as already delivered +(`md' for `mark delivered'). The first argument must be a message id, and the +remaining ones must be email addresses. These are matched to recipient +addresses in the message in a case-sensitive manner. If the message is active +(in the middle of a delivery attempt), its status is not altered. This option +can be used only by an admin user. + +.option Mrm #<<message id>>#<<message id>> ... +.index removing messages +.index abandoning mail +.index message||manually discarding +This option requests Exim to remove the given messages from the queue. No +bounce messages are sent; each message is simply forgotten. However, if any of +the messages are active, their status is not altered. This option can be used +only by an admin user or by the user who originally caused the message to be +placed on the queue. + +.option Mt #<<message id>>#<<message id>> ... +.index thawing messages +.index unfreezing messages +.index frozen messages||thawing +.index message||thawing frozen +This option requests Exim to `thaw' any of the listed messages that are +`frozen', so that delivery attempts can resume. However, if any of the messages +are active, their status is not altered. This option can be used only by an +admin user. + +.option Mvb #<<message id>> +.index listing||message body +.index message||listing body of +This option causes the contents of the message body (-D) spool file to be +written to the standard output. This option can be used only by an admin user. + +.option Mvh #<<message id>> +.index listing||message headers +.index header lines||listing +.index message||listing header lines +This option causes the contents of the message headers (-H) spool file to be +written to the standard output. This option can be used only by an admin user. + +.option Mvl #<<message id>> +.index listing||message log +.index message||listing message log +This option causes the contents of the message log spool file to be written to +the standard output. This option can be used only by an admin user. + +.option m +This is apparently a synonym for \-om-\ that is accepted by Sendmail, so Exim +treats it that way too. + +.option N +.index debugging||\-N-\ option +.index debugging||suppressing delivery +This is a debugging option that inhibits delivery of a message at the transport +level. It implies \-v-\. Exim goes through many of the motions of delivery -- +it just doesn't actually transport the message, but instead behaves as if it +had successfully done so. However, it does not make any updates to the retry +database, and the log entries for deliveries are flagged with `$*$>' rather +than `=>'. + +Because \-N-\ discards any message to which it applies, only root or the Exim +user are allowed to use it with \-bd-\, \-q-\, \-R-\ or \-M-\. In other words, +an ordinary user can use it only when supplying an incoming message to which it +will apply. Although transportation never fails when \-N-\ is set, an address +may be deferred because of a configuration problem on a transport, or a routing +problem. Once \-N-\ has been used for a delivery attempt, it sticks to the +message, and applies to any subsequent delivery attempts that may happen for +that message. + +.option n +.index Sendmail compatibility||\-n-\ option ignored +This option is interpreted by Sendmail to mean `no aliasing'. It is ignored by +Exim. + +.option O #<<data>> +This option is interpreted by Sendmail to mean `set option`. It is ignored by +Exim. + +.option oA #<<file name>> +.index Sendmail compatibility||\-oA-\ option +This option is used by Sendmail in conjunction with \-bi-\ to specify an +alternative alias file name. Exim handles \-bi-\ differently; see the +description above. + +.index SMTP||passed connection +.option oB #<<n>> +.index SMTP||multiple deliveries +.index multiple SMTP deliveries +This is a debugging option which limits the maximum number of messages that can +be delivered down one SMTP connection, overriding the value set in any \%smtp%\ +transport. If <<n>> is omitted, the limit is set to 1. + +.option odb +.index background delivery +.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. + +If one of the queueing options in the configuration file +(\queue@_only\ or \queue@_only@_file\, for example) is in effect, \-odb-\ +overrides it if \queue@_only@_override\ is set true, which is the default +setting. If \queue@_only@_override\ is set false, \-odb-\ has no effect. + +.option odf +.index foreground delivery +.index delivery||in the foreground +This option requests `foreground' (synchronous) delivery when Exim has accepted +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 +false and one of the queueing options in the configuration file is in effect. + +.option odi +This option is synonymous with \-odf-\. It is provided for compatibility with +Sendmail. + +.option odq +.index non-immediate delivery +.index delivery||suppressing immediate +.index queueing incoming messages +This option applies to all modes in which Exim accepts incoming messages, +including the listening daemon. It specifies that the accepting process should +not automatically start a delivery process for each message received. Messages +are placed on the queue, and remain there until a subsequent queue runner +process encounters them. +There are several configuration options (such as \queue@_only\) that can be +used to queue incoming messages under certain conditions. This option overrides +all of them and also \-odqs-\. It always forces queueing. + +.option odqs +.index SMTP||delaying delivery +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. + +When \-odqs-\ does operate, a delivery process is started for each incoming +message, in the background by default, but in the foreground if \-odi-\ is also +present. +The recipient addresses are routed, and local deliveries are done in the normal +way. However, if any SMTP deliveries are required, they are not done at this +time, so the message remains on the queue until a subsequent queue runner +process encounters it. Because routing was done, Exim knows which messages are +waiting for which hosts, and so a number of messages for the same host can be +sent in a single SMTP connection. The \queue@_smtp@_domains\ configuration +option has the same effect for specific domains. See also the \-qq-\ option. + +.option oee +.index error||reporting +If an error is detected while a non-SMTP message is being received (for +example, a malformed address), the error is reported to the sender in a mail +message. +.index return code||for \-oee-\ +Provided this error message is successfully sent, the Exim receiving process +exits with a return code of zero. If not, the return code is 2 if the problem +is that the original message has no recipients, or 1 any other error. This is +the default \-oe$it{x}-\ option if Exim is called as \*rmail*\. + +.option oem +.index error||reporting +.index return code||for \-oem-\ +This is the same as \-oee-\, except that Exim always exits with a non-zero +return code, whether or not the error message was successfully sent. +This is the default \-oe$it{x}-\ option, unless Exim is called as \*rmail*\. + +.option oep +.index error||reporting +If an error is detected while a non-SMTP message is being received, the +error is reported by writing a message to the standard error file (stderr). +.index return code||for \-oep-\ +The return code is 1 for all errors. + +.option oeq +.index error||reporting +This option is supported for compatibility with Sendmail, but has the same +effect as \-oep-\. + +.option oew +.index error||reporting +This option is supported for compatibility with Sendmail, but has the same +effect as \-oem-\. + +.option oi +.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 +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 +This option is treated as synonymous with \-oi-\. + +.option oMa #<<host address>> +.index sender||host address, specifying for local message +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-\, +\-be-\, +\-bf-\, \-bF-\, \-bt-\, or \-bv-\ testing options. In other circumstances, they +are ignored unless the caller is trusted. + +The \-oMa-\ option sets the sender host address. This may include a port number +at the end, after a full stop (period). For example: +.display asis +exim -bs -oMa 10.9.8.7.1234 +.endd +An alternative syntax is to enclose the IP address in square brackets, followed +by a colon and the port number: +.display asis +exim -bs -oMa [10.9.8.7]:1234 +.endd +The IP address is placed in the \$sender@_host@_address$\ variable, and the +port, if present, in \$sender@_host@_port$\. + +.option oMaa #<<name>> +.index authentication||name, specifying for local message +See \-oMa-\ above for general remarks about the \-oM-\ options. The \-oMaa-\ +option sets the value of \$sender@_host@_authenticated$\ (the authenticator +name). See chapter ~~CHAPSMTPAUTH for a discussion of SMTP authentication. + +.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 +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 +ids. + +.option oMas #<<address>> +.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$\. +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. + +.option oMi #<<interface address>> +.index interface||address, specifying for local message +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, +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 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 +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$\. +The default setting for local callers is the login id of the calling process. + +.option om +.index Sendmail compatibility||\-om-\ option ignored +In Sendmail, this option means `me too', indicating that the sender of a +message should receive a copy of the message if the sender appears in an alias +expansion. Exim always does this, so the option does nothing. + +.option oo +.index Sendmail compatibility||\-oo-\ option ignored +This option is ignored. In Sendmail it specifies `old style headers', whatever +that means. + +.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 +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, +because in those cases, the normal pid file is not used. + +.option or #<<time>> +.index timeout||for non-SMTP input +This option sets a timeout value for incoming non-SMTP messages. If it is not +set, Exim will wait forever for the standard input. The value can also be set +by the \receive@_timeout\ option. The format used for specifying times is +described in section ~~SECTtimeformat. + +.option os #<<time>> +.index timeout||for SMTP input +.index SMTP||timeout, input +This option sets a timeout value for incoming SMTP messages. The timeout +applies to each SMTP command and block of data. The value can also be set by +the \smtp@_receive@_timeout\ option; it defaults to 5 minutes. The format used +for specifying times is described in section ~~SECTtimeformat. + +.option ov +This option has exactly the same effect as \-v-\. + +.option oX #<<number or string>> +.index TCP/IP||setting listening ports +.index TCP/IP||setting listening interfaces +.index port||receiving TCP/IP +This option is relevant only when the \-bd-\ (start listening daemon) option is +also given. It controls which ports and interfaces the daemon uses. Details of +the syntax, and how it interacts with configuration file options, are given in +chapter ~~CHAPinterfaces. When \-oX-\ is used to start a daemon, no pid file is +written unless \-oP-\ is also present to specify a pid file name. + +.option pd +.index Perl||starting the interpreter +This option applies when an embedded Perl interpreter is linked with Exim (see +chapter ~~CHAPperl). It overrides the setting of the \perl@_at@_start\ option, +forcing the starting of the interpreter to be delayed until it is needed. + +.option ps +.index Perl||starting the interpreter +This option applies when an embedded Perl interpreter is linked with Exim (see +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 +-oMr <<rval>> -oMs <<sval>> +.endd +It sets the incoming protocol and host name (for trusted callers). The +host name and its colon can be omitted when only the protocol is to be set. +Note the Exim already has two private options, \-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 +This option is normally restricted to admin users. However, there is a +configuration option called \prod@_requires@_admin\ which can be set false to +relax this restriction (and also the same requirement for the \-M-\, \-R-\, and +\-S-\ options). + +.index queue runner||description of operation +The \-q-\ option starts one queue runner process. This scans the queue of +waiting messages, and runs a delivery process for each one in turn. It waits +for each delivery process to finish before starting the next one. A delivery +process may not actually do any deliveries if the retry times for the addresses +have not been reached. Use \-qf-\ (see below) if you want to override this. +.index SMTP||passed connection +.index SMTP||multiple deliveries +.index multiple SMTP deliveries +If the delivery process spawns other processes to deliver other messages down +passed SMTP connections, the queue runner waits for these to finish before +proceeding. + +When all the queued messages have been considered, the original queue runner +process terminates. In other words, a single pass is made over the waiting +mail, one message at a time. Use \-q-\ with a time (see below) if you want this +to be repeated periodically. + +Exim processes the waiting messages in an unpredictable order. It isn't very +random, but it is likely to be different each time, which is all that matters. +If one particular message screws up a remote MTA, other messages to the same +MTA have a chance of getting through if they get tried first. + +It is possible to cause the messages to be processed in lexical message id +order, which is essentially the order in which they arrived, by setting the +\queue@_run@_in@_order\ option, but this is not recommended for normal use. + +.option q <<qflags>> +The \-q-\ option may be followed by one or more flag letters that change its +behaviour. They are all optional, but if more than one is present, they must +appear in the correct order. Each flag is described in a separate item below. + +.option qq... +.index queue||double scanning +.index queue||routing +.index routing||whole queue before delivery +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. +.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 +deferred. After this is complete, a second, normal queue scan happens, with +routing and delivery taking place as normal. Messages that are routed to the +same host should mostly be delivered down a single SMTP +.index SMTP||passed connection +.index SMTP||multiple deliveries +.index multiple SMTP deliveries +connection because of the hints that were set up during the first queue scan. +This option may be useful for hosts that are connected to the Internet +intermittently. + +.option q[q]i... +.index queue||initial delivery +If the \*i*\ flag is present, the queue runner runs delivery processes only for +those messages that haven't previously been tried. (\*i*\ stands for `initial +delivery'.) This can be helpful if you are putting messages on the queue using +\-odq-\ and want a queue runner just to process the new messages. + +.option q[q][i]f... +.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 +their retry times are tried. + +.option q[q][i]ff... +.index frozen messages||forcing delivery +If \*ff*\ is present, a delivery attempt is forced for every message, whether +frozen or not. + +.option q[q][i][f[f]]l +.index queue||local deliveries only +The \*l*\ (the letter `ell') flag specifies that only local deliveries are to be +done. If a message requires any remote deliveries, it remains on the queue for +later delivery. + +.option q <<qflags>>#<<start id>>#<<end id>> +.index queue||delivering specific messages +When scanning the queue, Exim can be made to skip over messages whose ids are +lexically less than a given value by following the \-q-\ option with a starting +message id. For example: +.display +exim -q 0t5C6f-0000c8-00 +.endd +Messages that arrived earlier than \"0t5C6f-0000c8-00"\ are not inspected. If a +second message id is given, messages whose ids are lexically greater than it +are also skipped. If the same id is given twice, for example, +.display +exim -q 0t5C6f-0000c8-00 0t5C6f-0000c8-00 +.endd +just one delivery process is started, for that message. This differs from \-M-\ +in that retry data is respected, and it also differs from \-Mc-\ in that it +counts as a delivery from a queue run. Note that the selection mechanism does +not affect the order in which the messages are scanned. There are also other +ways of selecting specific sets of messages for delivery in a queue run -- see +\-R-\ and \-S-\. + +.option q <<qflags>><<time>> +.index queue runner||starting periodically +.index periodic queue running +When a time value is present, the \-q-\ option causes Exim to run as a daemon, +starting a queue runner process at intervals specified by the given time value +(whose format is described in section ~~SECTtimeformat). This form of the \-q-\ +option is commonly combined with the \-bd-\ option, in which case a single +daemon process handles both functions. A common way of starting up a combined +daemon at system boot time is to use a command such as +.display +/usr/exim/bin/exim -bd -q30m +.endd +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 +file is written unless one is explicitly requested by the \-oP-\ option. + +.option qR <<rsflags>>#<<string>> +This option is synonymous with \-R-\. It is provided for Sendmail +compatibility. + +.option qS <<rsflags>>#<<string>> +This option is synonymous with \-S-\. + +.option R <<rsflags>>#<<string>> +.index queue runner||for specific recipients +.index delivery||to given domain +.index domain||delivery to +The <<rsflags>> may be empty, in which case the white space before the string +is optional, unless the string is \*f*\, \*ff*\, \*r*\, \*rf*\, or \*rff*\, +which are the possible values for <<rsflags>>. White space is required if +<<rsflags>> is not empty. + +This option is similar to \-q-\ with no time value, that is, it causes Exim to +perform a single queue run, except that, when scanning the messages on the +queue, Exim processes only those that have at least one undelivered recipient +address containing the given string, which is checked in a case-independent +way. If the <<rsflags>> start with \*r*\, <<string>> is interpreted as a regular +expression; otherwise it is a literal string. + +Once a message is selected, all its addresses are processed. For the first +selected message, Exim overrides any retry information and forces a delivery +attempt for each undelivered address. This means that if delivery of any +address in the first message is successful, any existing retry information is +deleted, and so delivery attempts for that address in subsequently selected +messages (which are processed without forcing) will run. However, if delivery +of any address does not succeed, the retry information is updated, and in +subsequently selected messages, the failing address will be skipped. + +If the <<rsflags>> contain \*f*\ or \*ff*\, the delivery forcing applies to all +selected messages, not just the first; +.index frozen messages||forcing delivery +frozen messages are included when \*ff*\ is present. + +The \-R-\ option makes it straightforward to initiate delivery of all messages +to a given domain after a host has been down for some time. When the SMTP +command \\ETRN\\ is accepted by its ACL (see chapter ~~CHAPACL), its default +effect is to run Exim with the \-R-\ option, but it can be configured to run an +arbitrary command instead. + +.option r +This is a documented (for Sendmail) obsolete alternative name for \-f-\. + +.index delivery||from given sender +.option S <<rsflags>>#<<string>> +.index queue runner||for specific senders +This option acts like \-R-\ except that it checks the string against each +message's sender instead of against the recipients. If \-R-\ is also set, both +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 + +.option t +.index recipient||extracting from header lines +.index ::Bcc:: header line +.index ::Cc:: header line +.index ::To:: header line +When Exim is receiving a locally-generated, non-SMTP message on its standard +input, the \-t-\ option causes the recipients of the message to be obtained +from the ::To::, ::Cc::, and ::Bcc:: header lines in the message instead of from +the command arguments. The addresses are extracted before any rewriting takes +place. + +.index Sendmail compatibility||\-t-\ option +If the command has any arguments, they specify addresses to which the message +is $it{not} to be delivered. That is, the argument addresses are removed from +the recipients list obtained from the headers. This is compatible with Smail 3 +and in accordance with the documented behaviour of several versions of +Sendmail, as described in man pages on a number of operating systems (e.g. +Solaris 8, IRIX 6.5, HP-UX 11). However, some versions of Sendmail $it{add} +argument addresses to those obtained from the headers, and the O'Reilly +Sendmail book documents it that way. Exim can be made to add argument addresses +instead of subtracting them by setting the option +\extract__addresses__remove__arguments\ false. + +If a ::Bcc:: header line is present, it is removed from the message unless +there is no ::To:: or ::Cc::, in which case a ::Bcc:: line with no data is +created. This is necessary for conformity with the original RFC 822 standard; +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 +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 +\-t-\ was used in conjunction with \Resent@-\ header lines.) + +RFC 2822 talks about different sets of \Resent@-\ header lines (for when a +message is resent several times). The RFC also specifies that they should be +added at the front of the message, and separated by ::Received:: lines. It is +not at all clear how \-t-\ should operate in the present of multiple sets, +nor indeed exactly what constitutes a `set'. +In practice, it seems that MUAs do not follow the RFC. The \Resent@-\ lines are +often added at the end of the header, and if a message is resent more than +once, it is common for the original set of \Resent@-\ headers to be renamed as +\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 +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. + +.option U +.index Sendmail compatibility||\-U-\ option ignored +Sendmail uses this option for `initial message submission', and its +documentation states that in future releases, it may complain about +syntactically invalid messages rather than fixing them when this flag is not +set. Exim ignores this option. + +.option v +This option causes Exim to write information to the standard error stream, +describing what it is doing. In particular, it shows the log lines for +receiving and delivering a message, and if an SMTP connection is made, the SMTP +dialogue is shown. Some of the log lines shown may not actually be written to +the log if the setting of \log@_selector\ discards them. Any relevant selectors +are shown with each log line. If none are shown, the logging is unconditional. + +.option x +AIX uses \-x-\ for a private purpose (`mail from a local mail program has +National Language Support extended characters in the body of the mail item'). +It sets \-x-\ when calling the MTA from its \mail\ command. Exim ignores this +option. + +.endoptions + + + +. +. +. +. +. ============================================================================ +.chapter The Exim run time configuration file +.set runningfoot "configuration file" +.rset CHAPconf ~~chapter + +.index run time configuration +.index configuration file||general description +.index \\CONFIGURE@_FILE\\ +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 +control. + +The name of the configuration file is compiled into the binary for security +reasons, and is specified by the \\CONFIGURE@_FILE\\ compilation option. In +most configurations, this specifies a single file. However, it is permitted to +give a colon-separated list of file names, in which case Exim uses the first +existing file in the list. + +.index \\EXIM@_USER\\ +.index \\EXIM@_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, +.em +or by the user that is specified at compile time by the \\CONFIGURE@_OWNER\\ +option (if set). +.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 +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. + + +.section Using a different configuration file +.index configuration file||alternate +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 +\\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 privileged use of \-C-\ by the Exim user can be locked out by setting +\\ALT@_CONFIG@_ROOT@_ONLY\\ in \(Local/Makefile)\ when building Exim. However, +if you do this, you also lock 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 +\-odq-\, and another to do the delivery, using \-M-\). + +If \\ALT@_CONFIG@_PREFIX\\ is defined \(in Local/Makefile)\, it specifies a +prefix string with which any file named in a \-C-\ command line option must +start. In addition, the file name must not contain the sequence \"/../"\. There +is no default setting for \\ALT@_CONFIG@_PREFIX\\; when it is unset, any file +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 +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 +completely disabled, and its use causes an immediate error exit. + +Some sites may wish to use the same Exim binary on different machines that +share a file system, but to use different configuration files on each machine. +If \\CONFIGURE@_FILE@_USE@_NODE\\ is defined in \(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 +each file name in the list given by \\CONFIGURE@_FILE\\ or \-C-\. + +In some esoteric situations different versions of Exim may be run under +different effective uids and the \\CONFIGURE@_FILE@_USE@_EUID\\ is defined to +help with this. See the comments in \(src/EDITME)\ for details. + + +.section Configuration file format +.rset SECTconffilfor "~~chapter.~~section" +.index configuration file||format of +.index format||configuration file +Exim's configuration file is divided into a number of different parts. General +option settings must always appear at the start of the file. The other parts +are all optional, and may appear in any order. Each part other than the first +is introduced by the word `begin' followed by the name of the part. The +optional parts are: + +.numberpars $. +\*ACL*\: Access control lists for controlling incoming SMTP mail. +.nextp +.index \\AUTH\\||configuration +\*authenticators*\: Configuration settings for the authenticator drivers. These +are concerned with the SMTP \\AUTH\\ command (see chapter ~~CHAPSMTPAUTH). +.nextp +\*routers*\: Configuration settings for the router drivers. Routers process +addresses and determine how the message is to be delivered. +.nextp +\*transports*\: Configuration settings for the transport drivers. Transports +define mechanisms for copying messages to destinations. +.nextp +\*retry*\: Retry rules, for use when a message cannot be immediately delivered. +.nextp +\*rewrite*\: Global address rewriting rules, for use when a message arrives and +when new addresses are generated during delivery. +.nextp +\*local@_scan*\: Private options for the \*local@_scan()*\ function. If you +want to use this feature, you must set +.display asis +LOCAL_SCAN_HAS_OPTIONS=yes +.endd +in \(Local/Makefile)\ before building Exim. Full details of the +\*local@_scan()*\ facility are given in chapter ~~CHAPlocalscan. +.endp +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. +Comment lines beginning with @# (but not empty lines) may appear in the middle +of a sequence of continuation lines. + +A convenient way to create a configuration file is to start from the +default, which is supplied in \(src/configure.default)\, and add, delete, or +change settings as required. + +The ACLs, retry rules, and rewriting rules have their own syntax which is +described in chapters ~~CHAPACL, ~~CHAPretry, and ~~CHAPrewrite, respectively. +The other parts of the configuration file have some syntactic items in common, +and these are described below, from section ~~SECTcos onwards. Before that, the +inclusion, macro, and conditional facilities are described. + + +.section File inclusions in the configuration file +.index inclusions in configuration file +.index configuration file||including other files +.index .include in configuration file +.index .include@_if@_exists in configuration file +You can include other files inside Exim's run time configuration file by +using this syntax: +.display +@.include <<file name>> +.endd +or +.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 +second form does nothing for non-existent files. + +Includes may be nested to any depth, but remember that Exim reads its +configuration file often, so it is a good idea to keep them to a minimum. +If you change the contents of an included file, you must HUP the daemon, +because an included file is read only when the configuration itself is read. + +The processing of inclusions happens early, at a physical line level, so, like +comment lines, an inclusion can be used in the middle of an option setting, +for example: +.display asis +hosts_lookup = a.b.c \ + .include /some/file +.endd +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. + + +.section Macros in the configuration file +.rset SECTmacrodefs "~~chapter.~~section" +.index macro||description of +.index configuration file||macros +If a line in the main part of the configuration (that is, before the first +`begin' line) begins with an upper case letter, it is taken as a macro +definition, and must be of the form +.display +<<name>> = <<rest of line>> +.endd +The name must consist of letters, digits, and underscores, and need not all be +in upper case, though that is recommended. The rest of the line, including any +continuations, is the replacement text, and has leading and trailing white +space removed. Quotes are not removed. The replacement text can never end with +a backslash character, but this doesn't seem to be a serious limitation. + +Once a macro is defined, all subsequent lines in the file (and any included +files) are scanned for the macro name; if there are several macros, the line is +scanned for each in turn, in the order in which they are defined. The +replacement text is not re-scanned for the current macro, though it is scanned +for subsequently defined macros. For this reason, a macro name may not contain +the name of a previously defined macro as a substring. You could, for example, +define +.display asis +ABCD_XYZ = <<something>> +ABCD = <<something else>> +.endd +but putting the definitions in the opposite order would provoke a configuration +error. + +Macro expansion is applied to individual lines from the file, before checking +for line continuation or file inclusion (see below). If a line consists solely +of a macro name, and the expansion of the macro is empty, the line is ignored. +A macro at the start of a line may turn the line into a comment line or a +\".include"\ line. + +As an example of macro usage, consider a configuration where aliases are looked +up in a MySQL database. It helps to keep the file less cluttered if long +strings such as SQL statements are defined separately as macros, for example: +.display asis +ALIAS_QUERY = select mailbox from user where \ + login=${quote_mysql:$local_part}; +.endd +This can then be used in a \%redirect%\ router setting like this: +.display asis +data = ${lookup mysql{ALIAS_QUERY}} +.endd +In earlier versions of Exim macros were sometimes used for domain, host, or +address lists. In Exim 4 these are handled better by named lists -- see section +~~SECTnamedlists. + +Macros in the configuration file can be overridden by the \-D-\ command line +option, but Exim gives up its root privilege when \-D-\ is used, unless called +by root or the Exim user. + + +.section Conditional skips in the configuration file +.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). + +The implementation is very simple. Instances of the first four directives must +be followed by text that includes the names of one or macros. The condition +that is tested is whether or not any macro substitution has taken place in the +line. Thus: +.display +@.ifdef AAA +message@_size@_limit = 50M +@.else +message@_size@_limit = 100M +@.endif +.endd +sets a message size limit of 50M if the macro \"AAA"\ is defined, and 100M +otherwise. If there is more than one macro named on the line, the condition +is true if any of them are defined. That is, it is an `or' condition. To +obtain an `and' condition, you need to use nested \".ifdef"\s. + +Although you can use a macro expansion to generate one of these directives, +it is not very useful, because the condition `there was a macro substitution +in this line' will always be true. + +Text following \".else"\ and \".endif"\ is ignored, and can be used as comment +to clarify complicated nestings. + + +.section Common option syntax +.rset SECTcos "~~chapter.~~section" +.index common option syntax +.index syntax of common options +.index configuration file||common option syntax +For the main set of options, driver options, and \*local@_scan()*\ options, +each setting is on a line by itself, and starts with a name consisting of +lower-case letters and underscores. Many options require a data value, and in +these cases the name must be followed by an equals sign (with optional white +space) and then the value. For example: +.display asis +qualify_domain = mydomain.example.com +.endd +Some option settings may contain sensitive data, for example, passwords for +accessing databases. To stop non-admin users from using the \-bP-\ command line +option to read these values, you can precede the option settings with the word +`hide'. For example: +.display asis +hide mysql_servers = localhost/users/admin/secret-password +.endd +For non-admin users, such options are displayed like this: +.display asis +mysql_servers = <value not displayable> +.endd +If `hide' is used on a driver option, it hides the value of that option on all +instances of the same driver. + +The following sections describe the syntax used for the different data types +that are found in option settings. + +.section Boolean options +.index format||boolean +.index boolean configuration values +Options whose type is given as boolean are on/off switches. There are two +different ways of specifying such options: with and without a data value. If +the option name is specified on its own without data, the switch is turned on; +if it is preceded by `no@_' or `not@_' the switch is turned off. However, +boolean options may optionally be followed by an equals sign and one of the +words `true', `false', `yes', or `no', as an alternative syntax. For example, +the following two settings have exactly the same effect: +.display asis +queue_only +queue_only = true +.endd +The following two lines also have the same (opposite) effect: +.display asis +no_queue_only +queue_only = false +.endd +You can use whichever syntax you prefer. + + + +.section Integer values +.index integer configuration values +.index format||integer +If an integer data item starts with the characters `0x', the remainder of it +is interpreted as a hexadecimal number. Otherwise, it is treated as octal if it +starts with the digit 0, and decimal if not. If an integer value is followed by +the letter K, it is multiplied by 1024; if it is followed by the letter M, it +is multiplied by 1024x1024. + +When the values of integer option settings are output, values which are an +exact multiple of 1024 or 1024x1024 are +sometimes, but not always, +printed using the letters K and M. The printing style is independent of the +actual input format that was used. + +.section Octal integer values +.index integer format +.index format||octal integer +The value of an option specified as an octal integer is always interpreted in +octal, whether or not it starts with the digit zero. Such options are always +output in octal. + + +.section Fixed point number values +.index fixed point configuration values +.index format||fixed point +A fixed point number consists of a decimal integer, optionally followed by a +decimal point and up to three further digits. + + +.section Time interval values +.index time interval||specifying in configuration +.index format||time interval +.rset SECTtimeformat "~~chapter.~~section" +A time interval is specified as a sequence of numbers, each followed by one of +the following letters, with no intervening white space: +.display rm +.tabs 5 +\s\ $t seconds +\m\ $t minutes +\h\ $t hours +\d\ $t days +\w\ $t weeks +.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 +specify `90m' instead of `1h30m'. + + +.section String values +.index string||format of configuration values +.index format||string +.rset SECTstrings "~~chapter.~~section" +If a string data item does not start with a double-quote character, it is taken +as consisting of the remainder of the line plus any continuation lines, +starting at the first character after any leading white space, with trailing +white space characters removed, and with no interpretation of the characters in +the string. Because Exim removes comment lines (those beginning with @#) at an +early stage, they can appear in the middle of a multi-line string. The +following settings are therefore equivalent: +.display asis +trusted_users = uucp:mail + +trusted_users = uucp:\ + # This comment line is ignored + mail +.endd +.index string||quoted +.index escape characters in quoted strings +If a string does start with a double-quote, it must end with a closing +double-quote, and any backslash characters other than those used for line +continuation are interpreted as escape characters, as follows: +.display +.tabs 15 +@\@\ $t $rm{single backslash} +@\n $t $rm{newline} +@\r $t $rm{carriage return} +@\t $t $rm{tab} +@\<<octal digits>> $t $rm{up to 3 octal digits specify one character} +@\x<<hex digits>> $t $rm{up to 2 hexadecimal digits specify one character} +.endd +If a backslash is followed by some other character, including a double-quote +character, that character replaces the pair. + +Quoting is necessary only if you want to make use of the backslash escapes to +insert special characters, or if you need to specify a value with leading or +trailing spaces. These cases are rare, so quoting is almost never needed in +current versions of Exim. In versions of Exim before 3.14, quoting was required +in order to continue lines, so you may come across older configuration files +and examples that apparently quote unnecessarily. + +.section Expanded strings +.index string||expansion, definition of +.index expansion||definition of +Some strings in the configuration file are subjected to \*string expansion*\, +by which means various parts of the string may be changed according to the +circumstances (see chapter ~~CHAPexpand). The input syntax for such strings is +as just described; in particular, the handling of backslashes in quoted strings +is done as part of the input process, before expansion takes place. However, +backslash is also an escape character for the expander, so any backslashes that +are required for that reason must be doubled if they are within a quoted +configuration string. + +.section User and group names +.index user name||format of +.index format||user name +.index group||name format +.index format||group name +User and group names are specified as strings, using the syntax described +above, but the strings are interpreted specially. A user or group name must +either consist entirely of digits, or be a name that can be looked up using the +\*getpwnam()*\ or \*getgrnam()*\ function, as appropriate. + +.section List construction +.index list||syntax of in configuration +.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. + +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 +~~SECTstrings above is an example. If a colon is actually needed in an item in +a list, it must be entered as two colons. Leading and trailing white space on +each item in a list is ignored. This makes it possible to include items that +start with a colon, and in particular, certain forms of IPv6 address. For +example, the list +.display asis +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. +.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: +.display asis +local_interfaces = <; 127.0.0.1 ; ::1 +.endd +This facility applies to all lists, with the exception of the list in +\log@_file@_path\. It is recommended that the use of non-colon separators be +confined to circumstances where they really are needed. + + +.section Format of driver configurations +.rset SECTfordricon "~~chapter.~~section" +.index drivers||configuration format +There are separate parts in the configuration for defining routers, transports, +and authenticators. In each part, you are defining a number of driver +instances, each with its own set of options. Each driver instance is defined by +a sequence of lines like this: +.display +<<instance name>>: + <<option>> + ... + <<option>> +.endd +In the following example, the instance name is \%localuser%\, and it is +followed by three options settings: +.display asis +localuser: + driver = accept + check_local_user + transport = local_delivery +.endd +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 +you would use the \%appendfile%\ driver. Each of the drivers is described in +detail in its own separate chapter later in this manual. + +You can have several routers, transports, or authenticators that are based on +the same underlying driver (each must have a different name). + +The order in which routers are defined is important, because addresses are +passed to individual routers one by one, in order. The order in which +transports are defined does not matter at all. The order in which +authenticators are defined is used only when Exim, as a client, is searching +them to find one that matches an authentication mechanism offered by the +server. + +.index generic options +.index options||generic, definition of +Within a driver instance definition, there are two kinds of option: +$it{generic} and $it{private}. The generic options are those that apply to all +drivers of the same type (that is, all routers, all transports or all +authenticators). +The \driver\ option is a generic option that must appear in every definition. +.index private options +The private options are special for each driver, and none need appear, because +they all have default values. + +The options may appear in any order, except that the \driver\ option must +precede any private options, since these depend on the particular driver. For +this reason, it is recommended that \driver\ always be the first option. + +Driver instance names, which are used for reference in log entries and +elsewhere, can be any sequence of letters, digits, and underscores (starting +with a letter) and must be unique among drivers of the same type. A router and +a transport (for example) can each have the same name, but no two router +instances can have the same name. The name of a driver instance should not be +confused with the name of the underlying driver module. For example, the +configuration lines: +.display asis +remote_smtp: + driver = smtp +.endd +create an instance of the \%smtp%\ transport driver whose name is +\%remote@_smtp%\. The same driver code can be used more than once, with +different instance names and different option settings each time. A second +instance of the \%smtp%\ transport, with different options, might be defined +thus: +.display asis +special_smtp: + driver = smtp + port = 1234 + command_timeout = 10s +.endd +The names \%remote@_smtp%\ and \%special@_smtp%\ would be used to reference +these transport instances from routers, and these names would appear in log +lines. + +Comment lines may be present in the middle of driver specifications. The full +list of option settings for any particular driver instance, including all the +defaulted values, can be extracted by making use of the \-bP-\ command line +option. + + + + + + +. +. +. +. +. ============================================================================ +.chapter The default configuration file +.set runningfoot "default configuration" +.rset CHAPdefconfil "~~chapter" +.index configuration file||default, `walk through' +.index default||configuration file `walk through' +The default configuration file supplied with Exim as \(src/configure.default)\ +is sufficient for a host with simple mail requirements. As an introduction to +the way Exim is configured, this chapter `walks through' the default +configuration, giving brief explanations of the settings. Detailed descriptions +of the options are given in subsequent chapters. The default configuration file +itself contains extensive comments about ways you might want to modify the +initial settings. However, note that there are many options that are not +mentioned at all in the default configuration. + + +.section Main configuration settings +The main (global) configuration option settings must always come first in the +file. The first thing you'll see in the file, after some initial comments, is +the line +.display asis +# primary_hostname = +.endd +This is a commented-out setting of the \primary@_hostname\ option. Exim needs +to know the official, fully qualified name of your host, and this is where you +can specify it. However, in most cases you do not need to set this option. When +it is unset, Exim uses the \*uname()*\ system function to obtain the host name. + +The first three non-comment configuration lines are as follows: +.display asis +domainlist local_domains = @ +domainlist relay_to_domains = +hostlist relay_from_hosts = 127.0.0.1 +.endd +These are not, in fact, option settings. They are definitions of two named +domain lists and one named host list. Exim allows you to give names to lists of +domains, hosts, and email addresses, in order to make it easier to manage the +configuration file (see section ~~SECTnamedlists). + +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. +.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 +called \*a.host.example*\, mail to \*any.user@@a.host.example*\ is expected to +be delivered locally. Because the local host's name is referenced indirectly, +the same configuration file can be used on different hosts. + +The second line defines a domain list called \*relay@_to@_domains*\, but the +list itself is empty. Later in the configuration we will come to the part that +controls mail relaying through the local host; it allows relaying to any +domains in this list. By default, therefore, no relaying on the basis of a mail +domain is permitted. + +The third line defines a host list called \*relay@_from@_hosts*\. This list is +used later in the configuration to permit relaying from any host or IP address +that matches the list. The default contains just the IP address of the IPv4 +loopback interface, which means that processes on the local host are able to +submit mail for relaying by sending it over TCP/IP to that interface. No other +hosts are permitted to submit messages for relaying. + +Just to be sure there's no misunderstanding: at this point in the configuration +we aren't actually setting up any controls. We are just defining some domains +and hosts that will be used in the controls that are specified later. + +The next configuration line is a genuine option setting: +.display asis +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 +\\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 +configuration does not provide an ACL to check recipients, no SMTP mail can be +accepted. + +Two commented-out options settings are next: +.display asis +# qualify_domain = +# qualify_recipient = +.endd +The first of these specifies a domain that Exim uses when it constructs a +complete email address from a local login name. This is often needed when Exim +receives a message from a local process. If you do not set \qualify@_domain\, +the value of \primary@_hostname\ is used. If you set both of these options, you +can have different qualification domains for sender and recipient addresses. If +you set only the first one, its value is used in both cases. + +.index domain literal||recognizing format +The following line must be uncommented if you want Exim to recognize +addresses of the form \*user@@[10.11.12.13]*\ that is, with a `domain literal' +(an IP address) instead of a named domain. +.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 +\*postmaster*\) where domain literals are still useful. +.nem + +The next configuration line is a kind of trigger guard: +.display asis +never_users = root +.endd +It specifies that no delivery must ever be run as the root user. The normal +convention is to set up \*root*\ as an alias for the system administrator. This +setting is a guard against slips in the configuration. +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 +\\FIXED@_NEVER@_USERS\\ also specifies root. + +When a remote host connects to Exim in order to send mail, the only information +Exim has about the host's identity is its IP address. The next configuration +line, +.display asis +host_lookup = * +.endd +specifies that Exim should do a reverse DNS lookup on all incoming connections, +in order to get a host name. This improves the quality of the logging +information, but if you feel it is too expensive, you can remove it entirely, +or restrict the lookup to hosts on `nearby' networks. +Note that it is not always possible to find a host name from an IP address, +because not all DNS reverse zones are maintained, and sometimes DNS servers are +unreachable. + +The next two lines are concerned with \*ident*\ callbacks, as defined by RFC +1413 (hence their names): +.display asis +rfc1413_hosts = * +rfc1413_query_timeout = 30s +.endd +These settings cause Exim to make ident callbacks for all incoming SMTP calls. +You can limit the hosts to which these calls are made, or change the timeout +that is used. If you set the timeout to zero, all ident calls are disabled. +Although they are cheap and can provide useful information for tracing problem +messages, some hosts and firewalls have problems with ident calls. This can +result in a timeout instead of an immediate refused connection, leading to +delays on starting up an incoming SMTP session. + +When Exim receives messages over SMTP connections, it expects all addresses to +be fully qualified with a domain, as required by the SMTP definition. However, +if you are running a server to which simple clients submit messages, you may +find that they send unqualified addresses. The two commented-out options: +.display asis +# sender_unqualified_hosts = +# recipient_unqualified_hosts = +.endd +show how you can specify hosts that are permitted to send unqualified sender +and recipient addresses, respectively. + +The \percent@_hack@_domains\ option is also commented out: +.display asis +# percent_hack_domains = +.endd +It provides a list of domains for which the `percent hack' is to operate. This +is an almost obsolete form of explicit email routing. If you do not know +anything about it, you can safely ignore this topic. + +The last two settings in the main part of the default configuration are +concerned with messages that have been `frozen' on Exim's queue. When a message +is frozen, Exim no longer continues to try to deliver it. Freezing occurs when +a bounce message encounters a permanent failure because the sender address of +the original message that caused the bounce is invalid, so the bounce cannot be +delivered. This is probably the most common case, but there are also other +conditions that cause freezing, and frozen messages are not always bounce +messages. +.display asis +ignore_bounce_errors_after = 2d +timeout_frozen_after = 7d +.endd +The first of these options specifies that failing bounce messages are to be +discarded after 2 days on the queue. The second specifies that any frozen +message (whether a bounce message or not) is to be timed out (and discarded) +after a week. In this configuration, the first setting ensures that no failing +bounce message ever lasts a week. + + +.section ACL configuration +.index default||ACLs +.index ~~ACL||default configuration +In the default configuration, the ACL section follows the main configuration. +It starts with the line +.display asis +begin acl +.endd +and it contains the definition of one ACL called \*acl@_check@_rcpt*\ that was +referenced in the setting of \acl@_smtp@_rcpt\ above. +.index \\RCPT\\||ACL for +This ACL is used for every \\RCPT\\ command in an incoming SMTP message. Each +\\RCPT\\ command specifies one of the message's recipients. The ACL statements +are considered in order, until the recipient address is either accepted or +rejected. The \\RCPT\\ command is then accepted or rejected, according to the +result of the ACL processing. +.display asis +acl_check_rcpt: +.endd +This line, consisting of a name terminated by a colon, marks the start of the +ACL, and names it. +.display asis +accept hosts = : +.endd +This ACL statement accepts the recipient if the sending host matches the list. +But what does that strange list mean? It doesn't actually contain any host +names or IP addresses. The presence of the colon puts an empty item in the +list; Exim matches this only if the incoming message didn't come from a remote +host. The colon is important. Without it, the list itself is empty, and can +never match anything. + +What this statement is doing is to accept unconditionally all recipients in +messages that are submitted by SMTP from local processes using the standard +input and output (that is, not using TCP/IP). A number of MUAs operate in this +manner. +.display asis +deny domains = +local_domains + local_parts = ^[.] : ^.*[@%!/|] + +deny domains = !+local_domains + local_parts = ^[./|] : ^.*[@%!] : ^.*/\\.\\./ +.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 +addresses. + +The first three have in the past been associated with explicitly routed +addresses (percent is still sometimes used -- see the \percent@_hack@_domains\ +option). Addresses containing these characters are regularly tried by spammers +in an attempt to bypass relaying restrictions, and also by open relay testing +programs. Unless you really need them it is safest to reject these characters +at this early stage. This configuration is heavy-handed in rejecting these +characters for all messages it accepts from remote hosts. This is a deliberate +policy of being as safe as possible. + +The first rule above is stricter, and is applied to messages that are addressed +to one of the local domains handled by this host. This is implemented by the +first condition, which restricts it to domains that are listed in the +\*local@_domains*\ domain list. The `+' character is used to indicate a +reference to a named list. In this configuration, there is just one domain in +\*local@_domains*\, but in general there may be many. + +The second condition on the first statement uses two regular expressions to +block local parts that begin with a dot or contain `@@', `%', `!', `/', or `|'. +If you have local accounts that include these characters, you will have to +modify this rule. + +Empty components (two dots in a row) are not valid in RFC 2822, but Exim +allows them because they have been encountered in practice. (Consider local +parts constructed as `first-initial.second-initial.family-name' when applied to +someone like the author of Exim, who has no second initial.) However, a local +part starting with a dot or containing `/../' can cause trouble if it is used +as part of a file name (for example, for a mailing list). This is also true for +local parts that contain slashes. A pipe symbol can also be troublesome if the +local part is incorporated unthinkingly into a shell command line. + +The second rule above applies to all other domains, and is less strict. This +allows your own users to send outgoing messages to sites that use slashes +and vertical bars in their local parts. It blocks local parts that begin +with a dot, slash, or vertical bar, but allows these characters within the +local part. However, the sequence `/../' is barred. The use of `@@', `%', and +`!' is blocked, as before. The motivation here is to prevent your users (or +your users' viruses) from mounting certain kinds of attack on remote sites. + +.display asis +accept local_parts = postmaster + domains = +local_domains +.endd +This statement, which has two conditions, accepts an incoming address if the +local part is \*postmaster*\ and the domain is one of those listed in the +\*local@_domains*\ domain list. The `+' character is used to indicate a +reference to a named list. In this configuration, there is just one domain in +\*local@_domains*\, but in general there may be many. + +The presence of this statement means that mail to postmaster is never blocked +by any of the subsequent tests. This can be helpful while sorting out problems +in cases where the subsequent tests are incorrectly denying access. +.display asis +require verify = sender +.endd +This statement requires the sender address to be verified before any subsequent +ACL statement can be used. If verification fails, the incoming recipient +address is refused. Verification consists of trying to route the address, to +see if a +bounce +message could be delivered to it. In the case of remote addresses, basic +verification checks only the domain, but \*callouts*\ can be used for more +verification if required. Section ~~SECTaddressverification discusses the +details of address verification. + +.display asis +# deny message = rejected because $sender_host_address is \ +# in a black list at $dnslist_domain\n\ +# $dnslist_text +# dnslists = black.list.example +# +# warn message = X-Warning: $sender_host_address is \ +# in a black list at $dnslist_domain +# log_message = found in $dnslist_domain +# dnslists = black.list.example +.endd +These commented-out lines are examples of how you could configure Exim to check +sending hosts against a DNS black list. The first statement rejects messages +from blacklisted hosts, whereas the second merely inserts a warning header +line. + +.display asis +accept domains = +local_domains + endpass + message = unknown user + verify = recipient +.endd +This statement accepts the incoming recipient address if its domain is one of +the local domains, but only if the address can be verified. Verification of +local addresses normally checks both the local part and the domain. The +\endpass\ line needs some explanation: if the condition above \endpass\ fails, +that is, if the address is not in a local domain, control is passed to the next +ACL statement. However, if the condition below \endpass\ fails, that is, if a +recipient in a local domain cannot be verified, access is denied and the +recipient is rejected. +.index customizing||ACL failure message +The \message\ modifier provides a customized error message for the failure. +.display asis +accept domains = +relay_to_domains + endpass + message = unrouteable address + verify = recipient +.endd +This statement accepts the incoming recipient address if its domain is one of +the domains for which this host is a relay, but again, only if the address can +be verified. +.display asis +accept hosts = +relay_from_hosts +.endd +Control reaches this statement only if the recipient's domain is neither a +local domain, nor a relay domain. The statement accepts the address if the +message is coming from one of the hosts that are defined as being allowed to +relay through this host. Recipient verification is omitted here, because in +many cases the clients are dumb MUAs that do not cope well with SMTP error +responses. If you are actually relaying out from MTAs, you should probably add +recipient verification here. +.display asis +accept authenticated = * +.endd +Control reaches here for attempts to relay to arbitrary domains from arbitrary +hosts. The statement accepts the address only if the client host has +authenticated itself. The default configuration does not define any +authenticators, which means that no client can in fact authenticate. You will +need to add authenticator definitions if you want to make use of this ACL +statement. +.display asis +deny message = relay not permitted +.endd +The final statement denies access, giving a specific error message. Reaching +the end of the ACL also causes access to be denied, but with the generic +message `administrative prohibition'. + + +.section Router configuration +.index default||routers +.index routers||default +The router configuration comes next in the default configuration, introduced +by the line +.display asis +begin routers +.endd +Routers are the modules in Exim that make decisions about where to send +messages. An address is passed to each router in turn, until it is either +accepted, or failed. This means that the order in which you define the routers +matters. Each router is fully described in its own chapter later in this +manual. Here we give only brief overviews. + +.index domain literal||default router +.display asis +# domain_literal: +# driver = ipliteral +# domains = !+local_domains +# transport = remote_smtp +.endd +This router is commented out because the majority of sites do not want to +support domain literal addresses (those of the form \*user@@[10.9.8.7]*\). If +you uncomment this router, you also need to uncomment the setting of +\allow@_domain@_literals\ in the main part of the configuration. + +.display asis +dnslookup: + driver = dnslookup + domains = ! +local_domains + transport = remote_smtp +.newline + ignore_target_hosts = 0.0.0.0 : 127.0.0.0/8 +.newline + no_more +.endd +The first uncommented router handles addresses that do not involve any local +domains. This is specified by the line +.display asis +domains = ! +local_domains +.endd +The \domains\ option lists the domains to which this router applies, but the +exclamation mark is a negation sign, so the router is used only for domains +that are not in the domain list called \*local@_domains*\ (which was defined at +the start of the configuration). The plus sign before \*local@_domains*\ +indicates that it is referring to a named list. Addresses in other domains are +passed on to the following routers. + +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 +of the driver modules that is in the Exim binary. + +The \%dnslookup%\ router routes addresses by looking up their domains in the +DNS in order to obtain a list of hosts to which the address is routed. If the +router succeeds, the address is queued for the \%remote@_smtp%\ transport, as +specified by the \transport\ option. If the router does not find the domain in +the DNS, no further routers are tried because of the \no@_more\ setting, so the +address fails and is bounced. + +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 +whose IP addresses are 0.0.0.0 or are in the 127 subnet (typically 127.0.0.1). +Completely ignoring these IP addresses causes Exim to fail to route the +email address, so it bounces. Otherwise, Exim would log a routing problem, and +continue to try to deliver the message periodically until the address timed +out. +.display asis +system_aliases: + driver = redirect + allow_fail + allow_defer + data = ${lookup{$local_part}lsearch{/etc/aliases}} +# user = exim + file_transport = address_file + pipe_transport = address_pipe +.endd +Control reaches this and subsequent routers only for addresses in the local +domains. This router checks to see whether the local part is defined as an +alias in the \(/etc/aliases)\ file, and if so, redirects it according to the +data that it looks up from that file. If no data is found for the local part, +the value of the \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 +file. However, you can change this by setting \\SYSTEM@_ALIASES@_FILE\\ in +\(Local/Makefile)\ before building Exim. + +.display asis +userforward: + driver = redirect + check_local_user + file = $home/.forward + no_verify + no_expn + check_ancestor +# allow_filter + file_transport = address_file + pipe_transport = address_pipe + reply_transport = address_reply +.endd +This is the most complicated router in the default configuration. It is another +redirection router, but this time it is looking for forwarding data set up by +individual users. The \check@_local@_user\ setting means that the first thing it +does is to check that the local part of the address is the login name of a +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 +for more details). + +.index Sieve filter||enabling in default router +Traditional \(.forward)\ files contain just a list of addresses, pipes, or +files. Exim supports this by default. However, if \allow@_filter\ is set (it is +commented out by default), the contents of the file are interpreted as a set of +Exim or Sieve filtering instructions, provided the file begins with `@#Exim +filter' or `@#Sieve filter', respectively. User filtering is discussed in the +separate document entitled \*Exim's interfaces to mail filtering*\. + +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. +There are two reasons for doing this: +.numberpars +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. +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. +.endp + +The setting of \check@_ancestor\ prevents the router from generating a new +address that is the same as any previous address that was redirected. (This +works round a problem concerning a bad interaction between aliasing and +forwarding -- see section ~~SECTredlocmai). + +The final three option settings specify the transports that are to be used when +forwarding generates a direct delivery to a file, or to a pipe, or sets up an +auto-reply, respectively. For example, if a \(.forward)\ file contains +.display asis +a.nother@elsewhere.example, /home/spqr/archive +.endd +the delivery to \(/home/spqr/archive)\ is done by running the \address@_file\ +transport. +.display asis +localuser: + driver = accept + check_local_user + transport = local_delivery +.endd +The final router sets up delivery into local mailboxes, provided that the local +part is the name of a local login, by accepting the address and queuing it for +the \%local@_delivery%\ transport. Otherwise, we have reached the end of the +routers, so the address is bounced. + + +.section Transport configuration +.index default||transports +.index transports||default +Transports define mechanisms for actually delivering messages. They operate +only when referenced from routers, so the order in which they are defined does +not matter. The transports section of the configuration starts with +.display asis +begin transports +.endd +One remote transport and four local transports are defined. +.display asis +remote_smtp: + driver = smtp +.endd +This transport is used for delivering messages over SMTP connections. All its +options are defaulted. The list of remote hosts comes from the router. +.display asis +local_delivery: + driver = appendfile + file = /var/mail/$local_part + delivery_date_add + envelope_to_add + return_path_add +# group = mail +# mode = 0660 +.endd +This \%appendfile%\ transport is used for local delivery to user mailboxes in +traditional BSD mailbox format. By default it runs under the uid and gid of the +local user, which requires the sticky bit to be set on the \(/var/mail)\ +directory. Some systems use the alternative approach of running mail deliveries +under a particular group instead of using the sticky bit. The commented options +show how this can be done. + +Exim adds three headers to the message as it delivers it: ::Delivery-date::, +::Envelope-to:: and ::Return-path::. This action is requested by the three +similarly-named options above. +.display asis +address_pipe: + driver = pipe + return_output +.endd +This transport is used for handling deliveries to pipes that are generated by +redirection (aliasing or users' \(.forward)\ files). The \return@_output\ +option specifies that any output generated by the pipe is to be returned to the +sender. +.display asis +address_file: + driver = appendfile + delivery_date_add + envelope_to_add + return_path_add +.endd +This transport is used for handling deliveries to files that are generated by +redirection. The name of the file is not specified in this instance of +\%appendfile%\, because it comes from the \%redirect%\ router. +.display asis +address_reply: + driver = autoreply +.endd +This transport is used for handling automatic replies generated by users' +filter files. + + +.section Default retry rule +.index retry||default rule +.index default||retry rule +The retry section of the configuration file contains rules which affect the way +Exim retries deliveries that cannot be completed at the first attempt. It is +introduced by the line +.display asis +begin retry +.endd +In the default configuration, there is just one rule, which applies to all +errors: +.display asis +* * F,2h,15m; G,16h,1h,1.5; F,4d,6h +.endd +This causes any temporarily failing address to be retried every 15 minutes for +2 hours, then at intervals starting at one hour and increasing by a factor of +1.5 until 16 hours have passed, then every 6 hours up to 4 days. If an address +is not delivered after 4 days of failure, it is bounced. + + +.section Rewriting configuration +The rewriting section of the configuration, introduced by +.display asis +begin rewrite +.endd +contains rules for rewriting addresses in messages as they arrive. There are no +rewriting rules in the default configuration file. + + +.section Authenticators configuration +.index \\AUTH\\||configuration +The authenticators section of the configuration, introduced by +.display asis +begin authenticators +.endd +defines mechanisms for the use of the SMTP \\AUTH\\ command. No authenticators +are specified in the default configuration file. + + + +. +. +. +. +. ============================================================================ +.chapter Regular expressions +.set runningfoot "regular expressions" +.rset CHAPregexp ~~chapter + +.index regular expressions||library +.index PCRE +Exim supports the use of regular expressions in many of its options. It +uses the PCRE regular expression library; this provides regular expression +matching that is compatible with Perl 5. The syntax and semantics of +regular expressions is discussed in many Perl reference books, and also in +Jeffrey Friedl's +.if ~~html +[(A HREF="http://www.oreilly.com/catalog/regex/")] +.fi +$it{Mastering Regular Expressions} +.if ~~html +[(/A)] +.fi +(O'Reilly, ISBN 0-596-00289-0). + +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 +.if ~~html +[(A HREF="http://www.uit.co.uk/exim-book/")] +.fi +Exim book. +.if ~~html +[(/A)] +.fi +It describes in detail the features of the regular expressions that PCRE +supports, so no further description is included here. The PCRE functions are +called from Exim using the default option settings (that is, with no PCRE +options set), except that the \\PCRE@_CASELESS\\ option is set when the +matching is required to be case-insensitive. + +.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 +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 +domains = a.b.c : ^\\d{3} : *.y.z : ... +.endd +The doubling of the backslash is required because of string expansion that +precedes interpretation -- see section ~~SECTlittext for more discussion of +this issue, and a way of avoiding the need for doubling backslashes. The +regular expression that is eventually used in this example contains just one +backslash. The circumflex is included in the regular expression, and has the +normal effect of `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 +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, +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*\. +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 +.index testing||regular expressions +.index regular expressions||testing +.index \*pcretest*\ +A program called \*pcretest*\ forms part of the PCRE distribution and is built +with PCRE during the process of building Exim. It is primarily intended for +testing PCRE itself, but it can also be used for experimenting with regular +expressions. After building Exim, the binary can be found in the build +directory (it is not installed anywhere automatically). There is documentation +of various options in \(doc/pcretest.txt)\, but for simple testing, none are +needed. This is the output of a sample run of \*pcretest*\: +.display + re> $cb{/^([^@@]+)@@.+@\.(ac|edu)@\.(?!kr)[a-z]@{2@}@$/} +data> $cb{x@@y.ac.uk} + 0: x@@y.ac.uk + 1: x + 2: ac +data> $cb{x@@y.ac.kr} +No match +data> $cb{x@@y.edu.com} +No match +data> $cb{x@@y.edu.co} + 0: x@@y.edu.co + 1: x + 2: edu +.endd +.if ~~sys.fancy +Input typed by the user is shown in bold face. +.fi +After the `re>' prompt, a regular expression enclosed in delimiters is +expected. If this compiles without error, `data>' prompts are given for strings +against which the expression is matched. An empty data line causes a new +regular expression to be read. If the match is successful, the captured +substring values (that is, what would be in the variables \$0$\, \$1$\, \$2$\, +etc.) are shown. The above example tests for an email address whose domain ends +with either `ac' or `edu' followed by a two-character top-level domain that is +not `kr'. The local part is captured in \$1$\ and the `ac' or `edu' in \$2$\. + + + + + + +. +. +. +. +. ============================================================================ +.chapter File and database lookups +.set runningfoot "file/database lookups" +.rset CHAPfdlookup "~~chapter" +.index file||lookup +.index database lookups +.index lookup||description of +Exim can be configured to look up data in files or databases as it processes +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. +.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 +returned by the lookup is often (but not always) discarded; whether the lookup +succeeds or fails is what really counts. These kinds of list are described in +chapter ~~CHAPdomhosaddlists. +.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. +Be careful to distinguish between the following two examples: +.display asis +domains = ${lookup{$sender_host_address}lsearch{/some/file}} +domains = lsearch;/some/file +.endd +The first uses a string expansion, the result of which must be a domain list. +String expansions are described in detail in chapter ~~CHAPexpand. The +expansion takes place first, and the file that is searched could contain lines +like this: +.display asis +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 +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 +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: +domain2: +.endd +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 +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 +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 +~~CHAPexpand and ~~CHAPdomhosaddlists, respectively. + +.section Lookup types +.index lookup||types of +.index single-key lookup||definition of +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. +.nextp +.index query-style lookup||definition of +The \*query*\ style accepts a generalized database query. +No particular key value is assumed by Exim for query-style lookups. You can +use whichever Exim variable(s) you need to construct the database query. +.endp +The code for each lookup type is in a separate source file that is included in +the binary of Exim only if the corresponding compile-time option is set. The +default settings in \(src/EDITME)\ are: +.display asis +LOOKUP_DBM=yes +LOOKUP_LSEARCH=yes +.endd +which means that only linear searching and DBM lookups are included by default. +For some types of lookup (e.g. SQL databases), you need to install appropriate +libraries and header files before building Exim. + + + +.section Single-key lookup types +.rset SECTsinglekeylookups "~~chapter.~~section" +.index lookup||single-key types +.index single-key lookup||list of types +The following single-key lookup types are implemented: +.numberpars $. +.index cdb||description of +.index lookup||cdb +.index binary zero||in lookup key +\%cdb%\: The given file is searched as a Constant DataBase file, using the key +string without a terminating binary zero. The cdb format is designed for +indexed files that are read frequently and never updated, except by total +re-creation. As such, it is particulary suitable for large files containing +aliases or other indexed data referenced by an MTA. Information about cdb can +be found in several places: +.display rm +\?http://www.pobox.com/@~djb/cdb.html?\ +\?ftp://ftp.corpit.ru/pub/tinycdb/?\ +\?http://packages.debian.org/stable/utils/freecdb.html?\ +.endd +A cdb distribution is not needed in order to build Exim with cdb support, +because the code for reading cdb files is included directly in Exim itself. +However, no means of building or testing cdb files is provided with Exim, so +you need to obtain a cdb distribution in order to do this. +.nextp +.index DBM||lookup type +.index lookup||dbm +.index binary zero||in lookup key +\%dbm%\: Calls to DBM library functions are used to extract data from the given +DBM file by looking up the record with the given key. A terminating binary +zero is included in the key that is passed to the DBM library. See section +~~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 +Berkeley DB versions 3 or 4, it opens existing databases for reading with the +\\DB@_UNKNOWN\\ option. This enables it to handle any of the types of database +that the library supports, and can be useful for accessing DBM files created by +other applications. (For earlier DB versions, \\DB@_HASH\\ is always used.) + +.nextp +.index lookup||dbmnz +.index lookup||dbm, terminating zero +.index binary zero||in lookup key +.index Courier +.index \(/etc/userdbshadow.dat)\ +.index dmbnz lookup type +\%dbmnz%\: This is the same as \%dbm%\, except that a terminating binary zero +is not included in the key that is passed to the DBM library. You may need this +if you want to look up data in files that are created by or shared with some +other application that does not use terminating zeros. For example, you need to +use \%dbmnz%\ rather than \%dbm%\ if you want to authenticate incoming SMTP +calls using the passwords from Courier's \(/etc/userdbshadow.dat)\ file. Exim's +utility program for creating DBM files (\*exim@_dbmbuild*\) includes the zeros +by default, but has an option to omit them (see section ~~SECTdbmbuild). +.nextp +.index lookup||dsearch +.index dsearch lookup type +\%dsearch%\: The given file must be a directory; this is searched for a file +whose name is the key. The key may not contain any forward slash characters. +The result of a successful lookup is the name of the file. An example of how +this lookup can be used to support virtual domains is given in section +~~SECTvirtualdomains. +.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 +IPv6 addresses must be enclosed in quotes to prevent the first internal colon +being interpreted as a key terminator. For example: +.display asis +1.2.3.4: data for 1.2.3.4 +192.168.0.0/16 data for 192.168.0.0/16 +"abcd::cdab": data for abcd::cdab +"abcd:abcd::/32" data for abcd:abcd::/32 +.endd +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 +\%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 +the implicit key is the host's IP address rather than its name (see section +~~SECThoslispatsikey). +.nem + +.nextp +.index linear search +.index lookup||lsearch +.index lsearch lookup type +\%lsearch%\: The given file is a text file that is searched linearly for a +line beginning with the search key, terminated by a colon or white space or the +end of the line. The first occurrence that is found in the file is used. White +space between the key and the colon is permitted. The remainder of the line, +with leading and trailing white space removed, is the data. This can be +continued onto subsequent lines by starting them with any amount of white +space, but only a single space character is included in the data at such a +junction. If the data begins with a colon, the key must be terminated by a +colon, for example: +.display +baduser: :fail: +.endd +Empty lines and lines beginning with @# are ignored, even if they occur in the +middle of an item. This is the traditional textual format of alias files. Note +that the keys in an \%lsearch%\ file are literal strings. There is no +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. +.nextp +.index NIS lookup type +.index lookup||NIS +.index binary zero||in lookup key +\%nis%\: The given file is the name of a NIS map, and a NIS lookup is done with +the given key, without a terminating binary zero. There is a variant called +\%nis0%\ which does include the terminating binary zero in the key. This is +reportedly needed for Sun-style alias files. Exim does not recognize NIS +aliases; the full map names must be used. +.nextp +.index wildlsearch lookup type +.index lookup||wildlsearch +.index nwildlsearch lookup type +.index lookup||nwildlsearch +\%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, +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: +.display asis +*.a.b.c data for anything.a.b.c +*fish data for anythingfish +.endd +.nextp +The string may begin with a circumflex to indicate a regular expression. For +example, for \%wildlsearch%\: +.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 +string-expanded, the equivalent entry is: +.display asis +^\d+\.a\.b data for <digits>.a.b +.endd + +If the regular expression contains white space or colon characters, you must +either quote it (see \%lsearch%\ above), or represent these characters in other +ways. For example, \"@\s"\ can be used for white space and \"@\x3A"\ for a +colon. This may be easier than quoting, because if you quote, you have to +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%\ +means that the string may begin with a lookup name terminated by a semicolon, +and followed by lookup data. For example: +.display asis +cdb;/some/file data for keys that match the file +.endd +The data that is obtained from the nested lookup is discarded. +.endp +Keys that do not match any of these patterns are interpreted literally. The +continuation rules for the data are the same as for \%lsearch%\, and keys may +be followed by optional colons. + +\**Warning**\: Unlike most other single-key lookup types, a file of data for +\%(n)wildlsearch%\ can \*not*\ be turned into a DBM or cdb file, because those +lookup types support only literal keys. +.endp + +.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 +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. +.nextp +.index Interbase lookup type +.index lookup||Interbase +\%ibase%\: This does a lookup in an Interbase database. +.nextp +.index LDAP||lookup type +.index lookup||LDAP +\%ldap%\: This does an LDAP lookup using a query in the form of a URL, and +returns attributes from a single entry. There is a variant called \%ldapm%\ +that permits values from multiple entries to be returned. A third variant +called \%ldapdn%\ returns the Distinguished Name of a single entry instead of +any attribute values. See section ~~SECTldap. +.nextp +.index MySQL||lookup type +.index lookup||MySQL +\%mysql%\: The format of the query is an SQL statement that is passed to a MySQL +database. See section ~~SECTsql. +.nextp +.index NIS@+ lookup type +.index lookup||NIS+ +\%nisplus%\: This does a NIS+ lookup using a query that can specify the name of +the field to be returned. See section ~~SECTnisplus. +.nextp +.index Oracle||lookup type +.index lookup||Oracle +\%oracle%\: The format of the query is an SQL statement that is passed to an +Oracle database. See section ~~SECTsql. +.nextp +.index lookup||passwd +.index passwd lookup type +\%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%\ +lookup on a traditional \(/etc/passwd file)\, though with \"*"\ for the +password value. For example: +.display asis +*:42:42:King Rat:/home/kr:/bin/bash +.endd +.nextp +.index PostgreSQL lookup type +.index lookup||PostgreSQL +\%pgsql%\: The format of the query is an SQL statement that is passed to a +PostgreSQL database. See section ~~SECTsql. +.nextp +\%testdb%\: This is a lookup type that is used for testing Exim. It is +not likely to be useful in normal operation. +.nextp +.index whoson lookup type +.index lookup||whoson +\%whoson%\: \*Whoson*\ (\?http://whoson.sourceforge.net?\) is a proposed +Internet protocol that allows Internet server programs to check whether a +particular (dynamically allocated) IP address is currently allocated to a known +(trusted) user and, optionally, to obtain the identity of the said user. In +Exim, this can be used to implement `POP before SMTP' checking using ACL +statements such as +.display asis +require condition = \ + ${lookup whoson {$sender_host_address}{yes}{no}} +.endd +The query consists of a single IP address. The value returned is the name of +the authenticated user. +.endp + +.section Temporary errors in lookups +.index lookup||temporary error in +Lookup functions can return temporary error codes if the lookup cannot be +completed. For example, a NIS or LDAP database might be unavailable. For this +reason, it is not advisable to use a lookup that might do this for critical +options such as a list of local domains. + +When a lookup cannot be completed in a router or transport, delivery +of the message (to the relevant address) is deferred, as for any other +temporary error. In other circumstances Exim may assume the lookup has failed, +or may give up altogether. + + +.section Default values in single-key lookups +.rset SECTdefaultvaluelookups "~~chapter.~~section" +.index wildcard lookups +.index lookup||default values +.index lookup||wildcard +.index lookup||$*$ added to type +.index default||in single-key lookups +In this context, a `default value' is a value specified by the administrator +that is to be used if a lookup fails. + +If `$*$' is added to a single-key lookup type (for example, \lsearch$*$\) and +the initial lookup fails, the key `$*$' is looked up in the file to provide +a default value. See also the section on partial matching below. + +.index @*@@ with single-key lookup +.index lookup||$*$@@ added to type +.index alias file||per-domain default +Alternatively, if `$*$@@' is added to a single-key lookup type (for example +\dbm$*$@@\) then, if the initial lookup fails and the key contains an @@ +character, a second lookup is done with everything before the last @@ replaced +by $*$. This makes it possible to provide per-domain defaults in alias files +that include the domains in the keys. If the second lookup fails (or doesn't +take place because there is no @@ in the key), `$*$' is looked up. +For example, a \%redirect%\ router might contain: +.display asis +data = ${lookup{$local_part@$domain}lsearch*@{/etc/mixed-aliases}} +.endd +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 +Exim move on to try the next key. + + +.section Partial matching in single-key lookups +.rset SECTpartiallookup "~~chapter.~~section" +.index partial matching +.index wildcard lookups +.index lookup||partial matching +.index lookup||wildcard +.index asterisk||in search type +The normal operation of a single-key lookup is to search the file for an exact +match with the given key. However, in a number of situations where domains are +being looked up, it is useful to be able to do partial matching. In this case, +information in the file that has a key starting with `$*$.' is matched by any +domain that ends with the components that follow the full stop. For example, if +a key in a DBM file is +.display +*.dates.fict.example +.endd +then when partial matching is enabled this is matched by (amongst others) +\*2001.dates.fict.example*\ and \*1984.dates.fict.example*\. It is also matched +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 +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 +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. + +Partial matching is requested by adding the string `partial-' to the front of +the name of a single-key lookup type, for example, \partial-dbm\. When this is +done, the subject key is first looked up unmodified; if that fails, `$*$.' +is added at the start of the subject key, and it is looked up again. If that +fails, further lookups are tried with dot-separated components removed +from the start of the subject key, one-by-one, and `$*$.' added on the front of +what remains. + +A minimum number of two non-$*$ components are required. This can be adjusted +by including a number before the hyphen in the search type. For example, +\partial3-lsearch\ specifies a minimum of three non-$*$ components in the +modified keys. Omitting the number is equivalent to `partial2-'. If the subject +key is \*2250.dates.fict.example*\ then the following keys are looked up when +the minimum number of non-$*$ components is two: +.display asis +2250.dates.fict.example +*.2250.dates.fict.example +*.dates.fict.example +*.fict.example +.endd +As soon as one key in the sequence is successfully looked up, the lookup +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 +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: +.display asis +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 +components is unchanged). The prefix may consist of any punctuation characters +other than a closing parenthesis. It may be empty, for example: +.display asis +domains = partial1()cdb;/some/file +.endd +For this example, if the domain is \*a.b.c*\, the sequence of lookups is +\"a.b.c"\, \"b.c"\, and \"c"\. + +If `partial0' is specified, what happens at the end (when the lookup with just +one non-wild component has failed, and the original key is shortened right down +to the null string) depends on the prefix: +.numberpars $. +If the prefix has zero length, the whole lookup fails. +.nextp +If the prefix has length 1, a lookup for just the prefix is done. For +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 +for `$*$' on its own. +.nextp +Otherwise, the whole prefix is looked up. +.endp + +If the search type ends in `$*$' or `$*$@@' (see section +~~SECTdefaultvaluelookups above), the search for an ultimate default that this +implies happens after all partial lookups have failed. If `partial0' is +specified, adding `$*$' to the search type has no effect with the default +prefix, because the `$*$' key is already included in the sequence of partial +lookups. However, there might be a use for lookup types such as +`partial0(.)lsearch$*$'. + +The use of `$*$' in lookup partial matching differs from its use as a wildcard +in domain lists and the like. Partial matching works only in terms of +dot-separated components; a key such as \"*fict.example"\ +in a database file is useless, because the asterisk in a partial matching +subject key is always followed by a dot. + + + +.section 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. + + +.section Quoting lookup data +.index lookup||quoting +.index quoting||in lookups +When data from an incoming message is included in a query-style lookup, there +is the possibility of special characters in the data messing up the syntax of +the query. For example, a NIS+ query that contains +.display asis +[name=$local_part] +.endd +will be broken if the local part happens to contain a closing square bracket. +For NIS+, data can be enclosed in double quotes like this: +.display asis +[name="$local_part"] +.endd +but this still leaves the problem of a double quote in the data. The rule for +NIS+ is that double quotes must be doubled. Other lookup types have different +rules, and to cope with the differing requirements, an expansion operator +of the following form is provided: +.display +@$@{quote@_<<lookup-type>>:<<string>>@} +.endd +For example, the safest way to write the NIS+ query is +.display asis +[name="${quote_nisplus:$local_part}"] +.endd +See chapter ~~CHAPexpand for full coverage of string expansions. The quote +operator can be used for all lookup types, but has no effect for single-key +lookups, since no quoting is ever needed in their key strings. + + + +.section More about dnsdb +.rset SECTdnsdb "~~chapter.~~section" +.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: +.display asis +${lookup dnsdb{mx=a.b.example}{$value}fail} +.endd +.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: +.display asis +${lookup dnsdb{ptr=192.168.4.5}{$value}fail} +.endd + +.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. + + + + +.section More about LDAP +.rset SECTldap "~~chapter.~~section" +.index LDAP lookup +.index lookup||LDAP +.index Solaris||LDAP +The original LDAP implementation came from the University of Michigan; this has +become `Open LDAP', and there are now two different releases. Another +implementation comes from Netscape, and Solaris 7 and subsequent releases +contain inbuilt LDAP support. Unfortunately, though these are all compatible at +the lookup function level, their error handling is different. For this reason +it is necessary to set a compile-time variable when building Exim with LDAP, to +indicate which LDAP library is in use. One of the following should appear in +your \(Local/Makefile)\: +.display asis +LDAP_LIB_TYPE=UMICHIGAN +LDAP_LIB_TYPE=OPENLDAP1 +LDAP_LIB_TYPE=OPENLDAP2 +LDAP_LIB_TYPE=NETSCAPE +LDAP_LIB_TYPE=SOLARIS +.endd +If \\LDAP@_LIB@_TYPE\\ is not set, Exim assumes \"OPENLDAP1"\, which has the +same interface as the University of Michigan version. + +There are three LDAP lookup types in Exim. These behave slightly differently in +the way they handle the results of a query: +.numberpars $. +\%ldap%\ requires the result to contain just one entry; if there are more, it +gives an error. +.nextp +\%ldapdn%\ also requires the result to contain just one entry, but it is the +Distinguished Name that is returned rather than any attribute values. +.nextp +\%ldapm%\ permits the result to contain more than one entry; the attributes from +all of them are returned. +.endp + +For \%ldap%\ and \%ldapm%\, if a query finds only entries with no attributes, +Exim behaves as if the entry did not exist, and the lookup fails. The format of +the data returned by a successful lookup is described in the next section. +First we explain how LDAP queries are coded. + +.section Format of LDAP queries +.rset SECTforldaque "~~chapter.~~section" +.index LDAP||query format +An LDAP query takes the form of a URL as defined in RFC 2255. For example, in +the configuration of a \%redirect%\ router one might have this setting: +.display asis +data = ${lookup ldap \ + {ldap:///cn=$local_part,o=University%20of%20Cambridge,\ + c=UK?mailbox?base?}} +.endd +.index LDAP||with TLS +The URL may begin with \"ldap"\ or \"ldaps"\ if your LDAP library supports +secure (encrypted) LDAP connections. The second of these ensures that an +encrypted TLS connection is used. + +.section LDAP quoting +.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 +reason, there are two different LDAP-specific quoting operators. + +The \quote@_ldap\ operator is designed for use on strings that are part of +filter specifications. Conceptually, it first does the following conversions on +the string: +.display asis +* => \2A +( => \28 +) => \29 +\ => \5C +.endd +in accordance with RFC 2254. The resulting string is then quoted according +to the rules for URLs, that is, all characters except +.display asis +! $ ' - . _ ( ) * + +.endd +are converted to their hex values, preceded by a percent sign. For example: +.display asis +${quote_ldap: a(bc)*, a<yz>; } +.endd +yields +.display asis +%20a%5C28bc%5C29%5C2A%2C%20a%3Cyz%3E%3B%20 +.endd +Removing the URL quoting, this is (with a leading and a trailing space): +.display asis +a\28bc\29\2A, a<yz>; +.endd + +The \quote@_ldap@_dn\ operator is designed for use on strings that are part of +base DN specifications in queries. Conceptually, it first converts the string +by inserting a backslash in front of any of the following characters: +.display asis +, + " \ < > ; +.endd +It also inserts a backslash before any leading spaces or @# characters, and +before any trailing spaces. (These rules are in RFC 2253.) The resulting string +is then quoted according to the rules for URLs. For example: +.display asis +${quote_ldap_dn: a(bc)*, a<yz>; } +.endd +yields +.display asis +%5C%20a(bc)*%5C%2C%20a%5C%3Cyz%5C%3E%5C%3B%5C%20 +.endd +Removing the URL quoting, this is (with a trailing space): +.display asis +\ a(bc)*\, a\<yz\>\;\ +.endd +There are some further comments about quoting in the section on LDAP +authentication below. + +.section LDAP connections +.index LDAP||connections +The connection to an LDAP server may either be over TCP/IP, or, when OpenLDAP +is in use, via a Unix domain socket. The example given above does not specify +an LDAP server. A server that is reached by TCP/IP can be specified in a query +by starting it with +.display +ldap://<<hostname>>:<<port>>/... +.endd +If the port (and preceding colon) are omitted, the standard LDAP port (389) is +used. When no server is specified in a query, a list of default servers is +taken from the \ldap@_default@_servers\ configuration option. This supplies a +colon-separated list of servers which are tried in turn until one successfully +handles a query, or there is a serious error. Successful handling either +returns the requested data, or indicates that it does not exist. Serious errors +are syntactical, or multiple values when only a single value is expected. +Errors which cause the next server to be tried are connection failures, bind +failures, and timeouts. + +For each server name in the list, a port number can be given. The standard way +of specifing a host and port is to use a colon separator (RFC 1738). Because +\ldap@_default@_servers\ is a colon-separated list, such colons have to be +doubled. For example +.display asis +ldap_default_servers = ldap1.example.com::145:ldap2.example.com +.endd +If \ldap@_default@_servers\ is unset, a URL with no server name is passed +to the LDAP library with no server name, and the library's default (normally +the local host) is used. + +If you are using the OpenLDAP library, you can connect to an LDAP server using +a Unix domain socket instead of a TCP/IP connection. This is specified by using +\"ldapi"\ instead of \"ldap"\ in LDAP queries. What follows here applies only +to OpenLDAP. If Exim is compiled with a different LDAP library, this feature is +not available. + +For this type of connection, instead of a host name for the server, a pathname +for the socket is required, and the port number is not relevant. The pathname +can be specified either as an item in \ldap@_default@_servers\, or inline in +the query. In the former case, you can have settings such as +.display asis +ldap_default_servers = /tmp/ldap.sock : backup.ldap.your.domain +.endd +When the pathname is given in the query, you have to escape the slashes as +\"%2F"\ to fit in with the LDAP URL syntax. For example: +.display asis +${lookup ldap {ldapi://%2Ftmp%2Fldap.sock/o=... +.endd +When Exim processes an LDAP lookup and finds that the `hostname' is really +a pathname, it uses the Unix domain socket code, even if the query actually +specifies \"ldap"\ or \"ldaps"\. In particular, no encryption is used for a +socket connection. This behaviour means that you can use a setting of +\ldap@_default@_servers\ such as in the example above with traditional \"ldap"\ +or \"ldaps"\ queries, and it will work. First, Exim tries a connection via +the Unix domain socket; if that fails, it tries a TCP/IP connection to the +backup host. + +If an explicit \"ldapi"\ type is given in a query when a host name is +specified, an error is diagnosed. However, if there are more items in +\ldap@_default@_servers\, they are tried. In other words: +.numberpars $. +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. +.endp + +Using \"ldapi"\ with no host or path in the query, and no setting of +\ldap@_default@_servers\, does whatever the library does by default. + + +.section LDAP authentication and control information +.index LDAP||authentication +The LDAP URL syntax provides no way of passing authentication and other control +information to the server. To make this possible, the URL in an LDAP query may +be preceded by any number of `<<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: +.display +CONNECT $rm{set a connection timeout} +.newline +DEREFERENCE $rm{set the dereferencing parameter} +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', +`searching', `finding', or `always'. + +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 +.indent 0 +${lookup ldap + {user="cn=manager,o=University of Cambridge,c=UK" pass=secret + ldap:///o=University%20of%20Cambridge,c=UK?sn?sub?(cn=foo)} + {$value}fail} +.endd +The encoding of spaces as %20 is a URL thing which should not be done for any +of the auxiliary data. Exim configuration settings that include lookups which +contain password information should be preceded by `hide' to prevent non-admin +users from using the \-bP-\ option to see their values. + +The auxiliary data items may be given in any order. The default is no +connection timeout (the system timeout is used), no user or password, no limit +on the number of entries returned, and no time limit on queries. + +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 +quoting has two advantages: +.numberpars $. +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. +.endp +For example, a setting such as +.display asis +USER=cn=${quote_ldap_dn:$1} +.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 +does not allow unquoted spaces. For example: +.display asis +PASS=${quote:$3} +.endd + +The LDAP authentication mechanism can be used to check passwords as part of +SMTP authentication. See the \ldapauth\ expansion string condition in chapter +~~CHAPexpand. + + +.section Format of data returned by LDAP +.index LDAP||returned data formats +The \%ldapdn%\ lookup type returns the Distinguished Name from a single entry as +a sequence of values, for example +.display asis +cn=manager, o=University of Cambridge, c=UK +.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 +directory. + +In the common case where you specify a single attribute in your LDAP query, the +result is not quoted, and does not contain the attribute name. If the attribute +has multiple values, they are separated by commas. + +If you specify multiple attributes, the result contains space-separated, quoted +strings, each preceded by the attribute name and an equals sign. Within the +quotes, the quote character, backslash, and newline are escaped with +backslashes, and commas are used to separate multiple values for the attribute. +Apart from the escaping, the string within quotes takes the same form as the +output when a single attribute is requested. Specifying no attributes is the +same as specifying all of an entry's attributes. + +Here are some examples of the output format. The first line of each pair is an +LDAP query, and the second is the data that is returned. The attribute called +\attr1\ has two values, whereas \attr2\ has only one value: +.display asis +ldap:///o=base?attr1?sub?(uid=fred) +value1.1, value1.2 + +ldap:///o=base?attr2?sub?(uid=fred) +value two + +ldap:///o=base?attr1,attr2?sub?(uid=fred) +attr1="value1.1, value1.2" attr2="value two" + +ldap:///o=base??sub?(uid=fred) +objectClass="top" attr1="value1.1, value1.2" attr2="value two" +.endd +The \extract\ operator in string expansions can be used to pick out individual +fields from data that consists of $it{key}=$it{value} pairs. You can make use +of Exim's \-be-\ option to run expansion tests and thereby check the results of +LDAP lookups. + + + +.section More about NIS+ +.rset SECTnisplus "~~chapter.~~section" +.index NIS@+ lookup type +.index lookup||NIS+ +NIS+ queries consist of a NIS+ \*indexed name*\ followed by an optional colon +and field name. If this is given, the result of a successful query is the +contents of the named field; otherwise the result consists of a concatenation +of \*field-name=field-value*\ pairs, separated by spaces. Empty values and +values containing spaces are quoted. For example, the query +.display asis +[name=mg1456],passwd.org_dir +.endd +might return the string +.display asis +name=mg1456 passwd="" uid=999 gid=999 gcos="Martin Guerre" +home=/home/mg1456 shell=/bin/bash shadow="" +.endd +(split over two lines here to fit on the page), whereas +.display asis +[name=mg1456],passwd.org_dir:gcos +.endd +would just return +.display asis +Martin Guerre +.endd +with no quotes. A NIS+ lookup fails if NIS+ returns more than one table entry +for the given indexed key. The effect of the \quote@_nisplus\ expansion +operator is to double any quote characters within the text. + + +.section More about MySQL, PostgreSQL, Oracle, and Interbase +.rset SECTsql "~~chapter.~~section" +.index MySQL||lookup type +.index PostgreSQL lookup type +.index lookup||MySQL +.index lookup||PostgreSQL +.index Oracle||lookup type +.index lookup||Oracle +.index Interbase lookup type +.index lookup||Interbase +If any MySQL, PostgreSQL, Oracle, or Interbase lookups are used, the +\mysql@_servers\, \pgsql@_servers\, \oracle@_servers\, or \ibase@_servers\ +option (as appropriate) must be set to a colon-separated list of server +information. Each item in the list is a slash-separated list of four items: +host name, database name, user name, and password. In the case of Oracle, the +host name field is used for the `service name', and the database name field is +not used and should be empty. For example: +.display asis +hide oracle_servers = oracle.plc.example//ph10/abcdwxyz +.endd +Because password data is sensitive, you should always precede the setting with +`hide', to prevent non-admin users from obtaining the setting via the \-bP-\ +option. Here is an example where two MySQL servers are listed: +.display asis +hide mysql_servers = localhost/users/root/secret:\ + otherhost/users/root/othersecret +.endd +For MySQL and PostgreSQL, a host may be specified as <<name>>:<<port>> but +because this is a colon-separated list, the colon has to be doubled. + +For each query, these parameter groups are tried in order until a connection +and a query succeeds. Queries for these databases are SQL statements, so an +example might be +.display asis +.indent 0 +${lookup mysql{select mailbox from users where id='ph10'}{$value}fail} +.endd +If the result of the query contains more than one field, the data for +each field in the row is returned, preceded by its name, so the result +of +.display asis +.indent 0 +${lookup pgsql{select home,name from users where id='ph10'}{$value}} +.endd +might be +.display asis +home=/home/ph10 name="Philip Hazel" +.endd +Values containing spaces and empty values are double quoted, with embedded +quotes escaped by a backslash. + +If the result of the query contains just one field, the value is passed back +verbatim, without a field name, for example: +.display asis +Philip Hazel +.endd +If the result of the query yields more than one row, it is all concatenated, +with a newline between the data for each row. + +The \quote@_mysql\, \quote@_pgsql\, and \quote@_oracle\ expansion operators +convert newline, tab, carriage return, and backspace to @\n, @\t, @\r, and @\b +respectively, and the characters single-quote, double-quote, and backslash +itself are escaped with backslashes. The \quote@_pgsql\ expansion operator, in +addition, escapes the percent and underscore characters. This cannot be done +for MySQL because these escapes are not recognized in contexts where these +characters are not special. + + +.section Special MySQL features +For MySQL, an empty host name or the use of `localhost' in \mysql@_servers\ +causes a connection to the server on the local host by means of a Unix domain +socket. An alternate socket can be specified in parentheses. The full syntax of +each item in \mysql@_servers\ is: +.display +<<hostname>>@:@:<<port>>(<<socket name>>)/<<database>>/<<user>>/<<password>> +.endd +Any of the three sub-parts of the first field can be omitted. For normal use on +the local host it can be left blank or set to just `localhost'. + +No database need be supplied -- but if it is absent here, it must be given in +the queries. + +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. + + + +.section Special PostgreSQL features +PostgreSQL lookups can also use Unix domain socket connections to the database. +This is usually faster and costs less CPU time than a TCP/IP connection. +However it can be used only if the mail server runs on the same machine as the +database server. A configuration line for PostgreSQL via Unix domain sockets +looks like this: +.display asis +hide pgsql_servers = (/tmp/.s.PGSQL.5432)/db/user/password : ... +.endd +In other words, instead of supplying a host name, a path to the socket is +given. The path name is enclosed in parentheses so that its slashes aren't +visually confused with the delimiters for the other server parameters. + +If a PostgreSQL query is issued that does not request any data (an insert, +update, or delete command), the result of the lookup is the number of rows +affected. + + + + +. +. +. +. +. ============================================================================ +.chapter Domain, host, address, and local part lists +.set runningfoot "domain, host, and address lists" +.rset CHAPdomhosaddlists "~~chapter" +.index list||of domains, hosts, etc. +A number of Exim configuration options contain lists of domains, hosts, +email addresses, or local parts. For example, the \hold@_domains\ option +contains a list of domains whose delivery is currently suspended. These lists +are also used as data in ACL statements (see chapter ~~CHAPACL). + +Each item in one of these lists is a pattern to be matched against a domain, +host, email address, or local part, respectively. In the sections below, the +different types of pattern for each case are described, but first we cover some +general facilities that apply to all four kinds of list. + + +.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. + +If an item in a list is a regular expression, backslashes, dollars and possibly +other special characters in the expression must be protected against +misinterpretation by the string expander. The easiest way to do this is to use +the \"@\N"\ expansion feature to indicate that the contents of the regular +expression should not be expanded. For example, in an ACL you might have: +.display asis +deny senders = \N^\d{8}\w@.*\.baddomain\.example$\N : + ${lookup{$domain}lsearch{/badsenders/bydomain}} +.endd +The first item is a regular expression that is protected from expansion by +\"@\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 +.index list||negation +.index negation in lists +Items in a list may be positive or negative. Negative items are indicated by a +leading exclamation mark, which may be followed by optional white space. A list +defines a set of items (domains, etc). When Exim processes one of these lists, +it is trying to find out whether a domain, host, address, or local part +(respectively) is in the set that is defined by the list. It works like this: + +The list is scanned from left to right. If a positive item is matched, the +subject that is being checked is in the set; if a negative item is matched, the +subject is not in the set. If the end of the list is reached without the +subject having matched any of the patterns, it is in the set if the last item +was a negative one, but not if it was a positive one. For example, the list in +.display asis +domainlist relay_domains = !a.b.c : *.b.c +.endd +matches any domain ending in \*.b.c*\ except for \*a.b.c*\. Domains that match +neither \*a.b.c*\ nor \*@*.b.c*\ do not match, because the last item in the +list is positive. However, if the setting were +.display asis +domainlist relay_domains = !a.b.c +.endd +then all domains other than \*a.b.c*\ would match because the last item in the +list is negative. In other words, a list that ends with a negative item behaves +as if it had an extra item \":*"\ 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. + + +.section File names in lists +.rset SECTfilnamlis "~~chapter.~~section" +.index list||file name in +If an item in a domain, host, address, or local part list is an absolute file +name (beginning with a slash character), each line of the file is read and +processed as if it were an independent item in the list, except that further +file names are not allowed, +and no expansion of the data from the file takes place. +Empty lines in the file are ignored, and the file may also contain comment +lines: +.numberpars $. +For domain and host lists, if a @# character appears anywhere in a line of the +file, it and all following characters are ignored. +.nextp +Because local parts may legitimately contain @# characters, a comment in an +address list or local part list file is recognized only if @# is preceded by +white space or the start of the line. For example: +.display asis +not#comment@x.y.z # but this is a comment +.endd +.endp +Putting a file name in a list has the same effect as inserting each line of the +file as an item in the list (blank lines and comments excepted). However, there +is one important difference: the file is read each time the list is processed, +so if its contents vary over time, Exim's behaviour changes. + +If a file name is preceded by an exclamation mark, the sense of any match +within the file is inverted. For example, if +.display asis +hold_domains = !/etc/nohold-domains +.endd +and the file contains the lines +.display asis +!a.b.c +*.b.c +.endd +then \*a.b.c*\ is in the set of domains defined by \hold@_domains\, whereas any +domain matching \"*.b.c"\ is not. + + +.section An lsearch file is not an out-of-line list +As will be described in the sections that follow, lookups can be used in lists +to provide indexed methods of checking list membership. There has been some +confusion about the way \%lsearch%\ lookups work in lists. Because +an \%lsearch%\ file contains plain text and is scanned sequentially, it is +sometimes thought that it is allowed to contain wild cards and other kinds of +non-constant pattern. This is not the case. The keys in an \%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 +list, just give the file name on its own, without a search type, as described +in the previous section. + + + +.section Named lists +.rset SECTnamedlists "~~chapter.~~section" +.index named lists +.index list||named +A list of domains, hosts, email addresses, or local parts can be given a name +which is then used to refer to the list elsewhere in the configuration. This is +particularly convenient if the same list is required in several different +places. It also allows lists to be given meaningful names, which can improve +the readability of the configuration. For example, it is conventional to define +a domain list called \*local@_domains*\ for all the domains that are handled +locally on a host, using a configuration line such as +.display asis +domainlist local_domains = localhost:my.dom.example +.endd +Named lists are referenced by giving their name preceded by a plus sign, so, +for example, a router that is intended to handle local domains would be +configured with the line +.display asis +domains = +local_domains +.endd +The first router in a configuration is often one that handles all domains +except the local ones, using a configuration with a negated item like this: +.display asis +dnslookup: + driver = dnslookup + domains = ! +local_domains + transport = remote_smtp + no_more +.endd +The four kinds of named list are created by configuration lines starting with +the words \domainlist\, \hostlist\, \addresslist\, or \localpartlist\, +respectively. Then there follows the name that you are defining, followed by an +equals sign and the list itself. For example: +.display asis +hostlist relay_hosts = 192.168.23.0/24 : my.friend.example +addresslist bad_senders = cdb;/etc/badsenders +.endd +A named list may refer to other named lists: +.display asis +domainlist dom1 = first.example : second.example +domainlist dom2 = +dom1 : third.example +domainlist dom3 = fourth.example : +dom2 : fifth.example +.endd + +\**Warning**\: If the last item in a referenced list is a negative one, the +effect may not be what you intended, because the negation does not propagate +out to the higher level. For example, consider: +.display asis +domainlist dom1 = !a.b +domainlist dom2 = +dom1 : *.b +.endd +The second list specifies `either in the \dom1\ list or \*@*.b*\'. The first +list specifies just `not \*a.b*\', so the domain \*x.y*\ matches it. That means +it matches the second list as well. The effect is not the same as +.display asis +domainlist dom2 = !a.b : *.b +.endd +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 +address or checking an incoming message, it caches the result of tests on named +lists. So, if you have a setting such as +.display asis +domains = +local_domains +.endd +on several of your routers +or in several ACL statements, +the actual test is done only for the first one. However, the caching works only +if there are no expansions within the list itself or any sublists that it +references. In other words, caching happens only for lists that are known to be +the same each time they are referenced. + +By default, there may be up to 16 named lists of each type. This limit can be +extended by changing a compile-time variable. The use of domain and host lists +is recommended for concepts such as local domains, relay domains, and relay +hosts. The default configuration is set up like this. + + +.section Named lists compared with macros +.index list||named compared with macro +.index macro||compared with named list +At first sight, named lists might seem to be no different from macros in the +configuration file. However, macros are just textual substitutions. If you +write +.display asis +ALIST = host1 : host2 +auth_advertise_hosts = !ALIST +.endd +it probably won't do what you want, because that is exactly the same as +.display asis +auth_advertise_hosts = !host1 : host2 +.endd +Notice that the second host name is not negated. However, if you use a host +list, and write +.display asis +hostlist alist = host1 : host2 +auth_advertise_hosts = ! +alist +.endd +the negation applies to the whole list, and so that is equivalent to +.display asis +auth_advertise_hosts = !host1 : !host2 +.endd + + +.em +.section Named list caching +.index list||caching of named +.index caching||named lists +While processing a message, Exim caches the result of checking a named list if +it is sure that the list is the same each time. In practice, this means that +the cache operates only if the list contains no @$ characters, which guarantees +that it will not change when it is expanded. Sometimes, however, you may have +an expanded list that you know will be the same each time within a given +message. For example: +.display asis +domainlist special_domains = \ + ${lookup{$sender_host_address}cdb{/some/file}} +.endd +This provides a list of domains that depends only on the sending host's IP +address. If this domain list is referenced a number of times (for example, +in several ACL lines, or in several routers) the result of the check is not +cached by default, because Exim does not know that it is going to be the +same list each time. + +By appending \"@_cache"\ to \"domainlist"\ you can tell Exim to go ahead and +cache the result anyway. For example: +.display asis +domainlist_cache special_domains = ${lookup{... +.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 +.rset SECTdomainlist "~~chapter.~~section" +.index domain list||patterns for +.index list||domain list +Domain lists contain patterns that are to be matched against a mail domain. +The following types of item may appear in domain lists: +.numberpars $. +.index primary host name +.index host||name, matched in domain list +.index \primary@_hostname\ +.index domain list||matching primary host name +.index @@ in a domain list +If a pattern consists of a single @@ character, it matches the local host name, +as set by the \primary@_hostname\ option (or defaulted). This makes it possible +to use the same configuration file on several different hosts that differ only +in their names. +.nextp +.index @@[] in a domain list +.index domain list||matching local IP interfaces +.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 +In today's Internet, the use of domain literals is controversial. +.nem +.nextp +.index @@mx@_any +.index @@mx@_primary +.index @@mx@_secondary +.index domain list||matching MX pointers to local host +If a pattern consists of the string \"@@mx@_any"\ it matches any domain that +has an MX record pointing to the local host or to any host that is listed in +.index \hosts@_treat@_as@_local\ +\hosts@_treat@_as@_local\. The items \"@@mx@_primary"\ and \"@@mx@_secondary"\ +are similar, except that the first matches only when a primary MX target is the +local host, and the second only when no primary MX target is the local host, +but a secondary MX target is. `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\ +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 +on a router). For example: +.display asis +domains = @mx_any/ignore=127.0.0.1 +.endd +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 +contain negative items. + +Because the list of IP addresses is a sublist within a domain list, you have to +be careful about delimiters if there is more than one address. Like any other +list, the default delimiter can be changed. Thus, you might have: +.display asis +domains = @mx_any/ignore=<;127.0.0.1;0.0.0.0 : \ + an.other.domain : ... +.endd +so that the sublist uses semicolons for delimiters. When IPv6 addresses are +involved, it is easiest to change the delimiter for the main list as well: +.display asis +domains = <? @mx_any/ignore=<;127.0.0.1;::1 ? \ + an.other.domain ? ... +.endd +.nem + +.nextp +.index asterisk||in domain list +.index domain list||asterisk in +.index domain list||matching `ends with' +If a pattern starts with an asterisk, the remaining characters of the pattern +are compared with the terminating characters of the domain. The use of `$*$' in +domain lists differs from its use in partial matching lookups. In a domain +list, the character following the asterisk need not be a dot, whereas partial +matching works only in terms of dot-separated components. For example, a domain +list item such as \"*key.ex"\ matches \*donkey.ex*\ as well as +\*cipher.key.ex*\. +.nextp +.index regular expressions||in domain list +.index domain list||matching regular expression +If a pattern starts with a circumflex character, it is treated as a regular +expression, and matched against the domain using a regular expression matching +function. The circumflex is treated as part of the regular expression. +References to descriptions of the syntax of regular expressions are given in +chapter ~~CHAPregexp. + +\**Warning**\: Because domain lists are expanded before being processed, you +must escape any backslash and dollar characters in the regular expression, or +use the special \"@\N"\ sequence (see chapter ~~CHAPexpand) to specify that it +is not to be expanded (unless you really do want to build a regular expression +by expansion, of course). +.nextp +.index lookup||in domain list +.index domain list||matching by lookup +If a pattern starts with the name of a single-key lookup type followed by a +semicolon (for example, `dbm;' or `lsearch;'), the remainder of the pattern +must be a file name in a suitable format for the lookup type. For example, for +`cdb;' it must be an absolute path: +.display asis +domains = cdb;/etc/mail/local_domains.cdb +.endd +The appropriate type of lookup is done on the file using the domain name as the +key. In most cases, the data that is looked up is not used; Exim is interested +only in whether or not the key is present in the file. However, when a lookup +is used for the \domains\ option on a router +or a \domains\ condition in an ACL statement, the data is preserved in the +\$domain@_data$\ variable and can be referred to in other router options or +other statements in the same ACL. +.nextp +Any of the single-key lookup type names may be preceded by `partial<<n>>-', +where the <<n>> is optional, for example, +.display asis +domains = partial-dbm;/partial/domains +.endd +This causes partial matching logic to be invoked; a description of how this +works is given in section ~~SECTpartiallookup. +.nextp +.index asterisk||in lookup type +Any of the single-key lookup types may be followed by an asterisk. This causes +a default lookup for a key consisting of a single asterisk to be done if the +original lookup fails. This is not a useful feature when using a domain list to +select particular domains (because any domain would match), but it might have +value if the result of the lookup is being used via the \$domain@_data$\ +expansion variable. +.nextp +If the pattern starts with the name of a query-style lookup type followed by a +semicolon (for example, `nisplus;' or `ldap;'), the remainder of the pattern +must be an appropriate query for the lookup type, as described in chapter +~~CHAPfdlookup. For example: +.display asis +hold_domains = mysql;select domain from holdlist \ + where domain = '$domain'; +.endd +In most cases, the data that is looked up is not used (so for an SQL query, for +example, it doesn't matter what field you select). Exim is interested only in +whether or not the query succeeds. However, when a lookup is used for the +\domains\ option on a router, the data is preserved in the \$domain@_data$\ +variable and can be referred to in other options. +.nextp +.index domain list||matching literal domain name +If none of the above cases apply, a caseless textual comparison is made between +the pattern and the domain. +.endp + +Here is an example that uses several different kinds of pattern: +.display asis +domainlist funny_domains = \ + @ : \ + lib.unseen.edu : \ + *.foundation.fict.example : \ + \N^[1-2]\d{3}\.fict\.example$\N : \ + partial-dbm;/opt/data/penguin/book : \ + nis;domains.byname : \ + nisplus;[name=$domain,status=local],domains.org_dir +.endd +There are obvious processing trade-offs among the various matching modes. Using +an asterisk is faster than a regular expression, and listing a few names +explicitly probably is too. The use of a file or database lookup is expensive, +but may be the only option if hundreds of names are required. Because the +patterns are tested in order, it makes sense to put the most commonly matched +patterns earlier. + + +.section Host lists +.rset SECThostlist "~~chapter.~~section" +.index host list||patterns in +.index list||host list +Host lists are used to control what remote hosts are allowed to do. For +example, some hosts may be allowed to use the local host as a relay, and some +may be permitted to use the SMTP \\ETRN\\ command. Hosts can be identified in +two different ways, by name or by IP address. In a host list, some types of +pattern are matched to a host name, and some are matched to an IP address. +You need to be particularly careful with this when single-key lookups are +involved, to ensure that the right value is being used as the key. + +.section Special host list patterns +.index empty item in hosts list +.index host list||empty string in +If a host list item is the empty string, it matches only when no remote host is +involved. This is the case when a message is being received from a local +process using SMTP on the standard input, that is, when a TCP/IP connection is +not used. + +.index asterisk||in host list +The special pattern `$*$' in a host list matches any host or no host. Neither +the IP address nor the name is actually inspected. + + +.section Host list patterns that match by IP address +.rset SECThoslispatip "~~chapter.~~section" +.index host list||matching IP addresses +If an IPv4 host calls an IPv6 host and the call is accepted on an IPv6 socket, +the incoming address actually appears in the IPv6 host as +`@:@:$tt{ffff}:<<v4address>>'. When such an address is tested against a host +list, it is converted into a traditional IPv4 address first. (Not all operating +systems accept IPv4 calls on IPv6 sockets, as there have been some security +concerns.) + +The following types of pattern in a host list check the remote host by +inspecting its IP address: +.numberpars $. +If the pattern is a plain domain name (not a regular expression, not starting +with $*$, not a lookup of any kind), Exim calls the operating system function +to find the associated IP address(es). Exim uses the newer +\*getipnodebyname()*\ function when available, otherwise \*gethostbyname()*\. +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 +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 +If the pattern is `@@', the primary host name is substituted and used as a +domain name, as just described. +.nextp +If the pattern is an IP address, it is matched against the IP address of the +subject host. IPv4 addresses are given in the normal `dotted-quad' notation. +IPv6 addresses can be given in colon-separated format, but the colons have to +be doubled so as not to be taken as item separators when the default list +separator is used. IPv6 addresses are recognized even when Exim is compiled +without IPv6 support. This means that if they appear in a host list on an +IPv4-only host, Exim will not treat them as host names. They are just addresses +that can never match a client host. +.nextp +.index @@[] in a host list +If the pattern is `@@[]', it matches the IP address of any IP interface on +the local host. For example, if the local host is an IPv4 host with one +interface address 10.45.23.56, these two ACL statements have the same effect: +.display asis +accept hosts = 127.0.0.1 : 10.45.23.56 +accept hosts = @[] +.endd +.nextp +If the pattern is an IP address followed by a slash and a mask length (for +example 10.11.42.0/24), it is matched against the IP address of the subject +host under the given mask. +This allows, an entire network of hosts to be included (or excluded) by a +single item. +.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. + +\**Note**\: the mask is \*not*\ a count of addresses, nor is it the high number +of a range of addresses. It is the number of bits in the network portion of the +address. The above example specifies a 24-bit netmask, so it matches all 256 +addresses in the 10.11.42.0 network. An item such as +.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. + +Here is another example which shows an IPv4 and an IPv6 network: +.display asis +recipient_unqualified_hosts = 192.168.0.0/16: \ + 3ffe::ffff::836f::::/48 +.endd +The doubling of list separator characters applies only when these items +appear inline in a host list. It is not required when indirecting via a file. +For example, +.display asis +recipient_unqualified_hosts = /opt/exim/unqualnets +.endd +could make use of a file containing +.display asis +172.16.0.0/12 +3ffe:ffff:836f::/48 +.endd +to have exactly the same effect as the previous example. When listing IPv6 +addresses inline, it is usually more convenient to use the facility for +changing separator characters. This list contains the same two networks: +.display asis +recipient_unqualified_hosts = <; 172.16.0.0/12; \ + 3ffe:ffff:836f::/48 +.endd +The separator is changed to semicolon by the leading `<;' at the start of the +list. +.endp + + +.section Host list patterns for single-key lookups by host address +.rset SECThoslispatsikey "~~chapter.~~section" +.index host list||lookup of IP address +When a host is to be identified by a single-key lookup of its complete IP +address, the pattern takes this form: +.display +net-<<single-key-search-type>>;<<search-data>> +.endd +For example: +.display asis +hosts_lookup = net-cdb;/hosts-by-ip.db +.endd +The text form of the IP address of the subject host is used as the lookup key. +IPv6 addresses are converted to an unabbreviated form, using lower case +letters, with dots as separators because colon is the key terminator in +\%lsearch%\ files. [Colons can in fact be used in keys in \%lsearch%\ files by +quoting the keys, but this is a facility that was added later.] The data +returned by the lookup is not used. + +.index IP address||masking +.index host list||masked IP address +Single-key lookups can also be performed using masked IP addresses, using +patterns of this form: +.display +net<<number>>-<<single-key-search-type>>;<<search-data>> +.endd +For example: +.display asis +net24-dbm;/networks.db +.endd +The IP address of the subject host is masked using <<number>> as the mask +length. A textual string is constructed from the masked value, followed by the +mask, and this is used as the lookup key. For example, if the host's IP address +is 192.168.34.6, the key that is looked up for the above example is +`192.168.34.0/24'. IPv6 addresses are converted to a text value using lower +case letters and dots as separators instead of the more usual colon, because +colon is the key terminator in \%lsearch%\ files. Full, unabbreviated IPv6 +addresses are always used. + +\**Warning**\: Specifing \net32@-\ (for an IPv4 address) or \net128@-\ (for an +IPv6 address) is not the same as specifing just \net@-\ without a number. In +the former case the key strings include the mask value, whereas in the latter +case the IP address is used on its own. + + +.section Host list patterns that match by host name +.rset SECThoslispatnam "~~chapter.~~section" +.index host||lookup failures +.index unknown 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 +Although many sites on the Internet are conscientious about maintaining reverse +DNS data for their hosts, there are also many that do not do this. +Consequently, a name cannot always be found, and this may lead to unwanted +effects. Take care when configuring host lists with wildcarded name patterns. +Consider what will happen if a name cannot be found. + +Because of the problems of determining host names from IP addresses, matching +against host names is not as common as matching against IP addresses. + +By default, in order to find a host name, Exim first does a reverse DNS lookup; +if no name is found in the DNS, the system function (\*gethostbyaddr()*\ or +\*getipnodebyaddr()*\ if available) is tried. The order in which these lookups +are done can be changed by setting the \host@_lookup@_order\ option. + +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 +.index alias for host +As a result of aliasing, hosts may have more than one name. When processing any +of the following types of pattern, all the host's names are checked: +.numberpars $. +.index asterisk||in host list +If a pattern starts with `$*$' the remainder of the item must match the end of +the host name. For example, \"*.b.c"\ matches all hosts whose names end in +\*.b.c*\. This special simple form is provided because this is a very common +requirement. Other kinds of wildcarding require the use of a regular +expression. +.nextp +.index regular expressions||in host list +.index host list||regular expression in +If the item starts with `@^' it is taken to be a regular expression which is +matched against the host name. For example, +.display asis +^(a|b)\.c\.d$ +.endd +is a regular expression that matches either of the two hosts \*a.c.d*\ or +\*b.c.d*\. When a regular expression is used in a host list, you must take care +that backslash and dollar characters are not misinterpreted as part of the +string expansion. The simplest way to do this is to use \"@\N"\ to mark that +part of the string as non-expandable. For example: +.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 +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 +behaviour when it fails to find the information it is seeking is the same. + +.index \"+include@_unknown"\ +.index \"+ignore@_unknown"\ +By default, Exim behaves as if the host does not match the list. This may not +always be what you want to happen. To change Exim's behaviour, the special +items \"+include@_unknown"\ or \"+ignore@_unknown"\ may appear in the list (at +top level -- they are not recognized in an indirected file). +.numberpars $. +If any item that follows \"+include@_unknown"\ requires information that +cannot found, Exim behaves as if the host does match the list. For example, +.display asis +host_reject_connection = +include_unknown:*.enemy.ex +.endd +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 +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 +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. + +\**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 +.rset SECThoslispatnamsk "~~chapter.~~section" +.index host||lookup failures +.index unknown host name +.index host list||matching host name +If a pattern is of the form +.display +<<single-key-search-type>>;<<search-data>> +.endd +for example +.display asis +dbm;/host/accept/list +.endd +a single-key lookup is performend, using the host name as its key. If the +lookup succeeds, the host matches the item. The actual data that is looked up +is not used. + +\**Reminder**\: With this kind of pattern, you must have host $it{names} as +keys in the file, not IP addresses. If you want to do lookups based on IP +addresses, you must precede the search type with `net-' (see section +~~SECThoslispatsikey). There is, however, no reason why you could not use two +items in the same list, one doing an address lookup and one doing a name +lookup, both using the same file. + + +.section Host list patterns for query-style lookups +If a pattern is of the form +.display +<<query-style-search-type>>;<<query>> +.endd +the query is obeyed, and if it succeeds, the host matches the item. The actual +data that is looked up is not used. The variables \$sender@_host@_address$\ and +\$sender@_host@_name$\ can be used in the query. For example: +.display asis +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. + +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 +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 +still recognized for query-style lookups, but its presence or absence has no +effect. (Of course, for single-key lookups, \"net-"\ $it{is} important.) + + +.section Mixing wildcarded host names and addresses in host lists +.rset SECTmixwilhos "~~chapter.~~section" +.index host list||mixing names and addresses in +If you have name lookups or wildcarded host names and IP addresses in the same +host list, you should normally put the IP addresses first. For example, in an +ACL you could have: +.display asis +accept hosts = 10.9.8.7 : *.friend.example +.endd +The reason for this lies in the left-to-right way that Exim processes lists. +It can test IP addresses without doing any DNS lookups, but when it reaches an +item that requires a host name, it fails if it cannot find a host name to +compare with the pattern. If the above list is given in the opposite order, the +\accept\ statement fails for a host whose name cannot be found, even if its +IP address is 10.9.8.7. + +If you really do want to do the name check first, and still recognize the IP +address, you can rewrite the ACL like this: +.display asis +accept hosts = *.friend.example +accept hosts = 10.9.8.7 +.endd +If the first \accept\ fails, Exim goes on to try the second one. See chapter +~~CHAPACL for details of ACLs. + + + + +.section Address lists +.index list||address list +.index address list||empty item +.index address list||patterns +.rset SECTaddresslist "~~chapter.~~section" +Address lists contain patterns that are matched against mail addresses. There +is one special case to be considered: the sender address of a bounce message is +always empty. You can test for this by providing an empty item in an address +list. For example, you can set up a router to process bounce messages by +using this option setting: +.display asis +senders = : +.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. + +The following kinds of pattern are supported in address lists: +.numberpars $. +.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 +as part of the string expansion. The simplest way to do this is to use \"@\N"\ +to mark that part of the string as non-expandable. For example: +.display asis +deny senders = \N^\d{8}.+@spamhaus.example$\N : ... +.endd +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 @@@@ 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 +(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 +from the file is treated as a colon-separated list of local part patterns, each +of which is matched against the subject local part in turn. + +.index asterisk||in address list +The lookup may be a partial one, and/or one involving a search for a default +keyed by `$*$' (see section ~~SECTdefaultvaluelookups). The local part patterns +that are looked up can be regular expressions or begin with `$*$', or even be +further lookups. They may also be independently negated. For example, with +.display asis +deny senders = @@dbm;/etc/reject-by-domain +.endd +the data from which the DBM file is built could contain lines like +.display asis +baddomain.com: !postmaster : * +.endd +to reject all senders except \postmaster\ from that domain. +.index local part||starting with ! +If a local part that actually begins with an exclamation mark is required, it +has to be specified using a regular expression. In \%lsearch%\ files, an entry +may be split over several lines by indenting the second and subsequent lines, +but the separating colon must still be included at line breaks. White space +surrounding the colons is ignored. For example: +.display asis +aol.com: spammer1 : spammer2 : ^[0-9]+$ : + spammer3 : spammer4 +.endd +As in all colon-separated lists in Exim, a colon can be included in an item by +doubling. + +If the last item in the list starts with a right angle-bracket, the remainder +of the item is taken as a new key to look up in order to obtain a continuation +list of local parts. The new key can be any sequence of characters. Thus one +might have entries like +.display asis +aol.com: spammer1 : spammer 2 : >* +xyz.com: spammer3 : >* +*: ^\d{8}$ +.endd +in a file that was searched with \@@@@dbm$*$\, to specify a match for 8-digit +local parts for all domains, in addition to the specific local parts listed for +each domain. Of course, using this feature costs another lookup each time a +chain is followed, but the effort needed to maintain the data is reduced. +.index loop||in lookups +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 +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: +.display asis +deny senders = *@*.spamming.site:\ + *@+hostile_domains:\ + bozo@partial-lsearch;/list/of/dodgy/sites:\ +.newline + *@dbm;/bad/domains.db +.endd +.index local part||starting with ! +.index address list||local part starting with ! +If a local part that begins with an exclamation mark is required, it has to be +specified using a regular expression, because otherwise the exclamation mark is +treated as a sign of negation. +.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. +.endp + +\**Warning**\: there is an important difference between the address list items +in these two examples: +.display asis +senders = +my_list +senders = *@+my_list +.endd +In the first one, \"my@_list"\ is a named address list, whereas in the second +example it is a named domain list. + + + +.section Case of letters in address lists +.rset SECTcasletadd "~~chapter.~~section" +.index case of local parts +.index address list||case forcing +.index case forcing in address lists +Domains in email addresses are always handled caselessly, but for local parts +case may be significant on some systems (see \caseful@_local@_part\ for how +Exim deals with this when routing addresses). However, RFC 2505 ($it{Anti-Spam +Recommendations for SMTP MTAs}) suggests that matching of addresses to blocking +lists should be done in a case-independent manner. Since most address lists in +Exim are used for this kind of control, Exim attempts to do this by default. + +The domain portion of an address is always lowercased before matching it to an +address list. The local part is lowercased by default, and any string +comparisons that take place are done caselessly. This means that the data in +the address list itself, in files included as plain file names, and in any file +that is looked up using the `@@@@' mechanism, can be in any case. However, the +keys in files that are looked up by a search type other than \%lsearch%\ (which +works caselessly) must be in lower case, because these lookups are not +case-independent. + +.index \"+caseful"\ +To allow for the possibility of caseful address list matching, if an item in +an address list is the string `+caseful', the original case of the local +part is restored for any comparisons that follow, and string comparisons are no +longer case-independent. This does not affect the domain, which remains in +lower case. However, although independent matches on the domain alone are still +performed caselessly, regular expressions that match against an entire address +become case-sensitive after `+caseful' has been seen. + + +.section Local part lists +.rset SECTlocparlis "~~chapter.~~section" +.index list||local part list +.index local part||list +Case-sensitivity in local part lists is handled in the same way as for address +lists, as just described. The `+caseful' item can be used if required. In a +setting of the \local@_parts\ option in a router with \caseful@_local@_part\ +set false, the subject is lowercased and the matching is initially +case-insensitive. In this case, `+caseful' will restore case-sensitive matching +in the local part list, but not elsewhere in the router. If +\caseful@_local@_part\ is set true in a router, matching in the \local@_parts\ +option is case-sensitive from the start. + +If a local part list is indirected to a file (see section ~~SECTfilnamlis), +comments are handled in the same way as address lists -- they are recognized +only if the @# is preceded by white space or the start of the line. +Otherwise, local part lists are matched in the same way as domain lists, except +that the special items that refer to the local host (\"@@"\, \"@@[]"\, +\"@@mx@_any"\, \"@@mx@_primary"\, and \"@@mx@_secondary"\) are not recognized. +Refer to section ~~SECTdomainlist for details of the other available item +types. + + + +. +. +. +. +. ============================================================================ +.chapter String expansions +.set runningfoot "string expansions" +.rset CHAPexpand ~~chapter +.index expansion||of strings +Many strings in Exim's run time configuration are expanded before use. Some of +them are expanded every time they are used; others are expanded only once. + +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 +character, as described in the following section. + + +.section Literal text in expanded strings +.rset SECTlittext "~~chapter.~~section" +.index expansion||including literal text +An uninterpreted dollar can be included in an expanded string by putting a +backslash in front of it. A backslash can be used to prevent any special +character being treated specially in an expansion, including itself. If the +string appears in quotes in the configuration file, two backslashes are +required because the quotes themselves cause interpretation of backslashes when +the string is read in (see section ~~SECTstrings). + +.index expansion||non-expandable substrings +A portion of the string can specified as non-expandable by placing it between +two occurrences of \"@\N"\. This is particularly useful for protecting regular +expressions, which often contain backslashes and dollar signs. For example: +.display asis +deny senders = \N^\d{8}[a-z]@some\.site\.example$\N +.endd +On encountering the first \"@\N"\, the expander copies subsequent characters +without interpretation until it reaches the next \"@\N"\ or the end of the +string. + + +.section Character escape sequences in expanded strings +.index expansion||escape sequences +A backslash followed by one of the letters `n', `r', or `t' in an expanded +string is recognized as an escape sequence for the character newline, carriage +return, or tab, respectively. A backslash followed by up to three octal digits +is recognized as an octal encoding for a single character, and a backslash +followed by `x' and up to two hexadecimal digits is a hexadecimal encoding. + +These escape sequences are also recognized in quoted strings when they are read +in. Their interpretation in expansions as well is useful for unquoted strings, +and for other cases such as looked-up strings that are then expanded. + +.section Testing string expansions +.index expansion||testing +.index testing||string expansion +.index \-be-\ option +Many expansions can be tested by calling Exim with the \-be-\ option. This takes +the command arguments, or lines from the standard input if there are no +arguments, runs them through the string expansion code, and writes the results +to the standard output. Variables based on configuration values are set up, but +since no message is being processed, variables such as \$local@_part$\ have no +value. Nevertheless the \-be-\ option can be useful for checking out file and +database lookups, and the use of expansion operators such as \sg\, \substr\ and +\nhash\. + +Exim gives up its root privilege when it is called with the \-be-\ option, and +instead runs under the uid and gid it was called with, to prevent users from +using \-be-\ for reading files to which they do not have access. + + +.section Expansion items +.rset SECTexpansionitems "~~chapter.~~section" +The following items are recognized in expanded strings. White space may be used +between sub-items that are keywords or substrings enclosed in braces inside an +outer set of braces, to improve readability. \**Warning**\: Within braces, +white space is significant. + +.startitems + +.item "@$<<variable name>>#$rm{or}#@$@{<<variable name>>@}" +.index expansion||variables +Substitute the contents of the named variable, for example +.display asis +$local_part +${domain} +.endd +The second form can be used to separate the name from subsequent alphanumeric +characters. This form (using curly brackets) is available only for variables; +it does $it{not} apply to message headers. The names of the variables are given +in section ~~SECTexpvar below. If the name of a non-existent variable is given, +the expansion fails. + +.item "@$@{<<op>>:<<string>>@}" +.index expansion||operators +The string is first itself expanded, and then the operation specified by <<op>> +is applied to it. For example, +.display asis +${lc:$local_part} +.endd +The string starts with the first character after the colon, which may be +leading white space. A list of operators is given in section ~~SECTexpop below. +The operator notation is used for simple expansion items that have just one +argument, because it reduces the number of braces and therefore makes the +string easier to understand. + +.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 strings). +The key must not consist entirely of digits. The expanded <<string1>> must be +of the form: +.display +<<key1>> = <<value1>> <<key2>> = <<value2>> ... +.endd +where the equals signs and spaces (but not both) are optional. If any of the +values contain white space, they must be enclosed in double quotes, and any +values that are enclosed in double quotes are subject to escape processing as +described in section ~~SECTstrings. The expanded <<string1>> is searched for +the value that corresponds to the key. The search is case-insensitive. If the +key is found, <<string2>> is expanded, and replaces the whole item; otherwise +<<string3>> is used. During the expansion of <<string2>> the variable \$value$\ +contains the value that has been extracted. Afterwards, it is restored to any +previous value it might have had. + +If @{<<string3>>@} is omitted, the item is replaced by an empty string if the +key is not found. If @{<<string2>>@} is also omitted, the value that was +extracted is used. Thus, for example, these two expansions are identical, and +yield `2001': +.display +@$@{extract@{gid@}{uid=1984 gid=2001@}@} +@$@{extract@{gid@}{uid=1984 gid=2001@}@{@$value@}@} +.endd +Instead of @{<<string3>>@} the word `fail' (not in curly brackets) can appear, +for example: +.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. + + +.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. +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 +argument. You can use \$value$\ in <<string2>> or \"fail"\ instead of +<<string3>> as before. + +The fields in the string are separated by any one of the characters in the +separator string. These may include space or tab characters. +The first field is numbered one. If the number is negative, the fields are +counted from the end of the string, with the rightmost one numbered -1. If the +number given is zero, the entire string is returned. If the modulus of the +number is greater than the number of fields in the string, the result is the +expansion of <<string3>>, or the empty string if <<string3>> is not provided. +For example: +.display asis +${extract{2}{:}{x:42:99:& Mailer::/bin/bash}} +.endd +yields `42', and +.display asis +${extract{-4}{:}{x:42:99:& Mailer::/bin/bash}} +.endd +yields `99'. Two successive separators mean that the field between them is +empty (for example, the fifth field above). + + +.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 +(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>> +and <<string2>> do not change when they are expanded, you can use the +simpler operator notation that avoids some of the braces: +.display +@$@{hash@_<<n>>@_<<m>>:<<string>>@} +.endd +The second number is optional (in both notations). + +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 +.display asis +abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQWRSTUVWXYZ0123456789 +.endd +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"\ +.endd + + +.item "@$header@_<<header name>>:#$rm{or}#@$h@_<<header name>>:" +.item "@$bheader@_<<header name>>:#$rm{or}#@$bh@_<<header name>>:" +.item "@$rheader@_<<header name>>:#$rm{or}#@$rh@_<<header name>>:" +.index expansion||header insertion +.index \$header@_$\ +.index \$bheader@_$\ +.index \$rheader@_$\ +.index header lines||in expansion strings +.index header lines||character sets +.index header lines||decoding +Substitute the contents of the named message header line, for example +.display asis +$header_reply-to: +.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. + +The difference between \rheader\, \bheader\, and \header\ is in the way the +data in the header line is interpreted. +.numberpars $. +\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 +.index base64 encoding||in header lines +\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. +.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 +lines. +.nextp +\header\ tries to translate the string as decoded by \bheader\ to a standard +character set. This is an attempt to produce the same string as would be +displayed on a user's MUA. If translation fails, the \bheader\ string is +returned. Translation is attempted only on operating systems that support the +\*iconv()*\ function. This is indicated by the compile-time macro +\\HAVE@_ICONV\\ in a system Makefile or in \(Local/Makefile)\. +.endp + +In a filter file, the target character set for \header\ can be specified by a +command of the following form: +.display asis +headers charset "UTF-8" +.endd +This command affects all references to \$h@_$\ (or \$header@_$\) expansions in +subsequently obeyed filter commands. In the absence of this command, the target +character set in a filter is taken from the setting of the \headers@_charset\ +option in the runtime configuration. The value of this option defaults to the +value of \\HEADERS@_CHARSET\\ in \(Local/Makefile)\. The ultimate default is +ISO-8859-1. + +Header names follow the syntax of RFC 2822, which states that they may contain +any printing characters except space and colon. Consequently, curly brackets +$it{do not} terminate header names, and should not be used to enclose them as +if they were variables. Attempting to do so causes a syntax error. + +Only header lines that are common to all copies of a message are visible to +this mechanism. These are the original header lines that are received with the +message, and any that are added by +an ACL \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. + +For incoming SMTP messages, no header lines are visible in ACLs that are obeyed +before the \\DATA\\ ACL, because the header structure is not set up until the +message is received. Header lines that are added by \warn\ statements in a +\\RCPT\\ ACL (for example) are saved until the message's incoming header lines +are available, at which point they are added. When a \\DATA\\ ACL is running, +however, header lines added by earlier ACLs are visible. + +Upper case and lower case letters are synonymous in header names. If the +following character is white space, the terminating colon may be omitted, but +this is not recommended, because you may then forget it when it is needed. When +white space terminates the header name, 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.) + +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 +character is inserted between each line. +For the \header\ expansion, for those headers that contain lists of addresses, +a comma is also inserted at the junctions between lines. This does not happen +for the \rheader\ expansion. + + + +.item "@$@{hmac@{<<hashname>>@}@{<<secret>>@}@{<<string>>@}@}" +.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. +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 +or SHA-1 alone. +The hash name must expand to either \"md5"\ or \"sha1"\ at present. For +example: +.display asis +${hmac{md5}{somesecret}{$primary_hostname $tod_log}} +.endd +For the hostname \*mail.example.com*\ and time 2002-10-17 11:30:59, this +produces: +.display asis +dd97e3ba5d1a61b5006108f8c8252953 +.endd +As an example of how this might be used, you might put in the main part of +an Exim configuration: +.display asis +SPAMSCAN_SECRET=cohgheeLei2thahw +.endd +In a router or a transport you could then have: +.display asis +headers_add = \ + X-Spam-Scanned: ${primary_hostname} ${message_id} \ + ${hmac{md5}{SPAMSCAN_SECRET}\ + {${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 +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, +.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. + + +.item "@$@{length@{<<string1>>@}@{<<string2>>@}@}" +.index expansion||string truncation +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 +the braces: +.display +@$@{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 +\strlen\, which gives the length of a string. + + +.item "@${lookup@{<<key>>@} <<search type>> @{<<file>>@} @{<<string1>>@} @{<<string2>>@}@}" +.item "@${lookup <<search type>> @{<<query>>@} @{<<string1>>@} @{<<string2>>@}@}" +.index expansion||lookup in +.index file||lookup +.index lookup||in expanded string +These items specify data lookups in files and databases, as discussed in +chapter ~~CHAPfdlookup. The first form is used for single-key lookups, and the +second is used for query-style lookups. The <<key>>, <<file>>, and <<query>> +strings are expanded before use. + +If there is any white space in a lookup item which is part of a filter command, +a retry or rewrite rule, a routing rule for the \%manualroute%\ router, or any +other place where white space is significant, the lookup item must be enclosed +in double quotes. The use of data lookups in users' filter files may be locked +out by the system administrator. + +.index \$value$\ +If the lookup succeeds, <<string1>> is expanded and replaces the entire item. +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. + +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, +and also while <<string2>> of the second lookup is expanded, should the second +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. + +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 +search type to request default lookups if the key does not match (see sections +~~SECTdefaultvaluelookups and ~~SECTpartiallookup for details). + +.index numerical variables (\$1$\, \$2$\, etc)||in lookup expansion +If a partial search is used, the variables \$1$\ and \$2$\ contain the wild +and non-wild parts of the key during the expansion of the replacement text. +They return to their previous values at the end of the lookup item. + +This example looks up the postmaster alias in the conventional alias file: +.display asis +${lookup {postmaster} lsearch {/etc/aliases} {$value}} +.endd +This example uses NIS+ to look up the full name of the user corresponding to +the local part of an address, forcing the expansion to fail if it is not found: +.display asis +${lookup nisplus {[name=$local_part],passwd.org_dir:gcos} \ + {$value}fail} +.endd + + +.item "@$@{nhash@{<<string1>>@}@{<<string2>>@}@{<<string3>>@}@}" +.index expansion||numeric hash +.index hash function||numeric +The three strings are expanded; the first two must yield numbers. Call them +<<n>> and <<m>>. 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 +@$@{nhash@_<<n>>@_<<m>>:<<string>>@} +.endd +The second number is optional (in both notations). If there is only one number, +the result is a number in the range 0--<<n>>-1. Otherwise, the string is +processed by a div/mod hash function that returns two numbers, separated by a +slash, in the ranges 0 to <<n>>-1 and 0 to <<m>>-1, respectively. For example, +.display asis +${nhash{8}{64}{supercalifragilisticexpialidocious}} +.endd +returns the string `6/33'. + + + +.item "@$@{perl@{<<subroutine>>@}@{<<arg>>@}@{<<arg>>@}...@}" +.index Perl||use in expanded string +.index expansion||calling Perl from +This item is available only if Exim has been built to include an embedded Perl +interpreter. The subroutine name and the arguments are first separately +expanded, and then the Perl subroutine is called with those arguments. No +additional arguments need be given; the maximum number permitted, including the +name of the subroutine, is nine. + +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 +context. For example, if you return the name of a Perl vector, the +return value is the size of the vector, not its contents. + +If the subroutine exits by calling Perl's \die\ function, the expansion fails +with the error message that was passed to \die\. More details of the embedded +Perl facility are given in chapter ~~CHAPperl. + +The \%redirect%\ router has an option called \forbid@_filter@_perl\ which locks +out the use of this expansion item in filter files. + + +.item "@$@{readfile@{<<file name>>@}@{<<eol string>>@}@}" +.index expansion||inserting an entire file +.index file||inserting into expansion +The file name and end-of-line string are first expanded separately. The file is +then read, and its contents replace the entire item. All newline characters in +the file are replaced by the end-of-line string if it is present. Otherwise, +newlines are left in the string. +String expansion is not applied to the contents of the file. If you want this, +you must wrap the item in an \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 "@$@{readsocket@{<<name>>@}@{<<request>>@}@{<<timeout>>@}@{<<eol string>>@}@{<<fail string>>@}@}" +.index expansion||inserting from a socket +.index socket, use of in expansion +This item inserts data that is read from a Unix domain socket into the expanded +string. The minimal way of using it uses just two arguments: +.display asis +${readsocket{/socket/name}{request string}} +.endd +Exim connects to the socket, writes the request string (unless it is an +empty string) and reads from the socket until an end-of-file is read. A timeout +of 5 seconds is applied. Additional, optional arguments extend what can be +done. Firstly, you can vary the timeout. For example: +.display asis +${readsocket{/socket/name}{request-string}{3s}} +.endd +A fourth argument allows you to change any newlines that are in the data +that is read, in the same way as for \readfile\ (see above). This example turns +them into spaces: +.display asis +${readsocket{/socket/name}{request-string}{3s}{ }} +.endd +As with all expansions, the substrings are expanded before the processing +happens. Errors in these sub-expansions cause the expansion to fail. In +addition, the following errors can occur: +.numberpars $. +Failure to create a socket file descriptor; +.nextp +Failure to connect the socket; +.nextp +Failure to write the request-string; +.nextp +Timeout on reading from the socket. +.endp +By default, any of these errors causes the expansion to fail. However, if +you supply a fifth substring, it is expanded and used when any of the above +errors occurs. For example: +.display asis +${readsocket{/socket/name}{request-string}{3s}{\n}\ + {socket failure}} +.endd +You can test for the existence of the socket by wrapping this expansion in +\"@$@{if exists"\, but there is a race condition between that test and the +actual opening of the socket, so it is safer to use the fifth argument if you +want to be absolutely sure of avoiding an expansion error for a non-existent +socket. + +The \%redirect%\ router has an option called \forbid@_filter@_readsocket\ 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\ +expansion item above. + + + +.item "@$@{run@{<<command>> <<args>>@}@{<<string1>>@}@{<<string2>>@}@}" +.index expansion||running a command +The command and its arguments are first expanded separately, and then the +command is run in a separate process, but under the same uid and gid. As in +other command executions from Exim, a shell is not used by default. If you want +a shell, you must explicitly code it. +.index return code||from \run\ expansion +If the command succeeds (gives a zero return code) <<string1>> is expanded and +replaces the entire item; during this expansion, the standard output from the +command is in the variable \$value$\. If the command fails, <<string2>>, if +present, is expanded. If it is absent, the result is empty. Alternatively, +<<string2>> can be the word `fail' (not in braces) to force expansion failure +if the command does not succeed. If both strings are omitted, the result is the +standard output on success, and nothing on failure. + +The return code from the command is put in the variable \$runrc$\, and this +remains set afterwards, so in a filter file you can do things like this: +.display asis +if "${run{x y z}{}}$runrc" is 1 then ... + elif $runrc is 2 then ... + ... +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 +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$\ +by the expansion of one option, and use it in another. + +The \%redirect%\ router has an option called \forbid@_filter@_run\ which locks +out the use of this expansion item in filter files. + + +.item "@$@{sg@{<<subject>>@}@{<<regex>>@}@{<<replacement>>@}@}" +.index expansion||string substitution +This item works like Perl's substitution operator (s) with the global (/g) +option; hence its name. However, unlike the Perl equivalent, Exim does not +modify the subject string; instead it returns the modified string for insertion +into the overall expansion. The item takes three arguments: the subject string, +a regular expression, and a substitution string. For example +.display asis +${sg{abcdefabcdef}{abc}{xyz}} +.endd +yields `xyzdefxyzdef'. Because all three arguments are expanded before use, if +any @$ or @\ characters are required in the regular expression or in the +substitution string, they have to be escaped. For example +.display asis +${sg{abcdef}{^(...)(...)\$}{\$2\$1}} +.endd +yields `defabc', and +.display asis +${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 +string expansion. + + + +.item "@$@{substr@{<<string1>>@}@{<<string2>>@}@{<<string3>>@}@}" +.index \substr\ +.index substring extraction +.index expansion||substring extraction +The three strings are expanded; the first two must yield numbers. Call them +<<n>> and <<m>>. 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 +@$@{substr@_<<n>>@_<<m>>:<<string>>@} +.endd +The second number is optional (in both notations). + +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 +required. For example +.display asis +${substr{3}{2}{$local_part}} +.endd +If the starting offset is greater than the string length the result is the null +string; if the length plus starting offset is greater than the string length, +the result is the right-hand part of the string, starting from the given +offset. The first character in the string has offset zero. + +The \substr\ expansion item can take negative offset values to count +from the right-hand end of its operand. The last character is offset -1, the +second-last is offset -2, and so on. Thus, for example, +.display asis +${substr{-5}{2}{1234567}} +.endd +yields `34'. If the absolute value of a negative offset is greater than the +length of the string, the substring starts at the beginning of the string, and +the length is reduced by the amount of overshoot. Thus, for example, +.display asis +${substr{-5}{2}{12}} +.endd +yields an empty string, but +.display asis +${substr{-3}{2}{12}} +.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 +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. + + + +.item "@$@{tr@{<<subject>>@}@{<<characters>>@}@{<<replacements>>@}@}" +.index expansion||character translation +This item does single-character translation on its subject string. The second +argument is a list of characters to be translated in the subject string. Each +matching character is replaced by the corresponding character from the +replacement list. For example +.display asis +${tr{abcdea}{ac}{13}} +.endd +yields `1b3de1'. If there are duplicates in the second character string, the +last occurrence is used. If the third string is shorter than the second, its +last character is replicated. However, if it is empty, no translation takes +place. + +.enditems + + +.section Expansion operators +.rset SECTexpop "~~chapter.~~section" +.index expansion||operators +For expansion items that perform transformations on a single argument string, +the `operator' notation is used because it is simpler and uses fewer braces. +The substring is first expanded before the operation is applied to it. The +following operations can be performed: + +.startitems + +.item "@$@{address:<<string>>@}" +.index expansion||RFC 2822 address handling +The string is interpreted as an RFC 2822 address, as it might appear in a +header line, and the effective address is extracted from it. If the string does +not parse successfully, the result is empty. + + +.item "@$@{base62:<<digits>>@}" +.index base62 +.index expansion||conversion to base 62 +The string must consist entirely of decimal digits. The number is converted to +base 62 (sic) and output as a string of six characters, including leading +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>>@}" +.index domain||extraction +.index expansion||domain extraction +The string is interpreted as an RFC 2822 address and the domain is extracted +from it. If the string does not parse successfully, the result is empty. + + +.item "@$@{escape:<<string>>@}" +.index expansion||escaping non-printing characters +If the string contains any non-printing characters, they are converted to +escape sequences starting with a backslash. Whether characters with the most +significant bit set (so-called `8-bit characters') count as printing or not is +controlled by the \print@_topbitchars\ option. + + +.em +.item "@$@{eval:<<string>>@}" +.item "@$@{eval10:<<string>>@}" +.index expansion||expression evaluation +.index expansion||arithmetic expression +These items supports simple arithmetic in expansion strings. The string (after +expansion) must be a conventional arithmetic expression, but it is limited to +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. + +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 +a decimal representation of the answer (without `K' or `M'). For example: +.display + @$@{eval:1+1@} $rm{yields} 2 + @$@{eval:1+2*3@} $rm{yields} 7 + @$@{eval:(1+2)*3@} $rm{yields} 9 +.endd +As a more realistic example, in an ACL you might have +.display asis +deny message = Too many bad recipients + condition = \ + ${if and { \ + {>{$rcpt_count}{10}} \ + { \ + < \ + {$recipients_count} \ + {${eval:$rcpt_count/2}} \ + } \ + }{yes}{no}} +.endd +The condition is true if there have been more than 10 \\RCPT\\ commands and +fewer than half of them have resulted in a valid recipient. + + +.item "@$@{expand:<<string>>@}" +.index expansion||re-expansion of substring +The \expand\ operator causes a string to be expanded for a second time. For +example, +.display asis +${expand:${lookup{$domain}dbm{/some/file}{$value}}} +.endd +first looks up a string in a file while expanding the operand for \expand\, and +then re-expands what it has found. + + +.item "@$@{from@_utf8:<<string>>@}" +.index Unicode +.index UTF-8||conversion from +.index expansion||UTF-8 conversion +The world is slowly moving towards Unicode, although there are no standards for +email yet. However, other applications (including some databases) are starting +to store data in Unicode, using UTF-8 encoding. This operator converts from a +UTF-8 string to an ISO-8859-1 string. UTF-8 code values greater than 255 are +converted to underscores. The input must be a valid UTF-8 string. If it is not, +the result is an undefined sequence of bytes. + +Unicode code points with values less than 256 are compatible with ASCII and +ISO-8859-1 (also known as Latin-1). +For example, character 169 is the copyright symbol in both cases, though the +way it is encoded is different. In UTF-8, more than one byte is needed for +characters with code values greater than 127, whereas ISO-8859-1 is a +single-byte encoding (but thereby limited to 256 characters). This makes +translation from UTF-8 to ISO-8859-1 straightforward. + + +.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 +change when expanded). The effect is the same as +.display +@$@{hash@{<<n>>@}@{<<m>>@}@{<<string>>@}@} +.endd +See the description of the general \hash\ item above for details. The +abbreviation \h\ can be used when \hash\ is used as an operator. + + + +.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 +be useful for processing the output of the MD5 and SHA-1 hashing functions. + + +.item "@$@{lc:<<string>>@}" +.index case forcing in strings +.index string||case forcing +.index lower casing +.index expansion||case forcing +This forces the letters in the string into lower-case, for example: +.display asis +${lc:$local_part} +.endd + + +.item "@$@{length@_<<number>>:<<string>>@}" +.index expansion||string truncation +The \length\ operator is a simpler interface to the \length\ function that can +be used when the parameter is a fixed number (as opposed to a string that +changes when expanded). The effect is the same as +.display +@$@{length@{<<number>>@}@{<<string>>@}@} +.endd +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 "@$@{local@_part:<<string>>@}" +.index expansion||local part extraction +The string is interpreted as an RFC 2822 address and the local part is +extracted from it. If the string does not parse successfully, the result is +empty. + + +.item "@$@{mask:<<IP address>>/<<bit count>>@}" +.index masked IP address +.index IP address||masking +.index CIDR notation +.index expansion||IP address masking +If the form of the string to be operated on is not an IP address followed by a +slash and an integer (that is, a network address in CIDR notation), the +expansion fails. Otherwise, this operator converts the IP address to binary, +masks off the least significant bits according to the bit count, and converts +the result back to text, with mask appended. For example, +.display asis +${mask:10.111.131.206/28} +.endd +returns the string `10.111.131.192/28'. Since this operation is expected to be +mostly used for looking up masked addresses in files, the result for an IPv6 +address uses dots to separate components instead of colons, because colon +terminates a key string in lsearch files. So, for example, +.display asis +${mask:3ffe:ffff:836f:0a00:000a:0800:200a:c031/99} +.endd +returns the string +.display asis +3ffe.ffff.836f.0a00.000a.0800.2000.0000/99 +.endd +Letters in IPv6 addresses are always output in lower case. + + +.item "@$@{md5:<<string>>@}" +.index MD5 hash +.index expansion||MD5 hash +The \md5\ operator computes the MD5 hash value of the string, and returns it as +a 32-digit hexadecimal number, +in which any letters are in lower case. + + +.item "@$@{nhash@_<<n>>@_<<m>>:<<string>>@}" +.index expansion||numeric hash +.index hash function||numeric +The \nhash\ operator is a simpler interface to the numeric hashing function +that can be used when the two parameters are fixed numbers (as opposed to +strings that change when expanded). The effect is the same as +.display +@$@{nhash@{<<n>>@}@{<<m>>@}@{<<string>>@}@} +.endd +See the description of the general \nhash\ item above for details. + + +.item "@$@{quote:<<string>>@}" +.index quoting||in string expansions +.index expansion||quoting +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. +Newlines and carriage returns are converted to \"@\n"\ and \"@\r"\, +respectively For example, +.display asis +${quote:ab"*"cd} +.endd +becomes +.display asis +"ab\"*\"cd" +.endd +The place where this is useful is when the argument is a substitution from a +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 +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. + + +.item "@$@{quote@_<<lookup-type>>:<<string>>@}" +.index quoting||lookup-specific +This operator applies lookup-specific quoting rules to the string. Each +query-style lookup type has its own quoting rules which are described with +the lookups in chapter ~~CHAPfdlookup. For example, +.display asis +${quote_ldap:two * two} +.endd +returns +.display asis +two%20%5C2A%20two +.endd +For single-key lookup types, no quoting is ever necessary and this operator +yields an unchanged string. + + +.item "@$@{rxquote:<<string>>@}" +.index quoting||in regular expressions +.index regular expressions||quoting +The \rxquote\ operator inserts a backslash before any non-alphanumeric +characters in its argument. This is useful when substituting the values of +variables or headers inside regular expressions. + + +.item "@$@{rfc2047:<<string>>@}" +.index expansion||RFC 2047 +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 +.display asis +? = ( ) < > @ , ; : \ " . [ ] _ +.endd +it is not modified. Otherwise, the result is the RFC 2047 encoding, as a single +`coded word'. + + +.item "@$@{sha1:<<string>>@}" +.index SHA-1 hash +.index expansion||SHA-1 hashing +The \sha1\ operator computes the SHA-1 hash value of the string, and returns it +as a 40-digit hexadecimal number, in which any letters are in upper case. + + +.item "@$@{stat:<<string>>@}" +.index expansion||statting a file +.index file||extracting characteristics +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, +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', +`uid', `gid', `size', `atime', `mtime', and `ctime'. You can extract individual +fields using the \extract\ expansion item. \**Warning**\: The file size may be +incorrect on 32-bit systems for files larger than 2GB. + + +.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 +decimal number. \**Note**\: Do not confuse \strlen\ with \length\. + + +.item "@$@{substr@_<<start>>@_<<length>>:<<string>>@}" +.index \substr\ +.index substring extraction +.index expansion||substring expansion +The \substr\ operator is a simpler interface to the \substr\ 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 +@$@{substr@{<<start>>@}@{<<length>>@}@{<<string>>@}@} +.endd +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 +The argument (after sub-expansion) must be a sequence of decimal digits that +represents an interval of time as a number of seconds. It is converted into a +number of larger units and output in Exim's normal time format, for example, +\"1w3d4h2m6s"\. +.nem + +.item "@$@{uc:<<string>>@}" +.index case forcing in strings +.index string||case forcing +.index upper casing +.index expansion||case forcing +This forces the letters in the string into upper-case. + +.enditems + + + +.section Expansion conditions +.rset SECTexpcond "~~chapter.~~section" +.index expansion||conditions +The following conditions are available for testing by the \@$@{if\ construct +while expanding strings: + +.startitems + +.item "!<<condition>>" +.index expansion||negating a condition +Preceding any condition with an exclamation mark negates the result of the +condition. + +.item "<<symbolic operator>> @{<<string1>>@}@{<<string2>>@}" +.index numeric comparison +.index expansion||numeric comparison +There are a number of symbolic operators for doing numeric comparisons. They +are: +.display +.tabs 8 += $t $rm{equal} +== $t $rm{equal} +> $t $rm{greater} +>= $t $rm{greater or equal} +< $t $rm{less} +<= $t $rm{less or equal} +.endd +For example, +.display asis +${if >{$message_size}{10M} ... +.endd +Note that the general negation operator provides for inequality testing. The +two strings must take the form of optionally signed decimal integers, +optionally followed by one of the letters `K' or `M' (in either upper or lower +case), signifying multiplication by 1024 or 1024$*$1024, respectively. + +.item "crypteq @{<<string1>>@}@{<<string2>>@}" +.index expansion||encrypted comparison +.index encrypted strings, comparing +This condition is included in the Exim binary if it is built to support any +authentication mechanisms (see chapter ~~CHAPSMTPAUTH). Otherwise, it is +necessary to define \\SUPPORT@_CRYPTEQ\\ in \(Local/Makefile)\ to get \crypteq\ +included in the binary. + +The \crypteq\ condition has two arguments. The first is encrypted and compared +against the second, which is already encrypted. The second string may be in the +LDAP form for storing encrypted strings, which starts with the encryption type +in curly brackets, followed by the data. If the second string does not begin +with `{' it is assumed to be encrypted with \*crypt()*\ +or \*crypt16()*\ (see below), +since such strings cannot begin with `{'. Typically this will be a field from a +password file. + +An example of an encrypted string in LDAP form is: +.display asis +{md5}CY9rzUYh03PK3k6DJie09g== +.endd +If such a string appears directly in an expansion, the curly brackets have to +be quoted, because they are part of the expansion syntax. For example: +.display asis +${if crypteq {test}{\{md5\}CY9rzUYh03PK3k6DJie09g==}{yes}{no}} +.endd +The following encryption types +(whose names are matched case-independently) +are supported: +.numberpars $. +.index MD5 hash +.index base64 encoding||in encrypted password +\@{md5@}\ computes the MD5 digest of the first string, and expresses this as +printable characters to compare with the remainder of the second string. If the +length of the comparison string is 24, Exim assumes that it is base64 encoded +(as in the above example). If the length is 32, Exim assumes that it is a +hexadecimal encoding of the MD5 digest. If the length not 24 or 32, the +comparison fails. +.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 +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. +.nextp +.index \*crypt16()*\ +\@{crypt16@}\ calls the \*crypt16()*\ function (also known as \*bigcrypt()*\), +which uses up to 16 characters of the password. +.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 +support \*crypt16()*\. + +If you do not put any curly bracket encryption type in a \crypteq\ comparison, +the default is either \"@{crypt@}"\ or \"@{crypt16@}"\, as determined by the +setting of \\DEFAULT@_CRYPT\\ in \(Local/Makefile)\. The default default is +\"@{crypt@}"\. Whatever the default, you can always use either function by +specifying it explicitly in curly brackets. + +Note that if a password is no longer than 8 characters, the results of +encrypting it with \*crypt()*\ and \*crypt16()*\ are identical. That means that +\*crypt16()*\ is backwards compatible, as long as nobody feeds it a password +longer than 8 characters. + + +.item "def:<<variable name>>" +.index expansion||checking for empty variable +The \def\ condition must be followed by the name of one of the expansion +variables defined in section ~~SECTexpvar. The condition is true if the named +expansion variable does not contain the empty string, for example +.display asis +${if def:sender_ident {from $sender_ident}} +.endd +Note that the variable name is given without a leading \@$\ character. If the +variable does not exist, the expansion fails. + +.item "def:header@_<<header name>>:##or##def:h@_<<header name>>:" +.index expansion||checking header line existence +This condition is true if a message is being processed and the named header +exists in the message. For example, +.display asis +${if def:header_reply-to:{$h_reply-to:}{$h_from:}} +.endd +Note that no \@$\ appears before \header@_\ or \h@_\ in the condition, +and that header names must be terminated by colons if white space does not +follow. + +.item "eq @{<<string1>>@}@{<<string2>>@}" +.item "eqi @{<<string1>>@}@{<<string2>>@}" +.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 +letters, whereas for \eqi\ the comparison is case-independent. + +.item "exists @{<<file name>>@}" +.index expansion||file existence test +.index file||existence test +The substring is first expanded and then interpreted as an absolute path. The +condition is true if the named file (or directory) exists. The existence test +is done by calling the \*stat()*\ function. The use of the \exists\ test in +users' filter files may be locked out by the system administrator. + +.item "first@_delivery" +.index delivery||first +.index first delivery +.index expansion||first delivery test +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 +.index expansion||string comparison +The two substrings are first expanded. The condition is true if the first +string is lexically greater than or equal to the second string: for \ge\ the +comparison includes the case of letters, whereas for \gei\ the comparison is +case-independent. + +.item "gt @{<<string1>>@}@{<<string2>>@}" +.item "gti @{<<string1>>@}@{<<string2>>@}" +.index string||comparison +.index expansion||string comparison +The two substrings are first expanded. The condition is true if the first +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 +example, you could use +.display asis +${if isip4{$sender_host_address}... +.endd +to test which version of IP an incoming SMTP connection is using. + + +.item "ldapauth @{<<ldap query>>@}" +.index LDAP||use for authentication +.index expansion||LDAP authentication test +This condition supports user authentication using LDAP. See section ~~SECTldap +for details of how to use LDAP in lookups and the syntax of queries. For this +use, the query must contain a user name and password. The query itself is not +used, and can be empty. The condition is true if +the password is not empty, and the user name and password are accepted by the +LDAP server. An empty password is rejected without calling LDAP because LDAP +binds with an empty password are considered anonymous regardless of +the username, and will succeed in most configurations. +See chapter ~~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 +.index expansion||string comparison +The two substrings are first expanded. The condition is true if the first +string is lexically less than or equal to the second string: for \le\ the +comparison includes the case of letters, whereas for \lei\ the comparison is +case-independent. + +.item "lt @{<<string1>>@}@{<<string2>>@}" +.item "lti @{<<string1>>@}@{<<string2>>@}" +.index string||comparison +.index expansion||string comparison +The two substrings are first expanded. The condition is true if the first +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>>@}" +.index expansion||regular expression comparison +.index regular expressions||match in expanded string +The two substrings are first expanded. The second is then treated as a regular +expression and applied to the first. Because of the pre-expansion, if the +regular expression contains dollar, or backslash characters, they must be +escaped. Care must also be taken if the regular expression contains braces +(curly brackets). A closing brace must be escaped so that it is not taken as a +premature termination of <<string2>>. The easiest approach is to use the +\"@\N"\ feature to disable expansion of the regular expression. +For example, +.display asis +${if match {$local_part}{\N^\d{3}\N} ... +.endd +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 +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 \"@$"\ +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 +substitutions \$1$\ etc. are remembered. Obeying a \match\ condition that +succeeds causes them to be reset to the substrings of that condition and they +will have these values during the expansion of the success string. At the end +of the \if\ expansion, the previous values are restored. After testing a +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>>@}" +.index domain list||in expansion condition +.index address list||in expansion condition +.index local part list||in expansion condition +These conditions make it possible to test domain, address, and local +part lists within expansions. Each condition requires two arguments: an item +and a list to match. A trivial example is: +.display asis +${if match_domain{a.b.c}{x.y.z:a.b.c:p.q.r}{yes}{no}} +.endd +In each case, the second argument may contain any of the allowable items for a +list of the appropriate type. Also, because the second argument (after +expansion) is a standard form of list, it is possible to refer to a named list. +Thus, you can use conditions like this: +.display asis +${if match_domain{$domain}{+local_domains}{... +.endd +.index \"+caseful"\ +For address lists, the matching starts off caselessly, but the \"+caseful"\ +item can be used, as in all address lists, to cause subsequent items to +have their local parts matched casefully. Domains are always matched +caselessly. + +\**Note**\: Host lists are \*not*\ supported in this way. This is because +hosts have two identities: a name and an IP address, and it is not clear +how to specify cleanly how such a test would work. At least, I haven't come +up with anything yet. +.nem + +.item "pam {<<string1>>:<<string2>>:...@}" +.index PAM authentication +.index \\AUTH\\||with PAM +.index Solaris||PAM support +.index expansion||PAM authentication test +\*Pluggable Authentication Modules*\ +(\?http://www.kernel.org/pub/linux/libs/pam/?\) +are a facility which is available in the latest releases of Solaris and in some +GNU/Linux distributions. The Exim support, which is intended for use in +conjunction with the SMTP \\AUTH\\ command, is available only if Exim is +compiled with +.display asis +SUPPORT_PAM=yes +.endd +in \(Local/Makefile)\. You probably need to add \-lpam-\ to \\EXTRALIBS\\, and +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. +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 +remaining items in the data string are passed over in response to requests from +the authentication function. In the simple case there will only be one request, +for a password, so the data consists of just two strings. + +There can be problems if any of the strings are permitted to contain colon +characters. In the usual way, these have to be doubled to avoid being taken as +separators. If the data is being inserted from a variable, the \sg\ expansion +item can be used to double any existing colons. For example, the configuration +of a LOGIN authenticator might contain this setting: +.display asis +server_condition = ${if pam{$1:${sg{$2}{:}{::}}}{yes}{no}} +.endd +For a PLAIN authenticator you could use: +.display asis +server_condition = ${if pam{$2:${sg{$3}{:}{::}}}{yes}{no}} +.endd +In some operating systems, PAM authentication can be done only from a process +running as root. Since Exim is running as the Exim user when receiving +messages, this means that PAM cannot be used directly in those systems. +A patched version of the \*pam@_unix*\ module that comes with the +Linux PAM package is available from \?http:@/@/www.e-admin.de/pam@_exim/?\. +The patched module allows one special uid/gid combination, in addition to root, +to authenticate. If you build the patched module to allow the Exim user and +group, PAM can then be used from an Exim authenticator. + + +.item "pwcheck {<<string1>>:<<string2>>@}" +.index \*pwcheck*\ daemon +.index Cyrus +.index expansion||\*pwcheck*\ authentication test +This condition supports user authentication using the Cyrus \*pwcheck*\ daemon. +This is one way of making it possible for passwords to be checked by a process +that is not running as root. +\**Note:**\ The use of \*pwcheck*\ is now deprecated. Its replacement is +\*saslauthd*\ (see below). + +The pwcheck support is not included in Exim by default. You need to specify +the location of the pwcheck daemon's socket in \(Local/Makefile)\ before +building Exim. For example: +.display asis +CYRUS_PWCHECK_SOCKET=/var/pwcheck/pwcheck +.endd +You do not need to install the full Cyrus software suite in order to use +the pwcheck daemon. You can compile and install just the daemon alone +from the Cyrus SASL library. Ensure that \*exim*\ is the only user that has +access to the \(/var/pwcheck)\ directory. + +The \pwcheck\ condition takes one argument, which must be the user name and +password, separated by a colon. For example, in a LOGIN authenticator +configuration, you might have this: +.display asis +server_condition = ${if pwcheck{$1:$2}{1}{0}} +.endd + +.item "queue@_running" +.index queue runner||detecting when delivering from +.index expansion||queue runner test +This condition, which has no data, is true during delivery attempts that are +initiated by queue runner processes, and false otherwise. + + +.item "radius {<<authentication string>>@}" +.index Radius +.index expansion||Radius authentication +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. +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 +.display +server@_condition = @$@{if radius@{<<arguments>>@}@{yes@}@{no@}@} +.endd + + + +.item "saslauthd @{@{<<user>>@}@{<<password>>@}@{<<service>>@}@{<<realm>>@}@}" +.index \*saslauthd*\ daemon +.index Cyrus +.index expansion||\*saslauthd*\ authentication test +This condition supports user authentication using the Cyrus \*saslauthd*\ +daemon. This replaces the older \*pwcheck*\ daemon, which is now deprecated. +Using this daemon is one way of making it possible for passwords to be checked +by a process that is not running as root. + +The saslauthd support is not included in Exim by default. You need to specify +the location of the saslauthd daemon's socket in \(Local/Makefile)\ before +building Exim. For example: +.display asis +CYRUS_SASLAUTHD_SOCKET=/var/state/saslauthd/mux +.endd +You do not need to install the full Cyrus software suite in order to use +the saslauthd daemon. You can compile and install just the daemon alone +from the Cyrus SASL library. + +Up to four arguments can be supplied to the \saslauthd\ condition, but only two +are mandatory. For example: +.display asis +server_condition = ${if saslauthd{{$1}{$2}}{1}{0}} +.endd +The service and the realm are optional (which is why the arguments are enclosed +in their own set of braces). For details of the meaning of the service and +realm, and how to run the daemon, consult the Cyrus documentation. + +.enditems + + + +.section Combining expansion conditions +.index expansion||combining conditions +Several conditions can be tested at once by combining them using the \and\ and +\or\ combination conditions. Note that \and\ and \or\ are complete conditions +on their own, and precede their lists of sub-conditions. Each sub-condition +must be enclosed in braces within the overall braces that contain the list. No +repetition of \if\ is used. + +.startitems + +.item "or @{@{<<cond1>>@}@{<<cond2>>@}...@}" +.index `or' expansion condition +.index expansion||`or' of conditions +The sub-conditions are evaluated from left to right. The condition is true if +any one of the sub-conditions is true. +For example, +.display asis +${if or {{eq{$local_part}{spqr}}{eq{$domain}{testing.com}}}... +.endd +When a true sub-condition is found, the following ones are parsed but not +evaluated. If there are several `match' sub-conditions the values of the +numeric variables afterwards are taken from the first one that succeeds. + +.item "and @{@{<<cond1>>@}@{<<cond2>>@}...@}" +.index `and' expansion condition +.index expansion||`and' of conditions +The sub-conditions are evaluated from left to right. The condition is true if +all of the sub-conditions are true. If there are several `match' +sub-conditions, the values of the numeric variables afterwards are taken from +the last one. When a false sub-condition is found, the following ones are +parsed but not evaluated. + +.enditems + + + +.section Expansion variables +.rset SECTexpvar "~~chapter.~~section" +.index expansion||variables, list of + +The variables that are available for use in expansion strings are: + +.push +.indent 2em +.tempindent 0 +.index numerical variables (\$1$\, \$2$\, etc) +\$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\ +expansion item. They may also be set externally by some other matching process +which precedes the expansion of the string. For example, the commands available +in Exim filter files include an \if\ command with its own regular expression +matching condition. + +.tempindent 0 +\$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. +When a message is received, the values of these variables are saved with the +message, and can be accessed by filters, routers, and transports during +subsequent delivery. + +.tempindent 0 +\$acl@_m0$\ -- \$acl@_m9$\: Values can be placed in these variables by the +\set\ modifier in an ACL. They retain their values while a message is being +received, but are reset afterwards. They are also reset by \\MAIL\\, \\RSET\\, +\\EHLO\\, \\HELO\\, and after starting a TLS session. +When a message is received, the values of these variables are saved with the +message, and can be accessed by filters, routers, and transports during +subsequent delivery. + + +.tempindent 0 +\$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. + +.tempindent 0 +\$address@_data$\: This variable is set by means of the \address@_data\ +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. + +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. + +.tempindent 0 +\$address@_file$\: When, as a result of aliasing, forwarding, or filtering, a +message is directed to a specific file, this variable holds the name of the +file when the transport is running. At other times, the variable is empty. For +example, using the default configuration, if user \r2d2\ has a \(.forward)\ +file containing +.display asis +/home/r2d2/savemail +.endd +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 +to the relevant file. + + +.tempindent 0 +\$address@_pipe$\: When, as a result of aliasing or forwarding, a message is +directed to a pipe, this variable holds the pipe command when the transport is +running. + +.index authentication||id +.tempindent 0 +\$authenticated@_id$\: When a server successfully authenticates a client it may +be configured to preserve some of the authentication information in the +variable \$authenticated@_id$\ (see chapter ~~CHAPSMTPAUTH). For example, a +user/password authenticator configuration might preserve the user name for use +in the routers. When a message is submitted locally (that is, not over a TCP +connection), the value of \$authenticated@_id$\ is the login name of the +calling process. + +.index sender||authenticated +.index authentication||sender +.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 +in the \$authenticated@_sender$\ variable. If the sender is not trusted, Exim +accepts the syntax of \\AUTH=\\, but ignores the data. + +When a message is submitted locally (that is, not over a TCP connection), the +value of \$authenticated@_sender$\ is an address constructed from the login +name of the calling process and \$qualify@_domain$\. + + +.index authentication||failure +.tempindent 0 +\$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' +(\$sender@_host@_authenticated$\ is empty and \$authentication__failed$\ is set +to `0') and `tried to authenticate but failed' (\$sender@_host@_authenticated$\ +is empty and \$authentication@_failed$\ is set to `1'). Failure includes any +negative response to an \\AUTH\\ command, including (for example) an attempt to +use an undefined mechanism. + + +.index message||body, line count +.index body of message||line count +.tempindent 0 +\$body@_linecount$\: +When a message is being received or delivered, this variable contains the +number of lines in the message's body. + +.index message||body, binary zero count +.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$\: +This is set to the recipient address of a bounce message while Exim is creating +it. It is useful if a customized bounce message text file is in use (see +chapter ~~CHAPemsgcust). + +.tempindent 0 +\$bounce@_return@_size@_limit$\: This contains the value set in the +\bounce@_return@_size@_limit\ option, rounded up to a multiple of 1000. It is +useful when a customized error message text file is in use (see chapter +~~CHAPemsgcust). + +.index gid (group id)||caller +.tempindent 0 +\$caller@_gid$\: The +.em +real +.nem +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 +incarnation normally contains the Exim gid. + +.index uid (user id)||caller +.tempindent 0 +\$caller@_uid$\: The +.em +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 +incarnation normally contains the Exim uid. + +.tempindent 0 +\$compile@_date$\: The date on which the Exim binary was compiled. + +.tempindent 0 +\$compile@_number$\: The building process for Exim keeps a count of the number +of times it has been compiled. This serves to distinguish different +compilations of the same version of the program. + +.index black list (DNS) +.tempindent 0 +\$dnslist@_domain$\: When a client host is found to be on a DNS (black) list, +the list's domain name is put into this variable so that it can be included in +the rejection message. + +.tempindent 0 +\$dnslist@_text$\: When a client host is found to be on a DNS (black) list, the +contents of any associated TXT record are placed in this variable. + +.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 +separated. + +.tempindent 0 +\$domain$\: When an address is being routed, or delivered on its own, this +variable contains the domain. Global address rewriting happens when a message +is received, so the value of \$domain$\ during routing and delivery is the +value after rewriting. \$domain$\ is set during user filtering, but not during +system filtering, because a message may have many recipients and the system +filter is called just once. + +When more than one address is being delivered at once (for example, several +\\RCPT\\ commands in one SMTP delivery), \$domain$\ is set only if they all +have the same domain. Transports can be restricted to handling only one domain +at a time if the value of \$domain$\ is required at transport time -- this is +the default for local transports. For further details of the environment in +which local transports are run, see chapter ~~CHAPenvironment. + +.index \delay@_warning@_condition\ +At the end of a delivery, if all deferred addresses have the same domain, it is +set in \$domain$\ during the expansion of \delay@_warning@_condition\. + +The \$domain$\ variable is also used in some other circumstances: +.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\\ +ACL. +.nextp +When a rewrite item is being processed (see chapter ~~CHAPrewrite), \$domain$\ +contains the domain portion of the address that is being rewritten; it can be +used in the expansion of the replacement address, for example, to rewrite +domains by file lookup. +.nextp +With one important exception, whenever a domain list is being scanned, +\$domain$\ contains the subject domain. \**Exception**\: When a domain list in +a \sender@_domains\ condition in an ACL is being processed, the subject domain +is in \$sender@_address@_domain$\ and not in \$domain$\. It works this way so +that, in a \\RCPT\\ ACL, the sender domain list can be dependent on the +recipient domain (which is what is in \$domain$\ at this time). +.nextp +.index \\ETRN\\||value of \$domain$\ +.index \smtp@_etrn@_command\ +When the \smtp@_etrn@_command\ option is being expanded, \$domain$\ contains +the complete argument of the \\ETRN\\ command (see section ~~SECTETRN). +.endp + +.tempindent 0 +\$domain@_data$\: When the \domains\ option on a router matches a domain by +means of a lookup, the data read by the lookup is available during the running +of the router as \$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. + +\$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@_path$\: This variable contains the path to the Exim binary. + +.tempindent 0 +\$exim@_uid$\: This variable contains the numerical value of the Exim user id. +.nem + +.tempindent 0 +\$header@_<<name>>$\: This is not strictly an expansion variable. It is +expansion syntax for inserting the message header line with the given name. +Note that the name must be terminated by colon or white space, because it may +contain a wide variety of characters. +Note also that braces must \*not*\ be used. + +.tempindent 0 +\$home$\: +When the \check@_local@_user\ option is set for a router, the user's home +directory is placed in \$home$\ when the check succeeds. In particular, this +means it is set during the running of users' filter files. A router may also +explicitly set a home directory for use by a transport; this can be overridden +by a setting on the transport itself. + +When running a filter test via the \-bf-\ option, \$home$\ is set to the value +of the environment variable \\HOME\\. + +.tempindent 0 +\$host$\: +When the \%smtp%\ transport is expanding its options for encryption using TLS, +\$host$\ contains the name of the host to which it is connected. Likewise, when +used in the client part of an authenticator configuration (see chapter +~~CHAPSMTPAUTH), \$host$\ contains the name of the server to which the client +is connected. +.index transport||filter +.index filter||transport filter +When used in a transport filter (see chapter ~~CHAPtransportgeneric) \$host$\ +refers to the host involved in the current connection. When a local transport +is run as a result of a router that sets up a host list, \$host$\ contains the +name of the first host. + +.tempindent 0 +\$host@_address$\: +This variable is set to the remote host's IP address whenever \$host$\ is set +for a remote connection. + +.tempindent 0 +\$host@_data$\: +If a \hosts\ condition in an ACL is satisfied by means of a lookup, the result +of the lookup is made available in the \$host@_data$\ variable. This +allows you, for example, to do things like this: +.display asis +deny hosts = net-lsearch;/some/file + message = $host_data +.endd + +.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. +.nem + +.tempindent 0 +\$inode$\: +The only time this variable is set is while expanding the \directory@_file\ +option in the \%appendfile%\ transport. The variable contains the inode number +of the temporary file which is about to be renamed. It can be used to construct +a unique name for the file. + +.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 +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 +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 +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 +variable is 210. The value is recomputed every time the variable is referenced. + +.tempindent 0 +\$local@_part$\: When an address is being routed, or delivered on its own, this +variable contains the local part. When a number of addresses are being +delivered together (for example, multiple \\RCPT\\ commands in an SMTP +session), \$local@_part$\ is not set. + +Global address rewriting happens when a message is received, so the value of +\$local@_part$\ during routing and delivery is the value after rewriting. +\$local@_part$\ is set during user filtering, but not during system filtering, +because a message may have many recipients and the system filter is called just +once. + +If a local part prefix or suffix has been recognized, it is not included in the +value of \$local@_part$\ during routing and subsequent delivery. The values of +any prefix or suffix are in \$local@_part@_prefix$\ and +\$local@_part@_suffix$\, respectively. + +When a message is being delivered to a file, pipe, or autoreply transport as a +result of aliasing or forwarding, \$local@_part$\ is set to the local part of +the parent address, not to the file name or command (see \$address@_file$\ and +\$address@_pipe$\). + +When an ACL is running for a \\RCPT\\ command, \$local@_part$\ contains the +local part of the recipient address. + +When a rewrite item is being processed (see chapter ~~CHAPrewrite), +\$local@_part$\ contains the local part of the address that is being rewritten; +it can be used in the expansion of the replacement address, for example. + +In all cases, all quoting is removed from the local part. For example, for both +the addresses +.display asis +"abc:xyz"@test.example +abc\:xyz@test.example +.endd +the value of \$local@_part$\ is +.display asis +abc:xyz +.endd +If you use \$local@_part$\ to create another address, you should always wrap it +inside a quoting operator. For example, in a \%redirect%\ router you could have: +.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 +\caseful@_local@_part\ option (see chapter ~~CHAProutergeneric). +.nem + +.tempindent 0 +\$local@_part@_data$\: +When the \local@_parts\ option on a router matches a local part by means of a +lookup, the data read by the lookup is available during the running of the +router as \$local@_part@_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. + +\$local@_part@_data$\ is also set when the \local@_parts\ condition in an ACL +matches a local part by means of a lookup. The data read by the lookup is +available during the rest of the ACL statement. In all other situations, this +variable expands to nothing. + +.tempindent 0 +\$local@_part@_prefix$\: When an address is being routed or delivered, and a +specific prefix for the local part was recognized, it is available in this +variable, having been removed from \$local@_part$\. + +.tempindent 0 +\$local@_part@_suffix$\: When an address is being routed or delivered, and a +specific suffix for the local part was recognized, it is available in this +variable, having been removed from \$local@_part$\. + +.tempindent 0 +\$local@_scan@_data$\: This variable contains the text returned by the +\*local@_scan()*\ function when a message is received. See chapter +~~CHAPlocalscan for more details. + +.tempindent 0 +\$local@_user@_gid$\: See \$local@_user@_uid$\. + +.tempindent 0 +\$local@_user@_uid$\: This variable and \$local@_user@_gid$\ are set to +the uid and gid after the \check__local__user\ router precondition succeeds. +This means that their values are available for the remaining preconditions +(\senders\, \require@_files\, and \condition\), for the \address@_data\ +expansion, and for any router-specific expansions. At all other times, the +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. + +.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 +\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. + +.index message||age of +.tempindent 0 +\$message@_age$\: This variable is set at the start of a delivery attempt to +contain the number of seconds since the message was received. It does not +change during a single delivery attempt. + +.index body of message||expansion variable +.index message||body, in expansion +.index binary zero||in message body +.tempindent 0 +\$message@_body$\: This variable contains the initial portion of a message's +body while it is being delivered, and is intended mainly for use in filter +files. The maximum number of characters of the body that are put into the +variable is set by the \message@_body@_visible\ configuration option; the +default is 500. Newlines are converted into spaces to make it easier to search +for phrases that might be split over a line break. +Binary zeros are also converted into spaces. + +.index body of message||expansion variable +.index message||body, in expansion +.tempindent 0 +\$message@_body@_end$\: This variable contains the final portion of a message's +body while it is being delivered. The format and maximum size are as for +\$message@_body$\. + +.index body of message||size +.index message||body, size +.tempindent 0 +\$message@_body@_size$\: When a message is being processed, 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$\. + +.tempindent 0 +\$message@_headers$\: +This variable contains a concatenation of all the header lines when a message +is being processed, except for lines added by routers or transports. The header +lines are separated by newline characters. + +.tempindent 0 +\$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 +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: +\"1BXTIK-0001yO-VA"\. +.nem + +.index size||of message +.index message||size +.tempindent 0 +\$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 +deliveries as they are written. However, there is one special case: during the +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$\. + +.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 +-1 +if no size was given. The value may not, of course, be truthful. + +.tempindent 0 +\$n0$\ -- \$n9$\: These variables are counters that can be incremented by means +of the \add\ command in filter files. + +.tempindent 0 +\$original@_domain$\: When a top-level address is being processed for delivery, +this contains the same value as \$domain$\. However, if a `child' address (for +example, generated by an alias, forward, or filter file) is being processed, +this variable contains the domain of the original address. This differs from +\$parent@_domain$\ 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@_domain$\ 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 +part \*system-filter*\ and the default qualify domain. + +.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. + +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 +part \*system-filter*\ and the default qualify domain. + + +.index gid (group id)||of originating user +.index sender||gid +.tempindent 0 +\$originator@_gid$\: The value of \$caller@_gid$\ that was set when the message +was received. For messages received via the command line, this is the gid of +the sending user. For messages received by SMTP over TCP/IP, this is normally +the gid of the Exim user. + +.index uid (user id)||of originating user +.index sender||uid +.tempindent 0 +\$originator@_uid$\: The value of \$caller@_uid$\ that was set when the message +was received. For messages received via the command line, this is the uid of +the sending user. For messages received by SMTP over TCP/IP, this is normally +the uid of the Exim user. + +.tempindent 0 +\$parent@_domain$\: This variable is similar to \$original@_domain$\ (see +above), except that it refers to the immediately preceding parent address. + +.tempindent 0 +\$parent@_local@_part$\: This variable is similar to \$original@_local@_part$\ +(see above), except that it refers to the immediately preceding parent address. + +.index pid (process id)||of current process +.tempindent 0 +\$pid$\: This variable contains the current process id. + +.index filter||transport filter +.index transport||filter +.tempindent 0 +\$pipe@_addresses$\: This is not an expansion variable, but is mentioned here +because the string `@$pipe@_addresses' is handled specially in the command +specification for the \%pipe%\ transport (chapter ~~CHAPpipetransport) and in +transport filters (described under \transport@_filter\ in chapter +~~CHAPtransportgeneric). It cannot be used in general expansion strings, and +provokes an `unknown variable' error if encountered. + +.tempindent 0 +\$primary@_hostname$\: The value set in the configuration file, or read by the +\*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. + +.tempindent 0 +\$qualify@_recipient$\: 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 +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 +contains the number of \\RCPT\\ commands in the current message that have +previously been rejected with a temporary (4\*xx*\) response. + +.tempindent 0 +\$rcpt@_fail@_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 permanent (5\*xx*\) response. + +.tempindent 0 +\$received@_count$\: This variable contains the number of ::Received:: header +lines in the message, including the one added by Exim (so its value is always +greater than zero). It is available in the \\DATA\\ ACL, the non-SMTP ACL, and +while routing and delivering. + +.tempindent 0 +\$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. + +.em +.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 +value remains set until the next \recipients\ test. Thus, you can do things +like this: +.display +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 +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 +\$recipients$\: This variable contains a list of envelope recipients for a +message. A comma and a space separate the addresses in the replacement text. +However, the variable is not generally available, to prevent exposure of Bcc +recipients in unprivileged users' filter files. You can use \$recipients$\ only +.numberpars +In a system filter file. +.nextp +In the \\DATA\\ or non-SMTP ACL, that is, in the final ACL for accepting a +message. +.endp + +.tempindent 0 +\$recipients@_count$\: When a message is being processed, this variable +contains the number of envelope recipients that came with the message. +Duplicates are not excluded from the count. While a message is being received +over SMTP, the number increases for each accepted recipient. It can be +referenced in an ACL. + +.tempindent 0 +\$reply@_address$\: When a message is being processed, this variable contains +the contents of the ::Reply-To:: header line if one exists +and it is not empty, +or otherwise the contents of the ::From:: header line. + +.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, +\$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 +\$return@_path$\ contains the outgoing envelope sender. + +.tempindent 0 +\$return@_size@_limit$\: This is an obsolete name for +\$bounce@_return@_size@_limit$\. + +.index return code||from \run\ expansion +.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$\ +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 +.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 +the local host that the original router encountered. In other circumstances its +contents are null. + +.tempindent 0 +\$sender@_address$\: When a message is being processed, this variable contains +the sender's address that was received in the message's envelope. For bounce +messages, the value of this variable is the empty string. +See also \$return@_path$\. + +.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 +\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: +.display +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 +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 +variable contains the host name and IP address in a single string. It ends +with the IP address in square brackets, followed by a colon and a port number +if the logging of ports is enabled. The format of the rest of the string +depends on whether the host issued a \\HELO\\ or \\EHLO\\ SMTP command, and +whether the host name was verified by looking up its IP address. (Looking up +the IP address can be forced by the \host@_lookup\ option, independent of +verification.) A plain host name at the start of the string is a verified host +name; if this is not present, verification either failed or was not requested. +A host name in parentheses is the argument of a \\HELO\\ or \\EHLO\\ command. +This is omitted if it is identical to the verified host name or to the host's +IP address in square brackets. + +.tempindent 0 +\$sender@_helo@_name$\: When a message is received from a remote host that has +issued a \\HELO\\ or \\EHLO\\ command, the argument of that command is placed +in this variable. It is also set if \\HELO\\ or \\EHLO\\ is used when a message +is received using SMTP locally via the \-bs-\ or \-bS-\ options. + +.tempindent 0 +\$sender@_host@_address$\: When a message is received from a remote host, this +variable contains that host's IP address. For locally submitted messages, it is +empty. + +.tempindent 0 +\$sender@_host@_authenticated$\: This variable contains the name (not the +public name) of the authenticator driver which successfully authenticated the +client from which the message was received. It is empty if there was no +successful authentication. + +.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. +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 +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, +\$sender@_host@_name$\ remains empty, and \$host@_lookup@_failed$\ is set to +`1'. +.nem + +Exim does not automatically look up every calling host's name. If you want +maximum efficiency, you should arrange your configuration so that it avoids +these lookups altogether. The lookup happens only if one or more of the +following are true: +.numberpars +A string containing \$sender@_host@_name$\ is expanded. +.nextp +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 +Exim needs the host name in order to test an item in a host list. The items +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 +\\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 +.display asis +helo_lookup_domains = @ : @[] +.endd +which causes a lookup if a remote host (incorrectly) gives the server's name or +IP address in an \\EHLO\\ or \\HELO\\ command. +.endp + +.tempindent 0 +\$sender@_host@_port$\: When a message is received from a remote host, this +variable contains the port number that was used on the remote host. + +.tempindent 0 +\$sender@_ident$\: When a message is received from a remote host, this variable +contains the identification received in response to an RFC 1413 request. When a +message has been received locally, this variable contains the login name of the +user that called Exim. + +.tempindent 0 +\$sender@_rcvhost$\: This is provided specifically for use in ::Received:: +headers. It starts with either the verified host name (as obtained from a +.index DNS||reverse lookup +.index reverse DNS lookup +reverse DNS lookup) or, if there is no verified host name, the IP address in +square brackets. After that there may be text in parentheses. When the first +item is a verified host name, the first thing in the parentheses is the IP +address in square brackets, followed by a colon and a port number if port +logging is enabled. When the first item is an IP address, the port is recorded +as `port=$it{xxxx}' inside the parentheses. + +There may also be items of the form `helo=$it{xxxx}' if \\HELO\\ or \\EHLO\\ +was used and its argument was not identical to the real host name or IP +address, and `ident=$it{xxxx}' if an RFC 1413 ident string is available. If all +three items are present in the parentheses, a newline and tab are inserted into +the string, to improve the formatting of the ::Received:: header. + +.index \\AUTH\\||argument +.index \\EXPN\\||argument +.index \\ETRN\\||argument +.index \\VRFY\\||argument +.tempindent 0 +\$smtp@_command@_argument$\: While an ACL is running to check an \\AUTH\\, +\\EHLO\\, \\EXPN\\, \\ETRN\\, \\HELO\\, or \\VRFY\\ command, this variable +contains the argument for the SMTP command. + +.tempindent 0 +\$sn0$\ -- \$sn9$\: These variables are copies of the values of the \$n0$\ +-- \$n9$\ accumulators that were current at the end of the system filter file. +This allows a system filter file to set values that can be tested in users' +filter files. For example, a system filter could set a value indicating how +likely it is that a message is junk mail. + +.tempindent 0 +\$spool@_directory$\: The name of Exim's spool directory. + +.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 +description of that command. + +.tempindent 0 +\$tls@_certificate@_verified$\: +This variable is set to `1' if a TLS certificate was verified when the message +was received, and `0' otherwise. + +.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 +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, +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@_bsdinbox$\: The time of day and date, in the format required for +BSD-style mailbox files, for example: Thu Oct 17 17:14:09 1995. + +.tempindent 0 +\$tod@_epoch$\: The time and date as a number of seconds since the start of the +Unix epoch. + +.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 +negative values for those that are behind (west). + +.tempindent 0 +\$tod@_log$\: The time and date in the format used for writing Exim's log +files, for example: 1995-10-12 15:32:29, +but without a timezone. + +.tempindent 0 +\$tod@_logfile$\: +This variable contains the date in the format yyyymmdd. This is the format that +is used for datestamping log files when \log@_file@_path\ contains the \"%D"\ +flag. + +.tempindent 0 +\$tod@_zone$\: This variable contains the numerical value of the local +timezone, for example: -0500. + +.tempindent 0 +\$tod@_zulu$\: +This variable contains the UTC date and time in `Zulu' format, as specified by +ISO 8601, for example: 20030221154023Z. + +.index \$value$\ +.tempindent 0 +\$value$\: This variable contains the result of an expansion lookup, extraction +operation, or external command, as described above. + +.tempindent 0 +\$version@_number$\: The version number of Exim. + +.tempindent 0 +\$warn@_message@_delay$\: This variable is set only during the creation of a +message warning about a delivery delay. Details of its use are explained in +section ~~SECTcustwarn. + +.tempindent 0 +\$warn@_message@_recipients$\: This variable is set only during the creation of +a message warning about a delivery delay. Details of its use are explained in +section ~~SECTcustwarn. +.pop + + + +. +. +. ============================================================================ +.chapter Embedded Perl +.set runningfoot "embedded Perl" +.rset CHAPperl "~~chapter" +.index Perl||calling from Exim + +Exim can be built to include an embedded Perl interpreter. When this is done, +Perl subroutines can be called as part of the string expansion process. To make +use of the Perl support, you need version 5.004 or later of Perl installed on +your system. To include the embedded interpreter in the Exim binary, include +the line +.display asis +EXIM_PERL = perl.o +.endd +in your \(Local/Makefile)\ and then build Exim in the normal way. + +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 +no \perl@_startup\ option in the Exim configuration file then no Perl +interpreter is started and there is almost no overhead for Exim (since none of +the Perl library will be paged in unless used). If there is a \perl@_startup\ +option then the associated value is taken to be Perl code which is executed in +a newly created Perl interpreter. + +The value of \perl@_startup\ is not expanded in the Exim sense, so you do not +need backslashes before any characters to escape special meanings. The option +should usually be something like +.display asis +perl_startup = do '/etc/exim.pl' +.endd +where \(/etc/exim.pl)\ is Perl code which defines any subroutines you want to +use from Exim. Exim can be configured either to start up a Perl interpreter as +soon as it is entered, or to wait until the first time it is needed. Starting +the interpreter at the beginning ensures that it is done while Exim still has +its setuid privilege, but can impose an unnecessary overhead if Perl is not in +fact used in a particular run. Also, note that this does not mean that Exim is +necessarily running as root when Perl is called at a later time. By default, +the interpreter is started only when it is needed, but this can be changed in +two ways: +.numberpars $. +.index \perl@_at@_start\ +Setting \perl@_at@_start\ (a boolean option) in the configuration requests +a startup when Exim is entered. +.nextp +The command line option \-ps-\ also requests a startup when Exim is entered, +overriding the setting of \perl@_at@_start\. +.endp +There is also a command line option \-pd-\ (for delay) which suppresses the +initial startup, even if \perl@_at@_start\ is set. + +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 +forms: +.display asis +${perl{foo}} +${perl{foo}{argument}} +${perl{foo}{argument1}{argument2} ... } +.endd +which calls the subroutine \foo\ with the given arguments. A maximum of eight +arguments may be passed. Passing more than this results in an expansion failure +with an error message of the form +.display asis +Too many arguments passed to Perl subroutine "foo" (max is 8) +.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\. + +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 +.display asis +my $lp = Exim::expand_string('$local_part'); +.endd +makes the current Exim \$local@_part$\ available in the Perl variable \$lp$\. +Note those are single quotes and not double quotes to protect against +\$local@_part$\ being interpolated as a Perl variable. + +If the string expansion is forced to fail by a `fail' item, the result of +\*Exim@:@:expand@_string*\ is \undef\. If there is a syntax error in the +expansion string, the Perl call from the original expansion string fails with +an appropriate error message, in the same way as if \die\ were used. + +.index debugging||from embedded Perl +.index log||writing from embedded Perl +Two other Exim functions are available for use from within Perl code. +\*Exim@:@:debug@_write(<<string>>)*\ writes the string to the standard error +stream if Exim's debugging is enabled. If you want a newline at the end, you +must supply it. \*Exim@:@:log@_write(<<string>>)*\ writes the string to Exim's +main log, adding a leading timestamp. In this case, you should not supply a +terminating newline. + + + +. +. +. +. +. ============================================================================ +.chapter Starting the daemon and the use of network interfaces +.set runningfoot "starting the daemon" +.rset CHAPinterfaces "~~chapter" +.index daemon||starting +.index interface||listening +.index network interface +.index interface||network +.index IP address||for listening +.index daemon||listening IP addresses +.index TCP/IP||setting listening interfaces +.index TCP/IP||setting listening ports + +A host that is connected to a TCP/IP network may have one or more physical +hardware network interfaces. Each of these interfaces may be configured as one +or more `logical' interfaces, which are the entities that a program actually +works with. Each of these logical interfaces is associated with an IP address. +In addition, TCP/IP software supports `loopback' interfaces (127.0.0.1 in IPv4 +and @:@:1 in IPv6), which do not use any physical hardware. Exim requires +knowledge about the host's interfaces for use in three different circumstances: +.numberpars +When a listening daemon is started, Exim needs to know which interfaces +and ports to listen on. +.nextp +When Exim is routing an address, it needs to know which IP addresses +are associated with local interfaces. This is required for the correct +processing of MX lists by removing the local host and others with the +same or higher priority values. Also, Exim needs to detect cases +when an address is routed to an IP address that in fact belongs to the +local host. Unless the \self\ router option or the \allow@_localhost\ +option of the smtp transport is set (as appropriate), this is treated +as an error situation. +.nextp +When Exim connects to a remote host, it may need to know which interface to use +for the outgoing connection. +.endp + +Exim's default behaviour is likely to be appropriate in the vast majority +of cases. If your host has only one interface, and you want all its IP +addresses to be treated in the same way, and you are using only the +standard SMTP port, you should not need to take any special action. The +rest of this chapter does not apply to you. + +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. + +When a message is received over TCP/IP, the interface and port that were +actually used are set in \$interface@_address$\ and \$interface@_port$\. + + +.section Starting a listening daemon +When a listening daemon is started (by means of the \-bd-\ command line +option), the interfaces and ports on which it listens are controlled by the +following options: +.numberpars $. +\daemon@_smtp@_ports\ contains a list of default ports. (For backward +compatibility, this option can also be specified in the singular.) +.nextp +\local@_interfaces\ contains list of interface IP addresses on which to +listen. Each item may optionally also specify a port. +.endp +The default list separator in both cases is a colon, but this can be changed as +described in section ~~SECTlistconstruct. When IPv6 addresses are involved, it +is usually best to change the separator to avoid having to double all the +colons. For example: +.display asis +local_interfaces = <; 127.0.0.1 ; \ + 192.168.23.65 ; \ + ::1 ; \ + 3ffe:ffff:836f::fe86:a061 +.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 +on port 1234 on two different IP addresses: +.display asis +local_interfaces = <; 192.168.23.65.1234 ; \ + 3ffe:ffff:836f::fe86:a061.1234 +.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 +.endp +When a port is not specified, the value of \daemon@_smtp@_ports\ is used. The +default setting contains just one port: +.display asis +daemon_smtp_ports = smtp +.endd +If more than one port is listed, each interface that does not have its own port +specified listens on all of them. Ports that are listed in +\daemon@_smtp@_ports\ can be identified either by name (defined in +\(/etc/services)\) or by number. However, when ports are given with individual +IP addresses in \local@_interfaces\, only numbers (not names) can be used. + + +.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' +instead of setting up separate listening sockets for each interface. The +default value of \local@_interfaces\ is +.display asis +local_interfaces = 0.0.0.0 +.endd +when Exim is built without IPv6 support; otherwise it is: +.display asis +local_interfaces = <; ::0 ; 0.0.0.0 +.endd +Thus, by default, Exim listens on all available interfaces, on the SMTP port. + + +.section Overriding local@_interfaces and daemon@_smtp@_ports +The \-oX-\ command line option can be used to override the values of +\daemon@_smtp@_ports\ and/or \local@_interfaces\ for a particular daemon +instance. Another way of doing this would be to use macros and the \-D-\ +option. However, \-oX-\ can be used by any admin user, whereas modification of +the runtime configuration by \-D-\ is allowed only when the caller is root or +exim. + +The value of \-oX-\ is a list of items. The default colon separator can be +changed in the usual way if required. If there are any items that do not +contain dots or colons (that is, are not IP addresses), the value of +\daemon@_smtp@_ports\ is replaced by the list of those items. If there are any +items that do contain dots or colons, the value of \local@_interfaces\ is +replaced by those items. Thus, for example, +.display asis +-oX 1225 +.endd +overrides \daemon@_smtp@_ports\, but leaves \local@_interfaces\ unchanged, +whereas +.display asis +-oX 192.168.34.5.1125 +.endd +overrides \local@_interfaces\, leaving \daemon@_smtp@_ports\ unchanged. +(However, since \local@_interfaces\ now contains no items without ports, the +value of \daemon@_smtp@_ports\ is no longer relevant in this example.) + + +.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 +interfaces. Thus, additional information is needed, over and above the IP +address, to distinguish individual interfaces. A convention of using a +percent sign followed by something (often the interface name) has been +adopted in some cases, leading to addresses like this: +.display asis +3ffe:2101:12:1:a00:20ff:fe86:a061%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()*\ +to convert a textual IPv6 address for actual use. This function recognizes the +percent convention in operating systems that support it, and it processes the +address appropriately. Unfortunately, some older libraries have problems with +\*getaddrinfo()*\. If +.display asis +IPV6_USE_INET_PTON=yes +.endd +is set in \(Local/Makefile)\ (or an OS-dependent Makefile) when Exim is built, +Exim uses \*inet@_pton()*\ to convert a textual IPv6 address for actual use, +instead of \*getaddrinfo()*\. (Before version 4.14, it always used this +function.) Of course, this means that the additional functionality of +\*getaddrinfo()*\ -- recognizing scoped addresses -- is lost. + + +.section Examples of starting a listening daemon +The default case in an IPv6 environment is +.display asis +daemon_smtp_port = smtp +local_interfaces = <; ::0 ; 0.0.0.0 +.endd +This specifies listening on the smtp port on all IPv6 and IPv4 interfaces. +Either one or two sockets may be used, depending on the characteristics of +the TCP/IP stack. (This is complicated and messy; for more information, +read the comments in the \(daemon.c)\ source file.) + +To specify listening on ports 25 and 26 on all interfaces: +.display asis +daemon_smtp_ports = 25 : 26 +.endd +(leaving \local@_interfaces\ at the default setting) or, more explicitly: +.display asis +local_interfaces = <; ::0.25 ; ::0.26 \ + 0.0.0.0.25 ; 0.0.0.0.26 +.endd +To listen on the default port on all IPv4 interfaces, and on port 26 on the +IPv4 loopback address only: +.display asis +local_interfaces = 0.0.0.0 : 127.0.0.1.26 +.endd +To specify listening on the default port on specific interfaces only: +.display asis +local_interfaces = 192.168.34.67 : 192.168.34.67 +.endd +\**Note**\: such a setting excludes listening on the loopback interfaces. + + +.section Recognising the local host +.rset SECTreclocipadd "~~chapter.~~section" +The \local@_interfaces\ option is also used when Exim needs to determine +whether or not an IP address refers to the local host. That is, the IP +addresses of all the interfaces on which a daemon is listening are always +treated as local. + +For this usage, port numbers in \local@_interfaces\ are ignored. If either of +the items 0.0.0.0 or @:@:0 are encountered, Exim gets a complete list of +available interfaces from the operating system, and extracts the relevant +(that is, IPv4 or IPv6) addresses to use for checking. + +Some systems set up large numbers of virtual interfaces in order to provide +many virtual web servers. In this situation, you may want to listen for +email on only a few of the available interfaces, but nevertheless treat all +interfaces as local when routing. You can do this by setting +\extra@_local@_interfaces\ to a list of IP addresses, possibly including the +`all' wildcard values. These addresses are recognized as local, but are not +used for listening. Consider this example: +.display asis +local_interfaces = <; 127.0.0.1 ; ::1 ; \ + 192.168.53.235 ; \ + 3ffe:2101:12:1:a00:20ff:fe86:a061 + +extra_local_interfaces = <; ::0 ; 0.0.0.0 +.endd +The daemon listens on the loopback interfaces and just one IPv4 and one IPv6 +address, but all available interface addresses are treated as local when +Exim is routing. + +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 +during routing, either via an MX record or directly, it is treated as the local +host if its name matches \hosts@_treat@_as@_local\, or if any of its IP +addresses match \local@_interfaces\ or \extra@_local@_interfaces\. + + +.section Delivering to a remote host +Delivery to a remote host is handled by the smtp transport. By default, it +allows the system's TCP/IP functions to choose which interface to use (if +there is more than one) when connecting to a remote host. However, the +\interface\ option can be set to specify which interface is used. See the +description of the smtp transport in chapter ~~CHAPsmtptrans for more details. + + + + + +. +. +. +. +. ============================================================================ +.chapter Main configuration +.set runningfoot "main configuration" +.rset CHAPmainconfig "~~chapter" +.index configuration file||main section +.index main configuration +The first part of the run time configuration file contains three types of item: +.numberpars $. +Macro definitions: These lines start with an upper case letter. See section +~~SECTmacrodefs for details of macro processing. +.nextp +Named list definitions: These lines start with one of the words `domainlist', +`hostlist', `addresslist', or `localpartlist'. Their use is described in +section ~~SECTnamedlists. +.nextp +Main configuration settings: Each setting occupies one line of the file +(with possible continuations). If any setting is preceded by the word +`hide', the \-bP-\ command line option displays its value to admin users only. +See section ~~SECTcos for a description of the syntax of these option settings. +.endp +This chapter specifies all the main configuration options, along with their +types and default values. For ease of finding a particular option, they appear +in alphabetical order in section ~~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. + +.set savedisplayflowcheck ~~displayflowcheck +.set displayflowcheck 0 + +.section Miscellaneous +.display flow rm +.tabs 31 +\bi@_command\ $t$rm{to run for \-bi-\ command line option} +\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$\} +\print@_topbitchars\ $t$rm{top-bit characters are printing} +\timezone\ $t$rm{force time zone} +.endd + +.section Exim parameters +.display flow rm +.tabs 31 +\exim@_group\ $t$rm{override compiled-in value} +\exim@_path\ $t$rm{override compiled-in value} +\exim@_user\ $t$rm{override compiled-in value} +\primary@_hostname\ $t$rm{default from \*uname()*\} +\split@_spool@_directory\ $t$rm{use multiple directories} +\spool@_directory\ $t$rm{override compiled-in value} +.endd + +.section Privilege controls +.display flow rm +.tabs 31 +\admin@_groups\ $t$rm{groups that are Exim admin users} +\deliver@_drop@_privilege\ $t$rm{drop root for delivery processes} +\local@_from@_check\ $t$rm{insert ::Sender:: if necessary} +\local@_from@_prefix\ $t$rm{for testing ::From:: for local sender} +\local@_from@_suffix\ $t$rm{for testing ::From:: for local sender} +\local@_sender@_retain\ $t$rm{keep ::Sender:: from untrusted user} +\never@_users\ $t$rm{do not run deliveries as these} +\prod@_requires@_admin\ $t$rm{forced delivery requires admin user} +\queue@_list@_requires@_admin\ $t$rm{queue listing requires admin user} +\trusted@_groups\ $t$rm{groups that are trusted} +\trusted@_users\ $t$rm{users that are trusted} +.endd + +.section Logging +.display flow rm +.tabs 31 +\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} +\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 +.display flow rm +.tabs 31 +\auto@_thaw\ $t$rm{sets time for retrying frozen messages} +\freeze@_tell\ $t$rm{send message when freezing} +\move@_frozen@_messages\ $t$rm{to another directory} +\timeout@_frozen@_after\ $t$rm{keep frozen messages only so long} +.endd + +.section Data lookups +.display flow rm +.tabs 31 +\ldap@_default@_servers\ $t$rm{used if no server in query} +\ldap@_version\ $t$rm{set protocol version} +\lookup@_open@_max\ $t$rm{lookup files held open} +\mysql@_servers\ $t$rm{as it says} +\oracle@_servers\ $t$rm{as it says} +\pgsql@_servers\ $t$rm{as it says} +.endd + +.section Message ids +.display flow rm +.tabs 31 +\message@_id@_header@_domain\ $t$rm{used to build ::Message-ID:: header} +\message@_id@_header@_text\ $t$rm{ditto} +.endd + +.section Embedded Perl Startup +.display flow rm +.tabs 31 +\perl@_at@_start\ $t$rm{always start the interpreter} +\perl@_startup\ $t$rm{code to obey when starting Perl} +.endd + +.section Daemon +.display flow rm +.tabs 31 +\daemon@_smtp@_ports\ $t$rm{default ports} +\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} +.endd + +.section Resource control +.display flow rm +.tabs 31 +\check@_log@_inodes\ $t$rm{before accepting a message} +\check@_log@_space\ $t$rm{before accepting a message} +\check@_spool@_inodes\ $t$rm{before accepting a message} +\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} +\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} +\smtp@_accept@_max@_nonmail@_hosts\ $t$rm{hosts to which the limit applies} +\smtp@_accept@_max@_per@_connection\ $t$rm{messages per connection} +\smtp@_accept@_max@_per@_host\ $t$rm{connections from one host} +\smtp@_accept@_queue\ $t$rm{queue mail if more connections} +\smtp@_accept@_queue@_per@_connection\ $t$rm{queue if more messages per connection} +\smtp@_accept@_reserve\ $t$rm{only reserve hosts if more connections} +\smtp@_check@_spool@_space\ $t$rm{from \\SIZE\\ on \\MAIL\\ command} +\smtp@_connect@_backlog\ $t$rm{passed to TCP/IP stack} +\smtp@_load@_reserve\ $t$rm{SMTP from reserved hosts if load high} +\smtp@_reserve@_hosts\ $t$rm{these are the reserve hosts} +.endd + +.section Policy controls +.display flow rm +.tabs 31 +\acl@_not@_smtp\ $t$rm{set ACL for non-SMTP messages} +\acl@_smtp@_auth\ $t$rm{set ACL for \\AUTH\\} +\acl@_smtp@_connect\ $t$rm{set ACL for connection} +\acl@_smtp@_data\ $t$rm{set ACL for \\DATA\\} +\acl@_smtp@_etrn\ $t$rm{set ACL for \\ETRN\\} +\acl@_smtp@_expn\ $t$rm{set ACL for \\EXPN\\} +\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} +\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\\} +\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} +\helo@_allow@_chars\ $t$rm{allow illegal chars in \\HELO\\ names} +\helo@_lookup@_domains\ $t$rm{lookup hostname for these \\HELO\\ names} +\helo@_try@_verify@_hosts\ $t$rm{\\HELO\\ soft-checked for these hosts} +\helo@_verify@_hosts\ $t$rm{\\HELO\\ hard-checked for these hosts} +\host@_lookup\ $t$rm{host name looked up for these hosts} +\host@_lookup@_order\ $t$rm{order of DNS and local name lookups} +\host@_reject@_connection\ $t$rm{reject connection from these hosts} +\hosts@_treat@_as@_local\ $t$rm{useful in some cluster configurations} +\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} +.endd + +.section Callout cache +.display flow rm +.tabs 31 +\callout@_domain@_negative@_expire\ $t$rm{timeout for negative domain cache item} +\callout@_domain@_positive@_expire\ $t$rm{timeout for positive domain cache item} +\callout@_negative@_expire\ $t$rm{timeout for negative address cache item} +\callout@_positive@_expire\ $t$rm{timeout for positive address cache item} +\callout@_random@_local@_part\ $t$rm{string to use for `random' testing} +.endd + +.section TLS +.display flow rm +.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} +.newline +.nem +\tls@_dhparam\ $t$rm{DH parameters for server} +\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 +.display flow rm +.tabs 31 +\finduser@_retries\ $t$rm{useful in NIS environments} +\gecos@_name\ $t$rm{used when creating ::Sender::} +\gecos@_pattern\ $t$rm{ditto} +\max@_username@_length\ $t$rm{for systems that truncate} +\unknown@_login\ $t$rm{used when no login name found} +\unknown@_username\ $t$rm{ditto} +\uucp@_from@_pattern\ $t$rm{for recognizing `From ' lines} +\uucp@_from@_sender\ $t$rm{ditto} +.endd + +.section All incoming messages (SMTP and non-SMTP) +.display flow rm +.tabs 31 +\header@_maxsize\ $t$rm{total size of message header} +\header@_line@_maxsize\ $t$rm{individual header line limit} +\message@_size@_limit\ $t$rm{applies to all messages} +\percent@_hack@_domains\ $t$rm{recognize %-hack for these domains} +\received@_header@_text\ $t$rm{expanded to make ::Received::} +\received@_headers@_max\ $t$rm{for mail loop detection} +\recipients@_max\ $t$rm{limit per message} +\recipients@_max@_reject\ $t$rm{permanently reject excess} +.endd + + +.section Non-SMTP incoming messages +.display rm +.tabs 31 +\receive@_timeout\ $t$rm{for non-SMTP messages} +.endd + + + +.section Incoming SMTP messages +See also the \*Policy controls*\ section above. +.display flow rm +.tabs 31 +\host@_lookup\ $t$rm{host name looked up for these hosts} +\host@_lookup@_order\ $t$rm{order of DNS and local name lookups} +\recipient@_unqualified@_hosts\ $t$rm{may send unqualified recipients} +\rfc1413@_hosts\ $t$rm{make ident calls to these hosts} +\rfc1413@_query@_timeout\ $t$rm{zero disables ident calls} +\sender@_unqualified@_hosts\ $t$rm{may send unqualified senders} +\smtp@_accept@_keepalive\ $t$rm{some TCP/IP magic} +\smtp@_accept@_max\ $t$rm{simultaneous incoming connections} +\smtp@_accept@_max@_nommail\ $t$rm{non-mail commands} +\smtp@_accept@_max@_nonmail@_hosts\ $t$rm{hosts to which the limit applies} +\smtp@_accept@_max@_per@_connection\ $t$rm{messages per connection} +\smtp@_accept@_max@_per@_host\ $t$rm{connections from one host} +\smtp@_accept@_queue\ $t$rm{queue mail if more connections} +\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} +\smtp@_enforce@_sync\ $t$rm{of SMTP command/responses} +\smtp@_etrn@_command\ $t$rm{what to run for \\ETRN\\} +\smtp@_etrn@_serialize\ $t$rm{only one at once} +\smtp@_load@_reserve\ $t$rm{only reserve hosts if this load} +\smtp@_max@_unknown@_commands\ $t$rm{before dropping connection} +\smtp@_ratelimit@_hosts\ $t$rm{apply ratelimiting to these hosts} +\smtp@_ratelimit@_mail\ $t$rm{ratelimit for \\MAIL\\ commands} +\smtp@_ratelimit@_rcpt\ $t$rm{ratelimit for \\RCPT\\ commands} +\smtp@_receive@_timeout\ $t$rm{per command or data line} +\smtp@_reserve@_hosts\ $t$rm{these are the reserve hosts} +\smtp@_return@_error@_details\ $t$rm{give detail on rejections} +.endd + +.section SMTP extensions +.display flow rm +.tabs 31 +\accept@_8bitmime\ $t$rm{advertise \\8BITMIME\\} +\auth@_advertise@_hosts\ $t$rm{advertise \\AUTH\\ to these hosts} +\ignore@_fromline@_hosts\ $t$rm{allow `From ' from these hosts} +\ignore@_fromline@_local\ $t$rm{allow `From ' from local SMTP} +\pipelining@_advertise@_hosts\ $t$rm{advertise pipelining to these hosts} +\tls@_advertise@_hosts\ $t$rm{advertise TLS to these hosts} +.endd + +.section Processing messages +.display flow rm +.tabs 31 +\allow@_domain@_literals\ $t$rm{recognize domain literal syntax} +\allow@_mx@_to@_ip\ $t$rm{allow MX to point to IP address} +\allow@_utf8@_domains\ $t$rm{in addresses} +\delivery@_date@_remove\ $t$rm{from incoming messages} +\envelope@_to@_remote\ $t$rm{from incoming messages} +\extract@_addresses@_remove@_arguments\ $t$rm{affects \-t-\ processing} +\headers@_charset\ $t$rm{default for translations} +\qualify@_domain\ $t$rm{default for senders} +\qualify@_recipient\ $t$rm{default for recipients} +\return@_path@_remove\ $t$rm{from incoming messages} +\strip@_excess@_angle@_brackets\ $t$rm{in addresses} +\strip@_trailing@_dot\ $t$rm{at end of addresses} +\untrusted@_set@_sender\ $t$rm{untrusted can set envelope sender} +.endd + +.section System filter +.display flow rm +.tabs 31 +\system@_filter\ $t$rm{locate system filter} +\system@_filter@_directory@_transport\ $t$rm{transport for delivery to a directory} +\system@_filter@_file@_transport\ $t$rm{transport for delivery to a file} +\system@_filter@_group\ $t$rm{group for filter running} +\system@_filter@_pipe@_transport\ $t$rm{transport for delivery to a pipe} +\system@_filter@_reply@_transport\ $t$rm{transport for autoreply delivery} +\system@_filter@_user\ $t$rm{user for filter running} +.endd + +.section Routing and delivery +.display flow rm +.tabs 31 +\dns@_again@_means@_nonexist\ $t$rm{for broken domains} +\dns@_check@_names@_pattern\ $t$rm{pre-DNS syntax check} +\dns@_ipv4@_lookup\ $t$rm{only v4 lookup for these domains} +\dns@_retrans\ $t$rm{parameter for resolver} +\dns@_retry\ $t$rm{parameter for resolver} +\hold@_domains\ $t$rm{hold delivery for these domains} +\local@_interfaces\ $t$rm{for routing checks} +\queue@_domains\ $t$rm{no immediate delivery for these} +\queue@_only\ $t$rm{no immediate delivery at all} +\queue@_only@_file\ $t$rm{no immediate deliveryif file exists} +\queue@_only@_load\ $t$rm{no immediate delivery if load is high} +\queue@_only@_override\ $t$rm{allow command line to override} +\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@_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} +.endd + +.section Bounce and warning messages +.display flow rm +.tabs 31 +\bounce@_message@_file\ $t$rm{content of bounce} +\bounce@_message@_text\ $t$rm{content of bounce} +\bounce@_return@_body\ $t$rm{include body if returning message} +\bounce@_return@_message\ $t$rm{include original message in bounce} +\bounce@_return@_size@_limit\ $t$rm{limit on returned message} +\bounce@_sender@_authentication\ $t$rm{send authenticated sender with bounce} +\errors@_copy\ $t$rm{copy bounce messages} +\errors@_reply@_to\ $t$rm{::Reply-to:: in bounces} +\delay@_warning\ $t$rm{time schedule} +\delay@_warning@_condition\ $t$rm{condition for warning messages} +\ignore@_bounce@_errors@_after\ $t$rm{discard undeliverable bounces} +\warn@_message@_file\ $t$rm{content of warning message} +.endd + +.set displayflowcheck ~~savedisplayflowcheck + +.section Alphabetical list of main options +.rset SECTalomo "~~chapter.~~section" +.if ~~sgcal +Those options that undergo string expansion before use are marked with $**$. +.fi + +.startconf + +.index \\8BITMIME\\ +.index 8-bit characters +.conf accept@_8bitmime boolean false +This option causes Exim to send \\8BITMIME\\ in its response to an SMTP +\\EHLO\\ command, and to accept the \\BODY=\\ parameter on \\MAIL\\ commands. +However, though Exim is 8-bit clean, it is not a protocol converter, and it +takes no steps to do anything special with messages received by this route. +Consequently, this option is turned off by default. + +.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 +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 \\DATA\\, ACL for +.conf acl@_smtp@_data string$**$ unset +This option defines the ACL that is run after an SMTP \\DATA\\ command has been +processed and the message itself has been received, but before the final +acknowledgement is sent. See chapter ~~CHAPACL for further details. + +.index \\ETRN\\||ACL for +.conf acl@_smtp@_etrn string$**$ unset +This option defines the ACL that is run when an SMTP \\ETRN\\ command is +received. See chapter ~~CHAPACL for further details. + +.index \\EXPN\\||ACL for +.conf acl@_smtp@_expn string$**$ unset +This option defines the ACL that is run when an SMTP \\EXPN\\ command is +received. See chapter ~~CHAPACL for further details. + +.index \\EHLO\\||ACL for +.index \\HELO\\||ACL for +.conf acl@_smtp@_helo string$**$ unset +This option defines the ACL that is run when an SMTP \\EHLO\\ or \\HELO\\ +command is received. See chapter ~~CHAPACL for further details. + +.index \\MAIL\\||ACL for +.conf acl@_smtp@_mail string$**$ unset +This option defines the ACL that is run when an SMTP \\MAIL\\ command is +received. See chapter ~~CHAPACL for further details. + +.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 +a \\MAIL\\ command. See chapter ~~CHAPACL for details of ACLs, and chapter +~~CHAPSMTPAUTH for details of authentication. + +.index \\RCPT\\||ACL for +.conf acl@_smtp@_rcpt string$**$ unset +This option defines the ACL that is run when an SMTP \\RCPT\\ command is +received. See chapter ~~CHAPACL for further details. + +.index \\STARTTLS\\, ACL for +.conf acl@_smtp@_starttls string$**$ unset +This option defines the ACL that is run when an SMTP \\STARTTLS\\ command is +received. See chapter ~~CHAPACL for further details. + +.index \\VRFY\\||ACL for +.conf acl@_smtp@_vrfy string$**$ unset +This option defines the ACL that is run when an SMTP \\VRFY\\ command is +received. See chapter ~~CHAPACL for further details. + +.conf admin@_groups "string list" unset +.index admin user +If the current group or any of the supplementary groups of the caller is in +this colon-separated list, the caller has admin privileges. If all your system +programmers are in a specific group, for example, you can give them all Exim +admin privileges by putting that group in \admin@_groups\. However, this does +not permit them to read Exim's spool files (whose group owner is the Exim gid). +To permit this, you have to add individuals to the Exim group. + +.conf allow@_domain@_literals boolean false +.index domain literal +If this option is set, the RFC 2822 domain literal format is permitted in +email addresses. The option is not set by default, because the domain literal +format is not normally required these days, and few people know about it. It +has, however, been exploited by mail abusers. + +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 +.index MX record||pointing to IP address +It appears that more and more DNS zone administrators are breaking the rules +and putting domain names that look like IP addresses on the right hand side of +MX records. Exim follows the rules and rejects this, giving an error message +that explains the mis-configuration. However, some other MTAs support this +practice, so to avoid `Why can't Exim do this?' complaints, \allow@_mx@_to@_ip\ +exists, in order to enable this heinous activity. It is not recommended, except +when you have no other choice. + +.index domain||UTF-8 characters in +.index UTF-8||in domain name +.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 +experiment if they wish. + +If it is set true, Exim's domain parsing function allows valid +UTF-8 multicharacters to appear in domain name components, in addition to +letters, digits, and hyphens. However, just setting this option is not +enough; if you want to look up these domain names in the DNS, you must also +adjust the value of \dns@_check@_names@_pattern\ to match the extended form. A +suitable setting is: +.display asis +dns_check_names_pattern = (?i)^(?>(?(1)\.|())[a-z0-9\xc0-\xff]\ + (?>[-a-z0-9\x80-\xff]*[a-z0-9\x80-\xbf])?)+$ +.endd +Alternatively, you can just disable this feature by setting +.display asis +dns_check_names_pattern = +.endd +That is, set the option to an empty string so that no check is done. + +.conf auth@_advertise@_hosts "host list$**$" $*$ +.index authentication||advertising +.index \\AUTH\\||advertising +If any server authentication mechanisms are configured, Exim advertises them in +response to an \\EHLO\\ command only if the calling host matches this list. +Otherwise, Exim does not advertise \\AUTH\\. +Exim does not accept \\AUTH\\ commands from clients to which it has not +advertised the availability of \\AUTH\\. The advertising of individual +authentication mechanisms can be controlled by the use of the +\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 +and password for authentication if \\AUTH\\ is advertised, even though it may +not be needed (the host may accept messages from hosts on its local LAN without +authentication, for example). The \auth@_advertise@_hosts\ option can be used +to make these clients more friendly by excluding them from the set of hosts to +which Exim advertises \\AUTH\\. + +.index \\AUTH\\||advertising when encrypted +If you want to advertise the availability of \\AUTH\\ only when the connection +is encrypted using TLS, you can make use of the fact that the value of this +option is expanded, with a setting like this: +.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 +expansion is $*$, which matches all hosts. + +.conf auto@_thaw time 0s +.index thawing messages +.index unfreezing messages +If this option is set to a time greater than zero, a queue runner will try a +new delivery attempt on any frozen message if this much time has passed since +it was frozen. This may result in the message being re-frozen if nothing has +changed since the last attempt. It is a way of saying `keep on trying, even +though there are big problems'. See also \timeout@_frozen@_after\ and +\ignore@_bounce@_errors@_after\. + +.conf bi@_command string unset +.index \-bi-\ option +This option supplies the name of a command that is run when Exim is called with +the \-bi-\ option (see chapter ~~CHAPcommandline). The string value is just the +command name, it is not a complete command line. If an argument is required, it +must come from the \-oA-\ command line option. + +.conf bounce@_message@_file string unset +.index bounce message||customizing +.index customizing||bounce message +This option defines a template file containing paragraphs of text to be used +for constructing bounce messages. Details of the file's contents are given in +chapter ~~CHAPemsgcust. See also \warn@_message@_file\. + +.conf bounce@_message@_text string unset +When this option is set, its contents are included in the default bounce +message immediately after `This message was created automatically by mail +delivery software.' It is not used if \bounce@_message@_file\ is set. + +.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 +the message header is included. + +.index bounce message||including original +.conf bounce@_return@_message boolean true +If this option is set false, the original message is not included in bounce +messages generated by Exim. See also \bounce@_return@_size@_limit\. + +.conf bounce@_return@_size@_limit integer 100K +.index size||of bounce, limit +.index bounce message||size limit +.index limit||bounce message size +This option sets a limit in bytes on the size of messages that are returned to +senders as part of bounce messages when \bounce@_return@_message\ is true. The +limit should be less than the value of the global \message@_size@_limit\ and of +any \message@_size@_limit\ settings on transports, to allow for the bounce text +that Exim generates. If this option is set to zero there is no limit. + +When the body of any message that is to be included in a bounce message is +greater than the limit, it is truncated, and a comment pointing this out is +added at the top. The actual cutoff may be greater than the value given, owing +to the use of buffering for transferring the message in chunks (typically 8K in +size). The idea is to save bandwidth on those undeliverable 15-megabyte +messages. + +.index bounce message||sender authentication +.index authentication||bounce message +.index \\AUTH\\||on bounce message +.conf bounce@_sender@_authentication string unset +This option provides an authenticated sender address that is sent with any +bounce messages generated by Exim that are sent over an authenticated SMTP +connection. A typical setting might be: +.display asis +bounce_sender_authentication = mailer-daemon@my.domain.example +.endd +which would cause bounce messages to be sent using the SMTP command: +.display asis +MAIL FROM:<> AUTH=mailer-daemon@my.domain.example +.endd +The value of \bounce@_sender@_authentication\ must always be a complete email +address. + +.index caching||callout, timeouts +.index callout||caching timeouts +.conf callout@_domain@_negative@_expire time 3h +This option specifies the expiry time for negative callout cache data for a +domain. See section ~~SECTcallver for details of callout verification, and +section ~~SECTcallvercache for details of the caching. + +.conf callout@_domain@_positive@_expire time 7d +This option specifies the expiry time for positive callout cache data for a +domain. See section ~~SECTcallver for details of callout verification, and +section ~~SECTcallvercache for details of the caching. + +.conf callout@_negative@_expire time 2h +This option specifies the expiry time for negative callout cache data for an +address. See section ~~SECTcallver for details of callout verification, and +section ~~SECTcallvercache for details of the caching. + +.conf callout@_positive@_expire time 24h +This option specifies the expiry time for positive callout cache data for an +address. See section ~~SECTcallver for details of callout verification, and +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 +verification. The default value is +.display asis +$primary_host_name-$tod_epoch-testing +.endd +See section ~~CALLaddparcall for details of how this value is used. + +.conf check@_log@_inodes integer 0 +See \check@_spool@_space\ below. + +.conf check@_log@_space integer 0 +See \check@_spool@_space\ below. + +.conf check@_spool@_inodes integer 0 +See \check@_spool@_space\ below. + +.conf check@_spool@_space integer 0 +.index checking disk space +.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: +.display asis +check_spool_space = 10M +check_spool_inodes = 100 +.endd +The spool partition is the one which contains the directory defined by +\\SPOOL@_DIRECTORY\\ in \(Local/Makefile)\. It is used for holding messages in +transit. + +\check@_log@_space\ and \check@_log@_inodes\ check the partition in which log +files are written if either is greater than zero. These should be set only if +\log@_file@_path\ and \spool@_directory\ refer to different partitions. + +If there is less space or fewer inodes than requested, Exim refuses to accept +incoming mail. In the case of SMTP input this is done by giving a 452 temporary +error response to the \\MAIL\\ command. If ESMTP is in use and there was a +\\SIZE\\ parameter on the \\MAIL\\ command, its value is added to the +\check@_spool@_space\ value, and the check is performed even if +\check@_spool@_space\ is zero, unless \no@_smtp@_check@_spool@_space\ is set. + +The values for \check@_spool@_space\ and \check@_log@_space\ are held as a +number of kilobytes. If a non-multiple of 1024 is specified, it is rounded up. + +For non-SMTP input and for batched SMTP input, the test is done at start-up; on +failure a message is written to stderr and Exim exits with a non-zero code, as +it obviously cannot send an error message of any kind. + +.index port||for daemon +.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 +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 +.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 +just one time, it specifies the repeat interval. For example, with: +.display asis +delay_warning = 6h +.endd +messages are repeated every six hours. To stop warnings after a given time, set +a very large time at the end of the list. For example: +.display asis +delay_warning = 2h:12h:99d +.endd + +.conf delay@_warning@_condition string$**$ "see below" +The string is expanded at the time a warning message might be sent. If all the +deferred addresses have the same domain, it is set in \$domain$\ during the +expansion. Otherwise \$domain$\ is empty. If the result of the expansion is a +forced failure, an empty string, or a string matching any of `0', `no' or +`false' (the comparison being done caselessly) then the warning message is not +sent. The default is +.display asis +delay_warning_condition = \ + ${if match{$h_precedence:}{(?i)bulk|list|junk}{no}{yes}} +.endd +which suppresses the sending of warnings about messages that have `bulk', +`list' or `junk' in a ::Precedence:: header. + +.index unprivileged delivery +.index delivery||unprivileged +.conf deliver@_drop@_privilege boolean false +If this option is set true, Exim drops its root privilege at the start of a +delivery process, and runs as the Exim user throughout. This severely restricts +the kinds of local delivery that are possible, but is viable in certain types +of configuration. There is a discussion about the use of root privilege in +chapter ~~CHAPsecurity. + +.index load average +.index queue runner||abandoning +.conf deliver@_queue@_load@_max fixed-point unset +When this option is set, a queue run is abandoned if the system load average +becomes greater than the value of the option. The option has no effect on +ancient operating systems on which Exim cannot determine the load average. +See also \queue@_only@_load\ and \smtp@_load@_reserve\. + +.conf delivery@_date@_remove boolean true +.index ::Delivery-date:: header line +Exim's transports have an option for adding a ::Delivery-date:: header to a +message when it is delivered -- in exactly the same way as ::Return-path:: is +handled. ::Delivery-date:: records the actual time of delivery. Such headers +should not be present in incoming messages, and this option causes them to be +removed at the time the message is received, to avoid any problems that might +occur when a delivered message is subsequently sent on to some other recipient. + +.index DNS||`try again' response, overriding +.conf dns@_again@_means@_nonexist "domain list$**$" unset +DNS lookups give a `try again' response for the DNS errors `non-authoritative +host not found' and `\\SERVERFAIL\\'. This can cause Exim to keep trying to +deliver a message, or to give repeated temporary errors to incoming mail. +Sometimes the effect is caused by a badly set up name server and may persist +for a long time. If a domain which exhibits this problem matches anything in +\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 +.nem + +.index DNS||pre-check of name syntax +.conf dns@_check@_names@_pattern string "see below" +When this option is set to a non-empty string, it causes Exim to check domain +names for illegal characters before handing them to the DNS resolver, because +some resolvers give temporary errors for malformed names. If a domain name +contains any illegal characters, a `not found' result is forced, and the +resolver is not called. The check is done by matching the domain name against a +regular expression, which is the value of this option. The default pattern is +.display asis +dns_check_names_pattern = \ + (?i)^(?>(?(1)\.|())[^\W_](?>[a-z0-9-]*[^\W_])?)+$ +.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 +option to an empty string. + +.conf dns@_ipv4@_lookup "domain list$**$" unset +.index IPv6||DNS lookup for AAAA records +.index DNS||IPv6 lookup for AAAA records +When Exim is compiled with IPv6 support, it looks for IPv6 address records +(AAAA and, if configured, A6) as well as IPv4 address records when trying to +find IP addresses for hosts, unless the host's domain matches this list. + +This is a fudge to help with name servers that give big delays or otherwise do +not work for the new IPv6 record types. If Exim is handed an IPv6 address +record as a result of an MX lookup, it always recognizes it, and may as a +result make an outgoing IPv6 connection. All this option does is to make Exim +look only for IPv4-style A records when it needs to find an IP address for a +host name. In due course, when the world's name servers have all been upgraded, +there should be no need for this option. + +.conf dns@_retrans time 0s +.index DNS||resolver options +The options \dns@_retrans\ and \dns@_retry\ can be used to set the +retransmission and retry parameters for DNS lookups. Values of zero (the +defaults) leave the system default settings unchanged. The first value is the +time between retries, and the second is the number of retries. It isn't +totally clear exactly how these settings affect the total time a DNS lookup may +take. I haven't found any documentation about timeouts on DNS lookups; these +parameter values are available in the external resolver interface structure, +but nowhere does it seem to describe how they are used or what you might want +to set in them. + +.conf dns@_retry integer 0 +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 +described in section ~~SECTlineendings. + +.conf envelope@_to@_remove boolean true +.index ::Envelope-to:: header line +Exim's transports have an option for adding an ::Envelope-to:: header to a +message when it is delivered -- in exactly the same way as ::Return-path:: is +handled. ::Envelope-to:: records the original recipient address from the +messages's envelope that caused the delivery to happen. Such headers should not +be present in incoming messages, and this option causes them to be removed at +the time the message is received, to avoid any problems that might occur when a +delivered message is subsequently sent on to some other recipient. + +.conf errors@_copy "string list$**$" unset +.index bounce message||copy to other address +.index copy of bounce message +Setting this option causes Exim to send bcc copies of bounce messages that it +generates to other addresses. \**Note**\: this does not apply to bounce messages +coming from elsewhere. The value of the option is a colon-separated list of +items. Each item consists of a pattern, terminated by white space, followed by +a comma-separated list of email addresses. If a pattern contains spaces, it +must be enclosed in double quotes. + +Each pattern is processed in the same way as a single item in an address list +(see section ~~SECTaddresslist). When a pattern matches the recipient of the +bounce message, the message is copied to the addresses on the list. The items +are scanned in order, and once a matching one is found, no further items are +examined. For example: +.display asis +errors_copy = spqr@mydomain postmaster@mydomain.example :\ + rqps@mydomain hostmaster@mydomain.example,\ + postmaster@mydomain.example +.endd +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\ +variables \$0$\, \$1$\, etc. are set in the normal way. + +.conf errors@_reply@_to string unset +.index bounce message||::Reply-to:: in +Exim's bounce and delivery warning messages contain the header line +.display +From: Mail Delivery System @<Mailer-Daemon@@<<qualify-domain>>@> +.endd +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: +.display asis +errors_reply_to = postmaster@my.domain.example +.endd +The value of the option is not expanded. It must specify a valid RFC 2822 +address. + +.conf exim@_group string "compile-time configured" +.index gid (group id)||Exim's own +.index Exim group +This option changes the gid under which Exim runs when it gives up root +privilege. The default value is compiled into the binary. The value of this +option is used only when \exim@_user\ is also set. Unless it consists entirely +of digits, the string is looked up using \*getgrnam()*\, and failure causes a +configuration error. See chapter ~~CHAPsecurity for a discussion of security +issues. + +.conf exim@_path string "see below" +.index Exim binary, path name +This option specifies the path name of the Exim binary, which is used when Exim +needs to re-exec itself. The default is set up to point to the file \*exim*\ in +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 +settings such as the value of \spool@_directory\.) + +.conf exim@_user string "compile-time configured" +.index uid (user id)||Exim's own +.index Exim user +This option changes the uid under which Exim runs when it gives up root +privilege. The default value is compiled into the binary. Ownership of the run +time configuration file and the use of the \-C-\ and \-D-\ command line options +is checked against the values in the binary, not what is set here. + +Unless it consists entirely of digits, the string is looked up using +\*getpwnam()*\, and failure causes a configuration error. If \exim@_group\ is +not also supplied, the gid is taken from the result of \*getpwnam()*\ if it is +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 +~~SECTreclocipadd for details. + +.conf extract@_addresses@_remove@_arguments boolean true +.index \-t-\ option +.index command line||addresses with \-t-\ +.index Sendmail compatibility||\-t-\ option +According to some Sendmail documentation (Sun, IRIX, HP-UX), if any addresses +are present on the command line when the \-t-\ option is used to build an +envelope from a message's ::To::, ::Cc:: and ::Bcc:: headers, the command line +addresses are removed from the recipients list. This is also how Smail behaves. +However, other Sendmail documentation (the O'Reilly book) states that command +line addresses are added to those obtained from the header lines. When +\extract@_addresses@_remove@_arguments\ is true (the default), Exim subtracts +argument headers. If it is set false, Exim adds rather than removes argument +addresses. + +.conf finduser@_retries integer 0 +.index NIS, looking up users, retrying +On systems running NIS or other schemes in which user and group information is +distributed from a remote system, there can be times when \*getpwnam()*\ and +related functions fail, even when given valid data, because things time out. +Unfortunately these failures cannot be distinguished from genuine `not found' +errors. If \finduser@_retries\ is set greater than zero, Exim will try that +many extra times to find a user or a group, waiting for one second between +retries. + +.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, +or in an ACL, +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 +locally-generated +bounce message. (Without this exception there is the possibility of looping.) +The warning message is sent to the addresses supplied as the comma-separated +value of this option. If several of the message's addresses cause freezing, +only a single message is sent. +If the freezing was automatic, the reason(s) for freezing can be found in the +message log. If you configure freezing in a filter or ACL, you must arrange for +any logging that you require. + +.conf gecos@_name string$**$ unset +.index HP-UX +.index `gecos' field, parsing +Some operating systems, notably HP-UX, use the `gecos' field in the system +password file to hold other information in addition to users' real names. Exim +looks up this field for use when it is creating ::Sender:: or ::From:: headers. +If either \gecos@_pattern\ or \gecos@_name\ are unset, the contents of the +field are used unchanged, except that, if an ampersand is encountered, it is +replaced by the user's login name with the first character forced to +upper case, since this is a convention that is observed on many systems. + +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\ +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: +.display asis +gecos_pattern = ([^,]*) +gecos_name = $1 +.endd + +.conf gecos@_pattern string unset +See \gecos@_name\ above. + +.conf headers@_charset string "see below" +This option sets a default character set for translating from encoded MIME +`words' in header lines, when referenced by an \$h@_xxx$\ expansion item. The +default is the value of \\HEADERS@_CHARSET\\ in \(Local/Makefile)\. The +ultimate default is ISO-8859-1. For more details see the description of header +insertions in section ~~SECTexpansionitems. + + +.conf header@_maxsize integer "see below" +.index header section||maximum size of +.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 +sections are rejected. + +.conf header@_line@_maxsize integer 0 +.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 +header lines that are longer than the limit are rejected. The default value of +zero means `no limit'. + + + +.conf helo@_accept@_junk@_hosts "host list$**$" unset +.index \\HELO\\||accepting junk data +.index \\EHLO\\||accepting junk data +Exim checks the syntax of \\HELO\\ and \\EHLO\\ commands for incoming SMTP +mail, and gives an error response for invalid data. Unfortunately, there are +some SMTP clients that send syntactic junk. They can be accommodated by setting +this option. Note that this is a syntax check only. See \helo@_verify@_hosts\ +if you want to do semantic checking. +See also \helo@_allow@_chars\ for a way of extending the permitted character +set. + +.conf helo@_allow@_chars string unset +.index \\HELO\\||underscores in +.index \\EHLO\\||underscores in +.index underscore in \\EHLO\\/\\HELO\\ +This option can be set to a string of rogue characters that are permitted in +all \\EHLO\\ and \\HELO\\ names in addition to the standard letters, digits, +hyphens, and dots. If you really must allow underscores, you can set +.display asis +helo_allow_chars = _ +.endd +Note that the value is one string, not a list. + +.conf helo@_lookup@_domains "domain list$**$" "$tt{@@:@@[]}" +.index \\HELO\\||forcing reverse lookup +.index \\EHLO\\||forcing reverse lookup +If the domain given by a client in a \\HELO\\ or \\EHLO\\ command matches this +list, a reverse lookup is done in order to establish the host's true name. The +default forces a lookup if the client host gives the server's name or any of +its IP addresses (in brackets), something that broken clients have been seen to +do. + +.conf helo@_try@_verify@_hosts "host list$**$" unset +.index \\HELO\\||verifying, optional +.index \\EHLO\\||verifying, optional +The RFCs mandate that a server must not reject a message because it doesn't +like the \\HELO\\ or \\EHLO\\ command. By default, Exim just checks the syntax +of these commands (see \helo__accept__junk__hosts\ and \helo@_allow@_chars\ +above). However, some sites like to be stricter. If the calling host matches +\helo@_try@_verify@_hosts\, Exim checks that the host name given in the \\HELO\\ +or \\EHLO\\ command either: +.numberpars $. +is an IP literal matching the calling address of the host (the RFCs +specifically allow this), or +.nextp +.index DNS||reverse lookup +.index reverse DNS lookup +matches the host name that Exim obtains by doing a reverse lookup of the +calling host address, or +.nextp +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 +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@_verify@_hosts\ instead. + + +.conf helo@_verify@_hosts "host list$**$" unset +.index \\HELO\\||verifying, mandatory +.index \\EHLO\\||verifying, mandatory +For hosts that match this option, Exim checks the host name given in the +\\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 +error. + +.conf hold@_domains "domain list$**$" unset +.index domain||delaying delivery +.index delivery||delaying certain domains +This option allows mail for particular domains to be held on the queue +manually. The option is overridden if a message delivery is forced with the +\-M-\, \-qf-\, \-Rf-\ or \-Sf-\ options, and also while testing or verifying +addresses using \-bt-\ or \-bv-\. Otherwise, if a domain matches an item in +\hold@_domains\, no routing or delivery for that address is done, and it is +deferred every time the message is looked at. + +This option is intended as a temporary operational measure for delaying the +delivery of mail while some problem is being sorted out, or some new +configuration tested. If you just want to delay the processing of some +domains until a queue run occurs, you should use \queue@_domains\ or +\queue@_smtp@_domains\, not \hold@_domains\. + +A setting of \hold@_domains\ does not override Exim's code for removing +messages from the queue if they have been there longer than the longest retry +time in any retry rule. If you want to hold messages for longer than the normal +retry times, insert a dummy retry rule with a long retry time. + +.conf host@_lookup "host list$**$" unset +.index host||name lookup, forcing +Exim does not look up the name of a calling host from its IP address unless it +is required to compare against some host list, or the host matches +\helo@_try@_verify@_hosts\ or \helo@_verify@_hosts\, or the host matches this +option (which normally contains IP addresses rather than host names). The +default configuration file contains +.display asis +host_lookup = * +.endd +which causes a lookup to happen for all hosts. If the expense of these lookups +is felt to be too great, the setting can be changed or removed. + +After a successful reverse lookup, Exim does a forward lookup on the name it +has obtained, to verify that it yields the IP address that it started with. If +this check fails, Exim behaves as if the name lookup failed. + +After any kind of failure, the host name (in \$sender@_host@_name$\) remains +unset, and \$host@_lookup@_failed$\ is set to the string `1'. See also +\dns@_again@_means@_nonexist\, \helo__lookup__domains\, and \"verify = +reverse@_host@_lookup"\ in ACLs. + +.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 +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 +\(/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. +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. + +The ability to give an immediate rejection (either by this option or using an +ACL) is provided for use in unusual cases. Many hosts will just try again, +sometimes without much delay. Normally, it is better to use an ACL to reject +incoming messages at a later stage, such as after \\RCPT\\ commands. See +chapter ~~CHAPACL. + +.conf hosts@_treat@_as@_local "domain list$**$" unset +.index local host||domains treated as +.index host||treated as local +If this option is set, any host names that match the domain list are treated as +if they were the local host when Exim is scanning host lists obtained from MX +records +or other sources. Note that the value of this option is a domain list, not a +host list, because it is always used to check host names, not IP addresses. + +This option also applies when Exim is matching the special items +\"@@mx@_any"\, \"@@mx@_primary"\, and \"@@mx@_secondary"\ in a domain list (see +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 +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 +suffer temporary delivery failures are of course retried in the usual way.) + +After a permanent delivery failure, bounce messages are frozen, +because there is no sender to whom they can be returned. When a frozen bounce +message has been on the queue for more than the given time, it is unfrozen at +the next queue run, and a further delivery is attempted. If delivery fails +again, the bounce message is discarded. This makes it possible to keep failed +bounce messages around for a shorter time than the normal maximum retry time +for frozen messages. For example, +.display asis +ignore_bounce_errors_after = 12h +.endd +retries failed bounce message deliveries after 12 hours, discarding any further +failures. If the value of this option is set to a zero time period, bounce +failures are discarded immediately. Setting a very long time (as in the default +value) has the effect of disabling this option. For ways of automatically +dealing with other kinds of frozen message, see \auto@_thaw\ and +\timeout@_frozen@_after\. + +.conf ignore@_fromline@_hosts "host list$**$" unset +.index `From' line +.index UUCP||`From' line +Some broken SMTP clients insist on sending a UUCP-like `From' line before the +headers of a message. By default this is treated as the start of the message's +body, which means that any following headers are not recognized as such. Exim +can be made to ignore it by setting \ignore@_fromline@_hosts\ to match those +hosts that insist on sending it. If the sender is actually a local process +rather than a remote host, and is using \-bs-\ to inject the messages, +\ignore__fromline__local\ must be set to achieve this effect. + +.conf ignore@_fromline@_local boolean false +See \ignore@_fromline@_hosts\ above. + +.conf keep@_malformed time 4d +This option specifies the length of time to keep messages whose spool files +have been corrupted in some way. This should, of course, never happen. At the +next attempt to deliver such a message, it gets removed. The incident is +logged. + +.conf ldap@_default@_servers "string list" unset +.index LDAP||default servers +This option provides a list of LDAP servers which are tried in turn when an +LDAP query does not contain a server. See section ~~SECTforldaque for details +of LDAP queries. This option is available only when Exim has been built with +LDAP support. + +.conf ldap@_version integer unset +.index LDAP||protocol version, forcing +This option can be used to force Exim to set a specific protocol version for +LDAP. If it option is unset, it is shown by the \-bP-\ command line option as +-1. When this is the case, the default is 3 if \\LDAP@_VERSION3\\ is defined in +the LDAP headers; otherwise it is 2. This option is available only when Exim +has been built with LDAP support. + + +.conf local@_from@_check boolean true +.index ::Sender:: header line||disabling addition of +.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. + +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 +::Sender:: header lines supplied by untrusted users, you must also set +\local@_sender@_retain\ to be true. + +.index envelope sender +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. + + +.conf local@_from@_prefix string unset +When Exim checks the ::From:: header line of locally submitted messages for +matching the login id (see \local@_from@_check\ above), it can be configured to +ignore certain prefixes and suffixes in the local part of the address. This is +done by setting \local@_from@_prefix\ and/or \local@_from@_suffix\ to +appropriate lists, in the same form as the \local@_part@_prefix\ and +\local@_part@_suffix\ router options (see chapter ~~CHAProutergeneric). For +example, if +.display asis +local_from_prefix = *- +.endd +is set, a ::From:: line containing +.display asis +From: anything-user@your.domain.example +.endd +will not cause a ::Sender:: header to be added if \*user@@your.domain.example*\ +matches the actual sender address that is constructed from the login name and +qualify domain. + +.conf local@_from@_suffix 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 +.display asis +local_interfaces = 0.0.0.0 +.endd +when Exim is built without IPv6 support; otherwise it is +.display asis +local_interfaces = <; ::0 ; 0.0.0.0 +.endd + +.conf local@_scan@_timeout time 5m +.index timeout||for \*local@_scan()*\ function +.index \*local@_scan()*\ function||timeout +This timeout applies to the \*local@_scan()*\ function (see chapter +~~CHAPlocalscan). Zero means `no timeout'. If the timeout is exceeded, the +incoming message is rejected with a temporary error if it is an SMTP message. +For a non-SMTP message, the message is dropped and Exim ends with a non-zero +code. The incident is logged on the main and reject logs. + + +.conf local@_sender@_retain boolean false +.index ::Sender:: header line||retaining from local submission +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. If you +do not want this to happen, you must set \local@_sender@_retain\, and you must +also set \local@_from@_check\ to be false (Exim will complain if you do not). +Section ~~SECTthesenhea has more details about ::Sender:: processing. + + + +.conf localhost@_number string$**$ unset +.index host||locally unique number for +.index message||ids, with multiple hosts +Exim's message ids are normally unique only within the local host. If +uniqueness among a set of hosts is required, each host must set a different +value for the \localhost@_number\ option. The string is expanded immediately +after reading the configuration file (so that a number can be computed from the +host name, for example) and the result of the expansion must be a number in the +range 0--16 (or 0--10 on operating systems with case-insensitive file systems). +This is available in subsequent string expansions via the variable +\$localhost@_number$\. When \localhost@_number is set\, the final two +characters of the message id, instead of just being a fractional part of the +time, are computed from the time and the local host number as described in +section ~~SECTmessiden. + + +.conf log@_file@_path "string list$**$" "set at compile time" +.index log||file path for +This option sets the path which is used to determine the names of Exim's log +files, or indicates that logging is to be to syslog, or both. It is expanded +when Exim is entered, so it can, for example, contain a reference to the host +name. If no specific path is set for the log files at compile or run time, they +are written in a sub-directory called \(log)\ in Exim's spool directory. +Chapter ~~CHAPlog contains further details about Exim's logging, and section +~~SECTwhelogwri describes how the contents of \log@_file@_path\ are used. If +this string is fixed at your installation (contains no expansion variables) it +is recommended that you do not set this option in the configuration file, but +instead supply the path using \\LOG@_FILE@_PATH\\ in \(Local/Makefile)\ so that +it is available to Exim for logging errors detected early on -- in particular, +failure to read the configuration file. + +.conf log@_selector string unset +.index log||selectors +This option can be used to reduce or increase the number of things that Exim +writes to its log files. Its argument is made up of names preceded by plus or +minus characters. For example: +.display asis +log_selector = +arguments -retry_defer +.endd +A list of possible names and what they control is given in the chapter on +logging, in section ~~SECTlogselector. + +.conf log@_timezone boolean false +.index log||timezone for entries +By default, the timestamps on log lines are in local time without the +timezone. This means that if your timezone changes twice a year, the timestamps +in log lines are ambiguous for an hour when the clocks go back. One way of +avoiding this problem is to set the timezone to UTC. An alternative is to set +\log@_timezone\ true. This turns on the addition of the timezone offset to +timestamps in log lines. Turning on this option can add quite a lot to the size +of log files because each line is extended by 6 characters. Note that the +\$tod@_log$\ variable contains the log timestamp without the zone, but there is +another variable called \$tod@_zone$\ that contains just the timezone offset. + +.conf lookup@_open@_max integer 25 +.index too many open files +.index open files, too many +.index file||too many open +.index lookup||maximum open files +.index limit||open files for lookups +This option limits the number of simultaneously open files for single-key +lookups that use regular files (that is, \%lsearch%\, \%dbm%\, and \%cdb%\). Exim +normally keeps these files open during routing, because often the same file is +required several times. If the limit is reached, Exim closes the least recently +used file. Note that if you are using the \*ndbm*\ library, it actually opens +two files for each logical DBM database, though it still counts as one for the +purposes of \lookup@_open@_max\. If you are getting `too many open files' +errors with NDBM, you need to reduce the value of \lookup@_open@_max\. + +.conf max@_username@_length integer 0 +.index length of login name +.index user name||maximum length +.index limit||user name length +Some operating systems are broken in that they truncate long arguments to +\*getpwnam()*\ to eight characters, instead of returning `no such user'. If +this option is set greater than zero, any attempt to call \*getpwnam()*\ with +an argument that is longer behaves as if \*getpwnam()*\ failed. + + +.conf message@_body@_visible integer 500 +.index body of message||visible size +.index message||body, visible size +This option specifies how much of a message's body is to be included in the +\$message@_body$\ and \$message@_body@_end$\ expansion variables. + +.conf message@_id@_header@_domain string$**$ unset +.index ::Message-ID:: header line +If this option is set, the string is expanded and used as the right hand side +(domain) of the ::Message-ID:: header that Exim creates if a +locally-originated incoming message does not have one. `Locally-originated' +means `not received over TCP/IP.' +Otherwise, the primary host name is used. +Only letters, digits, dot and hyphen are accepted; any other characters are +replaced by hyphens. If the expansion is forced to fail, or if the result is an +empty string, the option is ignored. + +.conf message@_id@_header@_text string$**$ unset +If this variable is set, the string is expanded and used to augment the text of +the ::Message-id:: header that Exim creates if a +locally-originated +incoming message does not have one. The text of this header is required by RFC +2822 to take the form of an address. By default, Exim uses its internal message +id as the local part, and the primary host name as the domain. If this option +is set, it is expanded, and provided the expansion is not forced to fail, and +does not yield an empty string, the result is inserted into the header +immediately before the @@, separated from the internal message id by a dot. Any +characters that are illegal in an address are automatically converted into +hyphens. This means that variables such as \$tod@_log$\ can be used, because +the spaces and colons will become hyphens. + +.conf message@_logs boolean true +.index message||log, disabling +.index log||message log, disabling +If this option is turned off, per-message log files are not created in the +\(msglog)\ spool sub-directory. This reduces the amount of disk I/O required by +Exim, by reducing the number of files involved in handling a message from a +minimum of four (header spool file, body spool file, delivery journal, and +per-message log) to three. The other major I/O activity is Exim's main log, +which is not affected by this option. + +.conf message@_size@_limit string$**$ 50M +.index message||size limit +.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 +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 +message, because it has to be advertised in the server's response to \\EHLO\\. +String expansion failure causes a temporary error. A value of zero means no +limit, but its use is not recommended. See also \bounce@_return@_size@_limit\. + +Incoming SMTP messages are failed with a 552 error if the limit is +exceeded; locally-generated messages either get a stderr message or a delivery +failure message to the sender, depending on the \-oe-\ setting. Rejection of an +oversized message is logged in both the main and the reject logs. See also the +generic transport option \message@_size@_limit\, which limits the size of +message that an individual transport can process. + +.conf move@_frozen@_messages boolean false +.index frozen messages||moving +This option, which is available only if Exim has been built with the setting +.display asis +SUPPORT_MOVE_FROZEN_MESSAGES=yes +.endd +in \(Local/Makefile)\, causes frozen messages and their message logs to be +moved from the \(input)\ and \(msglog)\ directories on the spool to \(Finput)\ +and \(Fmsglog)\, respectively. There is currently no support in Exim or the +standard utilities for handling such moved messages, and they do not show up in +lists generated by \-bp-\ or by the Exim monitor. + +.conf mysql@_servers "string list" unset +.index MySQL||server list +This option provides a list of MySQL servers and associated connection data, to +be used in conjunction with \%mysql%\ lookups (see section ~~SECTsql). The +option is available only if Exim has been built with MySQL support. + +.conf never@_users "string list" unset +Local message deliveries are normally run in processes that are setuid to the +recipient, and remote deliveries are normally run under Exim's own uid and gid. +It is usually desirable to prevent any deliveries from running as root, as a +safety precaution. + +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 +\never@_users\ list, an error occurs, and delivery is deferred. A common +example is +.display +never@_users = root:daemon:bin +.endd +Including root is redundant if it is also on the fixed list, but it does no +harm. +This option overrides the \pipe@_as@_creator\ option of the \%pipe%\ transport +driver. + +.conf oracle@_servers "string list" unset +.index Oracle||server list +This option provides a list of Oracle servers and associated connection data, +to be used in conjunction with \%oracle%\ lookups (see section ~~SECTsql). The +option is available only if Exim has been built with Oracle support. + +.conf percent@_hack@_domains "domain list$**$" unset +.index `percent hack' +.index source routing||in email address +.index address||source-routed +The `percent hack' is the convention whereby a local part containing a percent +sign is re-interpreted as a new email address, with the percent replaced by @@. +This is sometimes called `source routing', though that term is also applied to +RFC 2822 addresses that begin with an @@ character. If this option is set, Exim +implements the percent facility for those domains listed, but no others. This +happens before an incoming SMTP address is tested against an ACL. + +\**Warning**\: The `percent hack' has often been abused by people who are +trying to get round relaying restrictions. For this reason, it is best avoided +if at all possible. Unfortunately, a number of less security-conscious MTAs +implement it unconditionally. If you are running Exim on a gateway host, and +routing mail through to internal MTAs without processing the local parts, it is +a good idea to reject recipient addresses with percent characters in their +local parts. Exim's default configuration does this. + +.conf perl@_at@_start boolean false +This option is available only when Exim is built with an embedded Perl +interpreter. See chapter ~~CHAPperl for details of its use. + +.conf perl@_startup string unset +This option is available only when Exim is built with an embedded Perl +interpreter. See chapter ~~CHAPperl for details of its use. + +.conf pgsql@_servers "string list" unset +.index PostgreSQL lookup type||server list +This option provides a list of PostgreSQL servers and associated connection +data, to be used in conjunction with \%pgsql%\ lookups (see section ~~SECTsql). +The option is available only if Exim has been built with PostgreSQL support. + +.conf pid@_file@_path string$**$ "set at compile time" +.index daemon||pid file path +.index pid file, path for +This option sets the name of the file to which the Exim daemon writes its +process id. The string is expanded, so it can contain, for example, references +to the host name: +.display asis +pid_file_path = /var/log/$primary_hostname/exim.pid +.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 \-oX-\ option, unless a path is explicitly supplied by \-oP-\. + +.conf pipelining@_advertise@_hosts "host list$**$" $*$ +.index \\PIPELINING\\||advertising, suppressing +This option can be used to suppress the advertisement of the SMTP +\\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 +\smtp@_max@_synprot@_errors\). +.nem + +.conf preserve@_message@_logs boolean false +.index message logs, preserving +If this option is set, message log files are not deleted when messages are +completed. Instead, they are moved to a sub-directory of the spool directory +called \(msglog.OLD)\, where they remain available for statistical or debugging +purposes. This is a dangerous option to set on systems with any appreciable +volume of mail. Use with care! + +.conf primary@_hostname string "see below" +.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 +.index 8-bit characters +By default, Exim considers only those characters whose codes lie in the range +32--126 to be printing characters. In a number of circumstances (for example, +when writing log entries) non-printing characters are converted into escape +sequences, primarily to avoid messing up the layout. If \print@_topbitchars\ is +set, code values of 128 and above are also considered to be printing +characters. + +.conf process@_log@_path string unset +.index process log path +.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 +script. If this option is unset, the file called \(exim-process.info)\ in +Exim's spool directory is used. The ability to specify the name explicitly can +be useful in environments where two different Exims are running, using +different spool directories. + +.conf prod@_requires@_admin boolean true +.index \-M-\ option +.index \-R-\ option +.index \-q-\ option +The \-M-\, \-R-\, and \-q-\ command-line options require the caller to be an +admin user unless \prod@_requires@_admin\ is set false. See also +\queue@_list@_requires@_admin\. + +.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. + +.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. + +.conf queue@_domains "domain list$**$" unset +.index domain||specifying non-immediate delivery +.index queueing incoming messages +.index message||queueing certain domains +This option lists domains for which immediate delivery is not required. +A delivery process is started whenever a message is received, but only those +domains that do not match are processed. All other deliveries wait until the +next queue run. See also \hold@_domains\ and \queue@_smtp@_domains\. + +.conf queue@_list@_requires@_admin boolean true +.index \-bp-\ option +The \-bp-\ command-line option, which lists the messages that are on the queue, +requires the caller to be an admin user unless \queue__list__requires__admin\ +is set false. See also \prod@_requires@_admin\. + +.conf queue@_only boolean false +.index queueing incoming messages +.index message||queueing unconditionally +If \queue@_only\ is set, a delivery process is not automatically started +whenever a message is received. Instead, the message waits on the queue for the +next queue run. Even if \queue@_only\ is false, incoming messages may not get +delivered immediately when certain conditions (such as heavy load) occur. + +The \-odq-\ command line has the same effect as \queue@_only\. The \-odb-\ and +\-odi-\ command line options override \queue@_only\ unless +\queue@_only@_override\ is set false. See also \queue@_only@_file\, +\queue@_only@_load\, and \smtp@_accept@_queue\. + +.conf queue@_only@_file string unset +.index queueing incoming messages +.index message||queueing by file existence +This option can be set to a colon-separated list of absolute path names, each +one optionally preceded by `smtp'. When Exim is receiving a message, +it tests for the existence of each listed path using a call to \*stat()*\. For +each path that exists, the corresponding queuing option is set. +For paths with no prefix, \queue@_only\ is set; for paths prefixed by `smtp', +\queue@_smtp@_domains\ is set to match all domains. So, for example, +.display asis +queue_only_file = smtp/some/file +.endd +causes Exim to behave as if \queue@_smtp@_domains\ were set to `$*$' whenever +\(/some/file)\ exists. + +.conf queue@_only@_load fixed-point unset +.index load average +.index queueing incoming messages +.index message||queueing by load +If the system load average is higher than this value, incoming messages from +all sources are queued, and no automatic deliveries are started. If this +happens during local or remote SMTP input, all subsequent messages on the same +connection are queued. Deliveries will subsequently be performed by queue +runner processes. This option has no effect on ancient operating systems on +which Exim cannot determine the load average. See also +\deliver@_queue@_load@_max\ and \smtp@_load@_reserve\. + +.conf queue@_only@_override boolean true +.index queueing incoming messages +When this option is true, the \-od\*x*\-\ command line options override the +setting of \queue@_only\ or \queue@_only@_file\ in the configuration file. If +\queue@_only@_override\ is set false, the \-od\*x*\-\ options cannot be used to +override; they are accepted, but ignored. + +.conf queue@_run@_in@_order boolean false +.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. + +.conf queue@_run@_max integer 5 +.index queue runner||maximum number of +This controls the maximum number of queue runner processes that an Exim daemon +can run simultaneously. This does not mean that it starts them all at once, +but rather that if the maximum number are still running when the time comes to +start another one, it refrains from starting another one. This can happen with +very large queues and/or very sluggish deliveries. This option does not, +however, interlock with other processes, so additional queue runners can be +started by other means, or by killing and restarting the daemon. + +.conf queue@_smtp@_domains "domain list$**$" unset +.index queueing incoming messages +.index message||queueing remote deliveries +When this option is set, a delivery process is started whenever a message is +received, routing is performed, and local deliveries take place. +However, if any SMTP deliveries are required for domains that match +\queue@_smtp@_domains\, they are not immediately delivered, but instead the +message waits on the queue for the next queue run. Since routing of the message +has taken place, Exim knows to which remote hosts it must be delivered, and so +when the queue run happens, multiple messages for the same host are delivered +over a single SMTP connection. The \-odqs-\ command line option causes all SMTP +deliveries to be queued in this way, and is equivalent to setting +\queue@_smtp@_domains\ to `$*$'. See also \hold@_domains\ and \queue@_domains\. + +.conf receive@_timeout time 0s +.index timeout||for non-SMTP input +This option sets the timeout for accepting a non-SMTP message, that is, the +maximum time that Exim waits when reading a message on the standard input. If +the value is zero, it will wait for ever. This setting is overridden by the +\-or-\ command line option. The timeout for incoming SMTP messages is +controlled by \smtp@_receive@_timeout\. + +.index customizing|| ::Received:: header +.index ::Received:: header line||customizing +.conf received@_header@_text string$**$ "see below" +This string defines the contents of the ::Received:: message header that is +added to each message, except for the timestamp, which is automatically added +on at the end (preceded by a semicolon). The string is expanded each time it is +used. If the expansion yields an empty string, no ::Received:: header line is +added to the message. Otherwise, the string should start with the text +`Received:' and conform to the RFC 2822 specification for ::Received:: header +lines. The default setting is: +.display asis +received_header_text = Received: \ + ${if def:sender_rcvhost {from $sender_rcvhost\n\t}\ + {${if def:sender_ident {from $sender_ident }}\ + ${if def:sender_helo_name {(helo=$sender_helo_name)\n\t}}}}\ + by $primary_hostname \ + ${if def:received_protocol {with $received_protocol}} \ + ${if def:tls_cipher {($tls_cipher)\n\t}}\ + (Exim $version_number)\n\t\ + id $message_id\ + ${if def:received_for {\n\tfor $received_for}} +.endd +Note the use of quotes, to allow the sequences \"@\n"\ and \"@\t"\ to be used +for newlines and tabs, respectively. The reference to the TLS cipher is omitted +when Exim is built without TLS support. The use of conditional expansions +ensures that this works for both locally generated messages and messages +received from remote hosts, giving header lines such as the following: +.display asis +Received: from scrooge.carol.example ([192.168.12.25] ident=root) + by marley.carol.example with esmtp (Exim 4.00) + id 16IOWa-00019l-00 + for chas@dickens.example; Tue, 25 Dec 2001 14:43:44 +0000 +Received: by scrooge.carol.example with local (Exim 4.00) + id 16IOWW-000083-00; Tue, 25 Dec 2001 14:43:41 +0000 +.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 +message was accepted. +.nem + +.conf received@_headers@_max integer 30 +.index loop||prevention +.index mail loop prevention +.index ::Received:: header line||counting +When a message is to be delivered, the number of ::Received:: headers is +counted, and if it is greater than this parameter, a mail loop is assumed to +have occurred, the delivery is abandoned, and an error message is generated. +This applies to both local and remote deliveries. + +.conf recipient@_unqualified@_hosts "host list$**$" unset +.index unqualified addresses +.index host||unqualified addresses from +This option lists those hosts from which Exim is prepared to accept unqualified +recipient addresses in message envelopes. The addresses are made fully +qualified by the addition of the \qualify@_recipient\ value. This option also +affects message header lines. Exim does not reject unqualified recipient +addresses in headers, but it qualifies them only if the message came from a +host that matches \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 +If this option is set greater than zero, it specifies the maximum number of +original recipients for any message. Additional recipients that are generated +by aliasing or forwarding do not count. SMTP messages get a 452 response for +all recipients over the limit; earlier recipients are delivered as normal. +Non-SMTP messages with too many recipients are failed, and no deliveries are +done. +.index \\RCPT\\||maximum number of incoming +Note that the RFCs specify that an SMTP server should accept at least 100 +\\RCPT\\ commands in a single message. + +.conf recipients@_max@_reject boolean false +If this option is set true, Exim rejects SMTP messages containing too many +recipients by giving 552 errors to the surplus \\RCPT\\ commands, and a 554 +error to the eventual \\DATA\\ command. Otherwise (the default) it gives a 452 +error to the surplus \\RCPT\\ commands and accepts the message on behalf of the +initial set of recipients. The remote server should then re-send the message +for the remaining recipients at a later time. + +.conf remote@_max@_parallel integer 2 +.index delivery||parallelism for remote +This option controls parallel delivery of one message to a number of remote +hosts. If the value is less than 2, parallel delivery is disabled, and Exim +does all the remote deliveries for a message one by one. Otherwise, if a single +message has to be delivered to more than one remote host, or if several copies +have to be sent to the same remote host, up to \remote@_max@_parallel\ +deliveries are done simultaneously. If more than \remote@_max@_parallel\ +deliveries are required, the maximum number of processes are started, and as +each one finishes, another is begun. The order of starting processes is the +same as if sequential delivery were being done, and can be controlled by the +\remote@_sort@_domains\ option. If parallel delivery takes place while running +with debugging turned on, the debugging output from each delivery process is +tagged with its process id. + +This option controls only the maximum number of parallel deliveries for one +message in one Exim delivery process. Because Exim has no central queue +manager, there is no way of controlling the total number of simultaneous +deliveries if the configuration allows a delivery attempt as soon as a message +is received. +.index number of deliveries +.index delivery||maximum number of +If you want to control the total number of deliveries on the system, you +need to set the \queue@_only\ option. This ensures that all incoming messages +are added to the queue without starting a delivery process. Then set up an Exim +daemon to start queue runner processes at appropriate intervals (probably +fairly often, for example, every minute), and limit the total number of queue +runners by setting the \queue__run__max\ parameter. Because each queue runner +delivers only one message at a time, the maximum number of deliveries that can +then take place at once is \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. + +.conf remote@_sort@_domains "domain list$**$" unset +.index sorting remote deliveries +.index delivery||sorting remote +When there are a number of remote deliveries for a message, they are sorted by +domain into the order given by this list. For example, +.display asis +remote_sort_domains = *.cam.ac.uk:*.uk +.endd +would attempt to deliver to all addresses in the \*cam.ac.uk*\ domain first, then +to those in the \uk\ domain, then to any others. + +.conf retry@_data@_expire time 7d +.index hints database||data expiry +This option sets a `use before' time on retry information in Exim's hints +database. Any older retry data is ignored. This means that, for example, once a +host has not been tried for 7 days, Exim behaves as if it has no knowledge of +past failures. + +.conf retry@_interval@_max time 24h +.index retry||limit on interval +.index limit||on retry interval +Chapter ~~CHAPretry describes Exim's mechanisms for controlling the intervals +between delivery attempts for messages that cannot be delivered straight away. +This option sets an overall limit to the length of time between retries. + +.conf return@_path@_remove boolean true +.index ::Return-path:: header line||removing +RFC 2821, section 4.4, states that an SMTP server must insert a ::Return-path:: +header line into a message when it makes a `final delivery'. The ::Return-path:: +header preserves the sender address as received in the \\MAIL\\ command. This +description implies that this header should not be present in an incoming +message. If \return@_path@_remove\ is true, any existing ::Return-path:: +headers are removed from messages at the time they are received. Exim's +transports have options for adding ::Return-path:: headers at the time of +delivery. They are normally used only for final local deliveries. + +.conf return@_size@_limit integer 100K +This option is an obsolete synonym for \bounce@_return@_size@_limit\. + +.conf rfc1413@_hosts "host list$**$" $*$ +.index RFC 1413 +.index host||for RFC 1413 calls +RFC 1413 identification calls are made to any client host which matches an item +in the list. + +.conf rfc1413@_query@_timeout time 30s +.index RFC 1413||query timeout +.index timeout||for RFC 1413 call +This sets the timeout on RFC 1413 identification calls. If it is set to zero, +no RFC 1413 calls are ever made. + +.conf sender@_unqualified@_hosts "host list$**$" unset +.index unqualified addresses +.index host||unqualified addresses from +This option lists those hosts from which Exim is prepared to accept unqualified +sender addresses. The addresses are made fully qualified by the addition of +\qualify@_domain\. This option also affects message header lines. Exim does not +reject unqualified addresses in headers that contain sender addresses, but it +qualifies them only if the message came from a host that matches +\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 +This option controls the setting of the \\SO@_KEEPALIVE\\ option on incoming +TCP/IP socket connections. When set, it causes the kernel to probe idle +connections periodically, by sending packets with `old' sequence numbers. The +other end of the connection should send an acknowledgement if the connection is +still okay or a reset if the connection has been aborted. The reason for doing +this is that it has the beneficial effect of freeing up certain types of +connection that can get stuck when the remote host is disconnected without +tidying up the TCP/IP call properly. The keepalive mechanism takes several +hours to detect unreachable hosts. + + +.conf smtp@_accept@_max integer 20 +.index limit||incoming SMTP connections +.index SMTP||incoming connection count +.index inetd +This option specifies the maximum number of simultaneous incoming SMTP calls +that Exim will accept. It applies only to the listening daemon; there is no +control (in Exim) when incoming SMTP is being handled by \*inetd*\. If the value +is set to zero, no limit is applied. However, it is required to be non-zero if +either \smtp@_accept@_max@_per@_host\ or \smtp@_accept@_queue\ is set. See also +\smtp@_accept@_reserve\. + + +.conf smtp@_accept@_max@_nonmail integer 10 +.index limit||non-mail SMTP commands +.index SMTP||limiting non-mail commands +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 host matches \smtp@_accept@_max@_nonmail@_hosts\. + +When a new message is expected, one occurrence of \\RSET\\ is not counted. This +allows a client to send one \\RSET\\ between messages (this is not necessary, +but some clients do it). Exim also allows one uncounted occurence of \\HELO\\ +or \\EHLO\\, and one occurrence of \\STARTTLS\\ between messages. After +starting up a TLS session, another \\EHLO\\ is expected, and so it too is not +counted. The first occurrence of \\AUTH\\ in a connection, or immediately +following \\STARTTLS\\ is not counted. Otherwise, all commands other than +\\MAIL\\, \\RCPT\\, \\DATA\\, and \\QUIT\\ are counted. + +.conf smtp@_accept@_max@_nonmail@_hosts "host list$**$" $*$ +You can control which hosts are subject to the \smtp@_accept@_max@_nonmail\ +check by setting this option. The default value makes it apply to all hosts. By +changing the value, you can exclude any badly-behaved hosts that you have to +live with. + + +.conf smtp@_accept@_max@_per@_connection integer 1000 +.index SMTP||incoming message count, limiting +.index limit||messages per SMTP connection +The value of this option limits the number of \\MAIL\\ commands that Exim is +prepared to accept over a single SMTP connection, whether or not each command +results in the transfer of a message. After the limit is reached, a 421 +response is given to subsequent \\MAIL\\ commands. This limit is a safety +precaution against a client that goes mad (incidents of this type have been +seen). + +.conf smtp@_accept@_max@_per@_host string$**$ unset +.index limit||SMTP connections from one host +.index host||limiting SMTP connections from +This option restricts the number of simultaneous IP connections from a single +host (strictly, from a single IP address) to the Exim daemon. The option is +expanded, to enable different limits to be applied to different hosts by +reference to \$sender@_host@_address$\. Once the limit is reached, additional +connection attempts from the same host are rejected with error code 421. The +default value of zero imposes no limit. If this option is set, it is required +that \smtp@_accept@_max\ be non-zero. + +\**Warning**\: When setting this option you should not use any expansion +constructions that take an appreciable amount of time. The expansion and test +happen in the main daemon loop, in order to reject additional connections +without forking additional processes (otherwise a denial-of-service attack +could cause a vast number or processes to be created). While the daemon is +doing this processing, it cannot accept any other incoming connections. + + +.conf smtp@_accept@_queue integer 0 +.index SMTP||incoming connection count +.index queueing incoming messages +.index message||queueing by SMTP connection count +If the number of simultaneous incoming SMTP calls handled via the listening +daemon exceeds this value, messages received by SMTP are just placed on the +queue; no delivery processes are started automatically. A value of zero implies +no limit, and clearly any non-zero value is useful only if it is less than the +\smtp@_accept@_max\ value (unless that is zero). See also \queue@_only\, +\queue@_only@_load\, \queue@_smtp@_domains\, and the various \-od-\ command +line options. + +.conf smtp@_accept@_queue@_per@_connection integer 10 +.index queueing incoming messages +.index message||queueing by message count +This option limits the number of delivery processes that Exim starts +automatically when receiving messages via SMTP, whether via the daemon or by +the use of \-bs-\ or \-bS-\. If the value of the option is greater than zero, +and the number of messages received in a single SMTP session exceeds this +number, subsequent messages are placed on the queue, but no delivery processes +are started. This helps to limit the number of Exim processes when a server +restarts after downtime and there is a lot of mail waiting for it on other +systems. On large systems, the default should probably be increased, and on +dial-in client systems it should probably be set to zero (that is, disabled). + +.conf smtp@_accept@_reserve integer 0 +.index SMTP||incoming call count +.index host||reserved +When \smtp@_accept@_max\ is set greater than zero, this option specifies a +number of SMTP connections that are reserved for connections from the hosts +that are specified in \smtp@_reserve@_hosts\. The value set in +\smtp@_accept@_max\ includes this reserve pool. The specified hosts are not +restricted to this number of connections; the option specifies a minimum number +of connection slots for them, not a maximum. It is a guarantee that that group +of hosts can always get at least \smtp@_accept@_reserve\ connections. + +For example, if \smtp@_accept@_max\ is set to 50 and \smtp@_accept@_reserve\ is +set to 5, once there are 45 active connections (from any hosts), new +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 +This option is provided for multi-homed servers that want to masquerade as +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: +.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 +.index banner for SMTP +.index welcome banner for SMTP +.index customizing||SMTP 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 +.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 +appropriate points, but not at the end. Note that the 220 code is not included +in this string. Exim adds it automatically (several times in the case of a +multiline response). + +.conf smtp@_check@_spool@_space boolean true +.index checking disk space +.index disk space, checking +.index spool directory||checking space +When this option is set, if an incoming SMTP session encounters the \\SIZE\\ +option on a \\MAIL\\ command, it checks that there is enough space in the +spool directory's partition to accept a message of that size, while still +leaving free the amount specified by \check@_spool@_space\ (even if that value +is zero). If there isn't enough space, a temporary error code is returned. + +.conf smtp@_connect@_backlog integer 20 +.index connection backlog +.index SMTP||connection backlog +.index backlog of connections +This option specifies a maximum number of waiting SMTP connections. Exim passes +this value to the TCP/IP system when it sets up its listener. Once this number +of connections are waiting for the daemon's attention, subsequent connection +attempts are refused at the TCP/IP level. At least, that is what the manuals +say; in some circumstances such connection attempts have been observed to time +out instead. For large systems it is probably a good idea to increase the +value (to 50, say). It also gives some protection against denial-of-service +attacks by SYN flooding. + +.conf smtp@_enforce@_sync boolean true +.index SMTP||synchronization checking +.index synchronization checking in SMTP +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. +.em +See also \pipelining@_advertise@_hosts\. +.nem + +.conf smtp@_etrn@_command string$**$ unset +.index \\ETRN\\||command to be run +If this option is set, the given command is run whenever an SMTP \\ETRN\\ +command is received from a host that is permitted to issue such commands (see +chapter ~~CHAPACL). The string is split up into separate arguments which are +independently expanded. The expansion variable \$domain$\ is set to the +argument of the \\ETRN\\ command, and no syntax checking is done on it. For +example: +.display asis +smtp_etrn_command = /etc/etrn_command $domain $sender_host_address +.endd +A new process is created to run the command, but Exim does not wait for it to +complete. Consequently, its status cannot be checked. If the command cannot be +run, a line is written to the panic log, but the \\ETRN\\ caller still receives +a 250 success response. Exim is normally running under its own uid when +receiving SMTP, so it is not possible for it to change the uid before running +the command. + +.conf smtp@_etrn@_serialize boolean true +.index \\ETRN\\||serializing +When this option is set, it prevents the simultaneous execution of more than +one identical command as a result of \\ETRN\\ in an SMTP connection. See +section ~~SECTETRN for details. + +.conf smtp@_load@_reserve fixed-point unset +.index load average +If the system load average ever gets higher than this, incoming SMTP calls are +accepted only from those hosts that match an entry in \smtp@_reserve@_hosts\. +If \smtp@_reserve@_hosts\ is not set, no incoming SMTP calls are accepted when +the load is over the limit. The option has no effect on ancient operating +systems on which Exim cannot determine the load average. See also +\deliver@_queue@_load@_max\ and \queue@_only@_load\. + + +.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 +particular, a syntactically invalid email address, as in this command: +.display asis +RCPT TO:<abc xyz@a.b.c> +.endd +causes immediate rejection of the command, before any other tests are done. +(The ACL cannot be run if there is no valid address to set up for it.) An +example of a protocol error is receiving \\RCPT\\ before \\MAIL\\. If there are +too many syntax or protocol errors in one SMTP session, the connection is +dropped. The limit is set by this option. + +.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 +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 +into making connections to SMTP ports; in these circumstances, a number of +non-SMTP command lines are sent first. + + +.conf smtp@_ratelimit@_hosts "host list$**$" unset +.index SMTP||rate limiting +.index limit||rate of message arrival +.index \\RCPT\\||rate limiting +Some sites find it helpful to be able to limit the rate at which certain hosts +can send them messages, and the rate at which an individual message can specify +recipients. When a host matches \smtp@_ratelimit@_hosts\, the values of +\smtp@_ratelimit@_mail\ and \smtp@_ratelimit@_rcpt\ are used to control the +rate of acceptance of \\MAIL\\ and \\RCPT\\ commands in a single SMTP session, +respectively. Each option, if set, must contain a set of four comma-separated +values: +.numberpars $. +A threshold, before which there is no rate limiting. +.nextp +An initial time delay. Unlike other times in Exim, numbers with decimal +fractional parts are allowed here. +.nextp +A factor by which to increase the delay each time. +.nextp +A maximum value for the delay. This should normally be less than 5 minutes, +because after that time, the client is liable to timeout the SMTP command. +.endp +For example, these settings have been used successfully at the site which +first suggested this feature, for controlling mail from their customers: +.display asis +smtp_ratelimit_mail = 2,0.5s,1.05,4m +smtp_ratelimit_rcpt = 4,0.25s,1.015,4m +.endd +The first setting specifies delays that are applied to \\MAIL\\ commands after +two have been received over a single connection. The initial delay is 0.5 +seconds, increasing by a factor of 1.05 each time. The second setting applies +delays to \\RCPT\\ commands when more than four occur in a single message. + +It is also possible to configure delays explicitly in ACLs. See section +~~SECTACLmodi for details. + + +.conf smtp@_ratelimit@_mail string unset +See \smtp@_ratelimit@_hosts\ above. + +.conf smtp@_ratelimit@_rcpt string unset +See \smtp@_ratelimit@_hosts\ above. + +.conf smtp@_receive@_timeout time 5m +.index timeout||for SMTP input +.index SMTP||timeout, input +This sets a timeout value for SMTP reception. It applies to all forms of SMTP +input, including batch SMTP. If a line of input (either an SMTP command or a +data line) is not received within this time, the SMTP connection is dropped and +the message is abandoned. +A line is written to the log containing one of the following messages: +.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 +means that it was in the \\DATA\\ phase, reading the contents of a message. + + +.index \-os-\ option +The value set by this option can be overridden by the +\-os-\ command-line option. A setting of zero time disables the timeout, but +this should never be used for SMTP over TCP/IP. (It can be useful in some cases +of local input using \-bs-\ or \-bS-\.) For non-SMTP input, the reception +timeout is controlled by \receive@_timeout\ and \-or-\. + +.conf smtp@_reserve@_hosts "host list$**$" unset +This option defines hosts for which SMTP connections are reserved; see +\smtp@_accept@_reserve\ and \smtp@_load@_reserve\ above. + +.conf smtp@_return@_error@_details boolean false +.index SMTP||details policy failures +.index policy control||rejection, returning details +In the default state, Exim uses bland messages such as +`Administrative prohibition' when it rejects SMTP commands for policy +reasons. Many sysadmins like this because it gives away little information +to spammers. However, some other syadmins who are applying strict checking +policies want to give out much fuller information about failures. Setting +\smtp@_return@_error@_details\ true causes Exim to be more forthcoming. For +example, instead of `Administrative prohibition', it might give: +.display asis +550-Rejected after DATA: '>' missing at end of address: +550 failing address in "From" header is: <user@dom.ain +.endd + +.conf split@_spool@_directory boolean false +.index multiple spool directories +.index spool directory||split +.index directories, multiple +If this option is set, it causes Exim to split its input directory into 62 +subdirectories, each with a single alphanumeric character as its name. The +sixth character of the message id is used to allocate messages to +subdirectories; this is the least significant base-62 digit of the time of +arrival of the message. + +Splitting up the spool in this way may provide better performance on systems +where there are long mail queues, by reducing the number of files in any one +directory. The msglog directory is also split up in a similar way to the input +directory; however, if \preserve@_message@_logs\ is set, all old msglog files +are still placed in the single directory \(msglog.OLD)\. + +It is not necessary to take any special action for existing messages when +changing \split@_spool@_directory\. Exim notices messages that are in the +`wrong' place, and continues to process them. If the option is turned off after +a period of being on, the subdirectories will eventually empty and be +automatically deleted. + +When \split@_spool@_directory\ is set, the behaviour of queue runner processes +changes. Instead of creating a list of all messages in the queue, and then +trying to deliver each one in turn, it constructs a list of those in one +sub-directory and tries to deliver them, before moving on to the next +sub-directory. The sub-directories are processed in a random order. This +spreads out the scanning of the input directories, and uses less memory. It is +particularly beneficial when there are lots of messages on the queue. However, +if \queue@_run@_in@_order\ is set, none of this new processing happens. The +entire queue has to be scanned and sorted before any deliveries can start. + +.conf spool@_directory string$**$ "set at compile time" +.index spool directory||path to +This defines the directory in which Exim keeps its spool, that is, the messages +it is waiting to deliver. The default value is taken from the compile-time +configuration setting, if there is one. If not, this option must be set. The +string is expanded, so it can contain, for example, a reference to +\$primary@_hostname$\. + +If the spool directory name is fixed on your installation, it is recommended +that you set it at build time rather than from this option, particularly if the +log files are being written to the spool directory (see \log@_file@_path\). +Otherwise log files cannot be used for errors that are detected early on, such +as failures in the configuration file. + +By using this option to override the compiled-in path, it is possible to run +tests of Exim without using the standard spool. + +.conf strip@_excess@_angle@_brackets boolean false +.index angle brackets, excess +If this option is set, redundant pairs of angle brackets round `route-addr' +items in addresses are stripped. For example, \*@<@<xxx@@a.b.c.d@>@>*\ is treated +as \*@<xxx@@a.b.c.d@>*\. If this is in the envelope and the message is passed on +to another MTA, the excess angle brackets are not passed on. If this option is +not set, multiple pairs of angle brackets cause a syntax error. + +.conf strip@_trailing@_dot boolean false +.index trailing dot on domain +.index dot||trailing on domain +If this option is set, a trailing dot at the end of a domain in an address is +ignored. If this is in the envelope and the message is passed on to another +MTA, the dot is not passed on. If this option is not set, a dot at the end of a +domain causes a syntax error. +.em +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 +When Exim is logging to syslog, it writes the log lines for its three +separate logs at different syslog priorities so that they can in principle +be separated on the logging hosts. Some installations do not require this +separation, and in those cases, the duplication of certain log lines is a +nuisance. If \syslog@_duplication\ is set false, only one copy of any +particular log line is written to syslog. For lines that normally go to +both the main log and the reject log, the reject log version (possibly +containing message header lines) is written, at \\LOG@_NOTICE\\ priority. +Lines that normally go to both the main and the panic log are written at +the \\LOG@_ALERT\\ priority. + +.conf syslog@_facility string unset +.index syslog||facility, setting +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 +option is unset, `mail' is used. See chapter ~~CHAPlog for details of Exim's +logging. + + +.conf syslog@_processname string "$tt{exim}" +.index syslog||process name, setting +This option sets the syslog `ident' name, used when Exim is logging to syslog. +The value must be no longer than 32 characters. See chapter ~~CHAPlog for +details of Exim's logging. + + +.conf syslog@_timestamp boolean true +.index syslog||timestamps +If \syslog@_timestamp\ is set false, the timestamps on Exim's log lines are +omitted when these lines are sent to syslog. See chapter ~~CHAPlog for +details of Exim's logging. + +.conf system@_filter string$**$ unset +.index filter||system filter +.index system filter||specifying +.index Sieve filter||not available for system filter +This option specifies an Exim filter file that is applied to all messages at +the start of each delivery attempt, before any routing is done. System filters +must be Exim filters; they cannot be Sieve filters. If the system filter +generates any deliveries to files or pipes, or any new mail messages, the +appropriate \system@_filter@_...@_transport\ option(s) must be set, to define +which transports are to be used. Details of this facility are given in chapter +~~CHAPsystemfilter. + +.conf system@_filter@_directory@_transport string$**$ unset +This sets the name of the transport driver that is to be used when the +\save\ command in a system message filter specifies a path ending in `/', +implying delivery of each message into a separate file in some directory. +During the delivery, the variable \$address@_file$\ contains the path name. + +.conf system@_filter@_file@_transport string$**$ unset +.index file||transport for system filter +This sets the name of the transport driver that is to be used when the \save\ +command in a system message filter specifies a path not ending in `/'. During +the delivery, the variable \$address@_file$\ contains the path name. + +.index gid (group id)||system filter +.conf system@_filter@_group string unset +This option is used only when \system@_filter@_user\ is also set. It sets the +gid under which the system filter is run, overriding any gid that is associated +with the user. The value may be numerical or symbolic. + +.conf system@_filter@_pipe@_transport string$**$ unset 7 +.index \%pipe%\ transport||for system filter +This specifies the transport driver that is to be used when a \pipe\ command is +used in a system filter. During the delivery, the variable \$address@_pipe$\ +contains the pipe command. + +.conf system@_filter@_reply@_transport string$**$ unset +.index \%autoreply%\ transport||for system filter +This specifies the transport driver that is to be used when a \mail\ command is +used in a system filter. + +.index uid (user id)||system filter +.conf system@_filter@_user string unset +If this option is not set, the system filter is run in the main Exim delivery +process, as root. When the option is set, the system filter runs in a separate +process, as the given user. Unless the string consists entirely of digits, it +is looked up in the password data. Failure to find the named user causes a +configuration error. The gid is either taken from the password data, or +specified by \system@_filter@_group\. When the uid is specified numerically, +\system@_filter@_group\ is required to be set. + +If the system filter generates any pipe, file, or reply deliveries, the uid +under which the filter is run is used when transporting them, unless a +transport option overrides. +Normally you should set \system@_filter@_user\ if your system filter generates +these kinds of delivery. + +.conf tcp@_nodelay boolean true +.index daemon||\\TCP@_NODELAY\\ on sockets +.index Nagle algorithm +.index \\TCP@_NODELAY\\ on listening sockets +If this option is set false, it stops the Exim daemon setting the +\\TCP@_NODELAY\\ option on its listening sockets. Setting \\TCP@_NODELAY\\ +turns off the `Nagle algorithm', which is a way of improving network +performance in interactive (character-by-character) situations. Turning it off +should improve Exim's performance a bit, so that is what happens by default. +However, it appears that some broken clients cannot cope, and time out. Hence +this option. It affects only those sockets that are set up for listening by the +daemon. Sockets created by the smtp transport for delivering mail always set +\\TCP@_NODELAY\\. + +.conf timeout@_frozen@_after time 0s +.index frozen messages||timing out +.index timeout||frozen messages +If \timeout@_frozen@_after\ is set to a time greater than zero, a frozen +message of any kind that has been on the queue for longer than the given +time is automatically cancelled at the next queue run. If it is a bounce +message, it is just discarded; otherwise, a bounce is sent to the sender, in a +similar manner to cancellation by the \-Mg-\ command line option. If you want +to timeout frozen bounce messages earlier than other kinds of frozen message, +see \ignore@_bounce@_errors@_after\. + +.conf timezone string unset +.index timezone, setting +The value of \timezone\ is used to set the environment variable \\TZ\\ while +running Exim (if it is different on entry). This ensures that all timestamps +created by Exim are in the required timezone. If you want all your timestamps +to be in UTC (aka GMT) you should set +.display asis +timezone = UTC +.endd +The default value is taken from \\TIMEZONE@_DEFAULT\\ in \(Local/Makefile)\, +or, if that is not set, from the value of the TZ environment variable when Exim +is built. If \timezone\ is set to the empty string, either at build or run +time, any existing \\TZ\\ variable is removed from the environment when Exim +runs. This is appropriate behaviour for obtaining wall-clock time on some, but +unfortunately not all, operating systems. + +.conf tls@_advertise@_hosts "host list$**$" unset +.index TLS||advertising +.index encryption||on SMTP connection +.index SMTP||encrypted connection +When Exim is built with support for TLS encrypted connections, the availability +of the \\STARTTLS\\ command to set up an encrypted session is advertised in +response to \\EHLO\\ only to those client hosts that match this option. See +chapter ~~CHAPTLS for details of Exim's support for TLS. + +.conf tls@_certificate string$**$ unset +.index TLS||server certificate, location of +.index certificate||for server, location of +The value of this option is expanded, and must then be the absolute path to a +file which contains the server's certificates. The server's private key is also +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 +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 +ignored. See section ~~SECTopenvsgnu for further details. + +.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. + +.conf tls@_remember@_esmtp boolean false +.index TLS||esmtp state, remembering +.index TLS||broken clients +If this option is set true, Exim violates the RFCs by remembering that it is in +`esmtp' state after successfully negotiating a TLS session. This provides +support for broken clients that fail to send a new \\EHLO\\ after starting a +TLS session. + +.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 +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. +.nem + +.conf tls@_try@_verify@_hosts "host list$**$" unset +.index TLS||client certificate verification +.index certificate||verification of client +See \tls@_verify@_hosts\ below. + +.conf tls@_verify@_certificates string$**$ unset +.index TLS||client certificate verification +.index certificate||verification of client +The value of this option is expanded, and must then be the absolute path to +a file containing permitted certificates for clients that +match \tls@_verify@_hosts\ or \tls@_try@_verify@_hosts\. Alternatively, if you +are using OpenSSL, you can set \tls@_verify@_certificates\ to the name of a +directory containing certificate files. This does not work with GnuTLS; the +option must be set to the name of a single file if you are using GnuTLS. + +.conf tls@_verify@_hosts "host list$**$" unset +.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 +\tls@_try@_verify@_hosts\ is set and \tls@_verify@_certificates\ is not set. + +Any client that matches \tls@_verify@_hosts\ is constrained by +\tls@_verify@_certificates\. The client must present one of the listed +certificates. If it does not, the connection is aborted. + +A weaker form of checking is provided by \tls@_try@_verify@_hosts\. If a client +matches this option (but not \tls@_verify@_hosts\), Exim requests a +certificate and checks it against \tls@_verify@_certificates\, but does not +abort the connection if there is no certificate or if it does not match. This +state can be detected in an ACL, which makes it possible to implement policies +such as `accept for relay only if a verified certificate has been received, but +accept for local delivery if encrypted, even without a verified certificate'. + +Client hosts that match neither of these lists are not asked to present +certificates. + +.conf trusted@_groups "string list" unset +.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. +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 +root and the Exim user are trusted. + +.conf trusted@_users "string list" unset +.index trusted user +.index user||trusted +If this option is set, any process that is running as one of the listed users +is trusted. +The users can be specified numerically or by name. +See section ~~SECTtrustedadmin for details of what trusted callers are +permitted to do. If neither \trusted@_groups\ nor \trusted@_users\ is set, only +root and the Exim user are trusted. + +.index uid (user id)||unknown caller +.conf unknown@_login string$**$ unset +This is a specialized feature for use in unusual configurations. By default, if +the uid of the caller of Exim cannot be looked up using \*getpwuid()*\, Exim +gives up. The \unknown@_login\ option can be used to set a login name to be +used in this circumstance. It is expanded, so values like \user@$caller@_uid\ +can be set. When \unknown@_login\ is used, the value of \unknown@_username\ is +used for the user's real name (gecos field), unless this has been set by the +\-F-\ option. + +.conf unknown@_username string unset +See \unknown@_login\. + +.conf untrusted@_set@_sender "address list$**$" unset +.index trusted user +.index sender||setting by untrusted user +.index untrusted user, setting sender +.index user||untrusted setting sender +.index envelope sender +When an untrusted user submits a message to Exim using the standard input, Exim +normally creates an envelope sender address from the user's login and the +default qualification domain. Data from the \-f-\ option (for setting envelope +senders on non-SMTP messages) or the SMTP \\MAIL\\ command (if \-bs-\ or \-bS-\ +is used) is ignored. + +However, untrusted users are permitted to set an empty envelope sender address, +to declare that a message should never generate any bounces. For example: +.display asis +exim -f '<>' user@domain.example +.endd +The \untrusted@_set@_sender\ option allows you to permit untrusted users to set +other envelope sender addresses in a controlled way. When it is set, untrusted +users are allowed to set envelope sender addresses that match any of the +patterns in the list. Like all address lists, the string is expanded. The +identity of the user is in \$sender@_ident$\, so you can, for example, restrict +users to setting senders that start with their login ids +followed by a hyphen +by a setting like this: +.display asis +untrusted_set_sender = ^$sender_ident- +.endd +If you want to allow untrusted users to set envelope sender addresses without +restriction, you can use +.display asis +untrusted_set_sender = * +.endd +The \untrusted@_set@_sender\ option applies to all forms of local input, but +only to the setting of the envelope sender. It does not permit untrusted users +to use the other options which trusted user can use to override message +parameters. Furthermore, it does not stop Exim from removing an existing +::Sender:: header in the message, or from adding a ::Sender:: header if +necessary. See \local__sender__retain\ and \local@_from@_check\ for ways of +overriding these actions. The handling of the ::Sender:: header is also +described in section ~~SECTthesenhea. + +The log line for a message's arrival shows the envelope sender following `<='. +For local messages, the user's login always follows, after `U='. In \-bp-\ +displays, and in the Exim monitor, if an untrusted user sets an envelope sender +address, the user's login is shown in parentheses after the sender address. + +.conf uucp@_from@_pattern string "see below" +.index `From' line +.index UUCP||`From' line +Some applications that pass messages to an MTA via a command line interface use +an initial line starting with `From' to pass the envelope sender. In +particular, this is used by UUCP software. Exim recognizes such a line by means +of a regular expression that is set in \uucp@_from@_pattern\. When the pattern +matches, the sender address is constructed by expanding the contents of +\uucp@_from@_sender\, provided that the caller of Exim is a trusted user. The +default pattern recognizes lines in the following two forms: +.display asis + From ph10 Fri Jan 5 12:35 GMT 1996 + From ph10 Fri, 7 Jan 97 14:00:00 GMT +.endd +The pattern can be seen by running +.display asis +exim -bP uucp_from_pattern +.endd +It checks only up to the hours and minutes, and allows for a 2-digit or 4-digit +year in the second case. The first word after `From' is matched in the regular +expression by a parenthesized subpattern. The default value for +\uucp@_from@_sender\ is `$1', which therefore just uses this first word (`ph10' +in the example above) as the message's sender. See also +\ignore@_fromline@_hosts\. + +.conf uucp@_from@_sender string$**$ "$tt{@$1}" +See \uucp@_from@_pattern\ above. + +.conf warn@_message@_file string unset +.index warning of delay||customizing the message +.index customizing||warning message +This option defines a template file containing paragraphs of text to be used +for constructing the warning message which is sent by Exim when a message has +been on the queue for a specified amount of time, as specified by +\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 + + + +. +. +. +. +. ============================================================================ +.chapter Generic options for routers +.rset CHAProutergeneric "~~chapter" +.set runningfoot "generic router options" +.index options||generic, for routers +.index generic options||router + +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\. + +.startconf + +.conf address@_data string$**$ unset +.index router||data attached to address +The string is expanded just before the router is run, that is, after all the +precondition tests have succeeded. If the expansion is forced to fail, the +router declines. Other expansion failures cause delivery of the address to be +deferred. + +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. + +\**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 +point. + +Even if the router declines or passes, the value of \$address@_data$\ remains +with the address, though it can be changed by another \address@_data\ setting +on a subsequent router. If a router generates child addresses, the value of +\$address@_data$\ propagates to them. This also applies to the special kind of +`child' that is generated by a router with the \unseen\ option. + +The idea of \address@_data\ is that you can use it to look up a lot of data for +the address once, and then pick out parts of the data later. For example, you +could use a single LDAP lookup to return a string of the form +.display asis +uid=1234 gid=5678 mailbox=/mail/xyz forward=/home/xyz/.forward +.endd +In the transport you could pick out the mailbox by a setting such as +.display asis +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.) + +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. + + +.conf address@_test "boolean (precondition)" true +.index \-bt-\ option +.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 +routing. + + +.conf cannot@_route@_message string$**$ unset +.index router||customizing `cannot route' message +.index customizing||`cannot route' message +This option specifies a text message that is used when an address cannot be +routed because Exim has run out of routers. The default message is `Unrouteable +address'. This option is useful only on routers that have \more\ set false, or +on the very last router in a configuration, because the value that is used is +taken from the last router that inspects an address. For example, using the +default configuration, you could put: +.display asis +cannot_route_message = Remote domain not found in DNS +.endd +on the first (\%dnslookup%\) router, and +.display asis +cannot_route_message = Unknown local user +.endd +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 +the routing failure. + +.conf caseful@_local@_part boolean false +.index case of local parts +.index router||case of local parts +By default, routers handle the local parts of addresses in a case-insensitive +manner, though the actual case is preserved for transmission with the message. +If you want the case of letters to be significant in a router, you must set +this option true. For individual router options that contain address or local +part lists (for example, \local@_parts\), case-sensitive matching can be turned +on by `+caseful' as a list item. See section ~~SECTcasletadd for more details. + + +.conf check@_local@_user "boolean (precondition)" false +.index local user, checking in router +.index router||checking for local user +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. + +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\ +setting to achieve this. For example: +.display asis +local_parts = passwd;$local_part : lsearch;/etc/other/users +.endd +Note, however, that the side effects of \check@_local@_user\ (such as setting +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. + +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). + + +.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 +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\ +option appears not to be working, \debug@_print\ can be used to output the +variables it references. The output happens after checks for \domains\, +\local@_parts\, and \check@_local@_user\ but before any other preconditions are +tested. A newline is added to the text if it does not end with one. + + +.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 +If this option is set, the router is skipped unless the current domain matches +the list. If the match is achieved by means of a file lookup, the data that the +lookup returned for the domain is placed in \$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 +are evaluated. + + +.conf driver string unset +This option must always be set. It specifies which of the available routers is +to be used. + + +.conf errors@_to string$**$ unset +.index envelope sender +.index router||changing address for errors +If a router successfully handles an address, it may queue the address for +delivery or it may generate child addresses. In both cases, if there is a +delivery problem during later processing, the resulting bounce message is sent +to the address that results from expanding this string, provided that the +address verifies successfully. +\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 +the expansion fails to verify, the errors address associated with the incoming +address is used. At top level, this is the envelope sender. A non-forced +expansion failure causes delivery to be deferred. + +If an address for which \errors@_to\ has been set ends up being delivered over +SMTP, the envelope sender for that delivery is the \errors@_to\ value, so that +any bounces that are generated by other MTAs on the delivery route are also +sent there. The most common use of \errors@_to\ is probably to direct mailing +list bounces to the manager of the list, as described in section +~~SECTmailinglists. + +The \errors@_to\ setting associated with an address can be overridden if it +subsequently passes through other routers that have their own \errors@_to\ +settings, +or if it is delivered by a transport with a \return@_path\ setting. + +You can set \errors@_to\ to the empty string by either of these settings: +.display asis +errors_to = +errors_to = "" +.endd +An expansion item that yields an empty string has the same effect. If you do +this, a locally detected delivery error for addresses processed by this router +no longer gives rise to a bounce message; the error is discarded. If the +address is delivered to a remote host, the return path is set to \"<>"\, unless +overridden by the \return@_path\ option on the transport. + +If for some reason you want to discard local errors, but use a non-empty +\\MAIL\\ command for remote delivery, you can preserve the original return +path in \$address@_data$\ in the router, and reinstate it in the transport by +setting \return@_path\. + + +.conf expn "boolean (precondition)" true +.index address||testing +.index testing||addresses +.index \\EXPN\\||router skipping +.index router||skipping for \\EXPN\\ +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 +are evaluated. + +The use of the SMTP \\EXPN\\ command is controlled by an ACL (see chapter +~~CHAPACL). When Exim is running an \\EXPN\\ command, it is similar to testing +an address with \-bt-\. Compare \\VRFY\\, whose counterpart is \-bv-\. + + +.conf fail@_verify boolean false +.index router||forcing verification failure +Setting this option has the effect of setting both \fail@_verify@_sender\ and +\fail@_verify@_recipient\ to the same value. + + +.conf fail@_verify@_recipient boolean false +If this option is true and an address is accepted by this router when +verifying a recipient, verification fails. + + +.conf fail@_verify@_sender boolean false +If this option is true and an address is accepted by this router when +verifying a sender, verification fails. + + +.conf fallback@_hosts "string list" unset +.index router||fallback hosts +.index fallback||hosts specified on router +String expansion is not applied to this option. The argument must be a +colon-separated list of host names or IP addresses. If a router queues an +address for a remote transport, this host list is associated with the address, +and used instead of the transport's fallback host list. If \hosts@_randomize\ +is set on the transport, the order of the list is randomized for each use. See +the \fallback@_hosts\ option of the \%smtp%\ transport for further details. + +.conf group string$**$ "see below" +.index gid (group id)||local delivery +.index local transports||uid and gid +.index transport||local +.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 +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 +the discussion in chapter ~~CHAPenvironment. + + +.conf headers@_add string$**$ unset +.index header lines||adding +.index router||adding header lines +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. + +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'. + +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. + + +.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. +.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 +.index router||discarding IP addresses +Although this option is a host list, it should normally contain IP address +entries rather than names. If any host that is looked up by the router has an +IP address that matches an item in this list, Exim behaves as if that IP +address did not exist. This option allows you to cope with rogue DNS entries +like +.display asis +remote.domain.example. A 127.0.0.1 +.endd +by setting +.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. + +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. + + + +.index additional groups +.index groups, additional +.index local transports||uid and gid +.index transport||local +.conf initgroups boolean false +If the router queues an address for a transport, and this option is true, and +the uid supplied by the router is not overridden by the transport, the +\*initgroups()*\ function is called when running the transport to ensure that +any additional groups associated with the uid are set up. See also \group\ and +\user\ and the discussion in chapter ~~CHAPenvironment. + + +.conf local@_part@_prefix "string list (precondition)" unset +.index router||prefix for local part +.index prefix||for local part, used in router +If this option is set, the router is skipped unless the local part +starts with one of the given strings, or \local@_part@_prefix@_optional\ is +true. +See section ~~SECTrouprecon for a list of the order in which preconditions +are evaluated. + +The list is scanned from left to right, and the first prefix that matches is +used. A limited form of wildcard is available; if the prefix begins with an +asterisk, it matches the longest possible sequence of arbitrary characters at +the start of the local part. An asterisk should therefore always be followed by +some character that does not occur in normal local parts. +.index multiple mailboxes +.index mailbox||multiple +Wildcarding can be used to set up multiple user mailboxes, as described in +section ~~SECTmulbox. + +During the testing of the \local@_parts\ option, and while the router is +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 +relevant transport. + +The prefix facility is commonly used to handle local parts of the form +\owner-something\. Another common use is to support local parts of the form +\real-username\ to bypass a user's \(.forward)\ file -- helpful when trying to +tell a user their forwarding is broken -- by placing a router like this one +immediately before the router that handles \(.forward)\ files: +.display asis +real_localuser: + driver = accept + local_part_prefix = real- + check_local_user + transport = local_delivery +.endd +If both \local@_part@_prefix\ and \local@_part@_suffix\ are set for a router, +both conditions must be met if not optional. Care must be taken if wildcards +are used in both a prefix and a suffix on the same router. Different +separator characters must be used to avoid ambiguity. + +.conf local@_part@_prefix@_optional boolean false +See \local@_part@_prefix\ above. + + +.conf local@_part@_suffix "string list (precondition)" unset +.index router||suffix for local part +.index suffix for local part, used in router +This option operates in the same way as \local@_part@_prefix\, except that the +local part must end (rather than start) with the given string, the +\local@_part@_suffix@_optional\ option determines whether the suffix is +mandatory, and the wildcard $*$ character, if present, must be the last +character of the suffix. This option facility is commonly used to handle local +parts of the form \something-request\ and multiple user mailboxes of the form +\username-foo\. + +.conf local@_part@_suffix@_optional boolean false +See \local@_part@_suffix\ above. + + +.conf local@_parts "local part list$**$ (precondition)" unset +.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 +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 +example: +.display asis +local_parts = dbm;/usr/local/specials/$domain +.endd +If the match is achieved by a lookup, the data that the lookup returned +for the local part is placed in the variable \$local@_part@_data$\ for use in +expansions of the router's private options. You might use this option, for +example, if you have a large number of local virtual domains, and you want to +send all postmaster mail to the same place without having to set up an alias in +each virtual domain: +.display asis +postmaster: + driver = redirect + local_parts = postmaster + data = postmaster@real.domain.example +.endd + + +.conf log@_as@_local boolean "see below" +.index log||delivery line +.index delivery||log line format +Exim has two logging styles for delivery, the idea being to make local +deliveries stand out more visibly from remote ones. In the `local' style, the +recipient address is given just as the local part, without a domain. The use of +this style is controlled by this option. It defaults to true for the \%accept%\ +router, and false for all the others. + + +.conf more boolean$**$ true +The result of string expansion for this option must be a valid boolean value, +that is, one of the strings `yes', `no', `true', or `false'. Any other result +causes an error, and delivery is deferred. If the expansion is forced to fail, +the default value for the option (true) is used. Other failures cause delivery +to be deferred. + +If this option is set false, and the router is run, but declines to handle the +address, no further routers are tried, routing fails, and the address is +bounced. +.index \self\ option +However, if the router explicitly passes an address to the following router by +means of the setting +.display asis +self = pass +.endd +or otherwise, the setting of \more\ is ignored. Also, the setting of \more\ +does not affect the behaviour if one of the precondition tests fails. In that +case, the address is always passed to the next router. + + +.conf pass@_on@_timeout boolean false +.index timeout||of router +.index router||timeout +If a router times out during a host lookup, it normally causes deferral of the +address. If \pass@_on@_timeout\ is set, the address is passed on to the next +router, overriding \no@_more\. This may be helpful for systems that are +intermittently connected to the Internet, or those that want to pass to a smart +host any messages that cannot immediately be delivered. + +There are occasional other temporary errors that can occur while doing DNS +lookups. They are treated in the same way as a timeout, and this option +applies to all of them. + + +.conf pass@_router string unset +.index router||go to after `pass' +When a router returns `pass', the address is normally handed on to the next +router in sequence. This can be changed by setting \pass@_router\ to the name +of another router. However (unlike \redirect@_router\) the named router must be +below the current router, to avoid loops. Note that this option applies only to +the special case of `pass'. It does not apply when a router returns `decline'. + + +.conf redirect@_router string unset +.index router||start at after redirection +Sometimes an administrator knows that it is pointless to reprocess addresses +generated from alias or forward files with the same router again. For +example, if an alias file translates real names into login ids there is no +point searching the alias file a second time, especially if it is a large file. + +The \redirect@_router\ option can be set to the name of any router instance. It +causes the routing of any generated addresses to start at the named router +instead of at the first router. This option has no effect if the router in +which it is set does not generate new addresses. + + +.conf require@_files "string list$**$ (precondition)" unset +.index file||requiring for router +.index router||requiring file existence +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. + +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 +failures cause routing of the address to be deferred. + +If any expanded string is empty, it is ignored. Otherwise, except as described +below, each string must be a fully qualified file path, optionally preceded by +`!'. The paths are passed to the \*stat()*\ function to test for the existence +of the files or directories. The router is skipped if any paths not preceded by +`!' do not exist, or if any paths preceded by `!' do exist. + +.index NFS +If \*stat()*\ cannot determine whether a file exists or not, delivery of +the message is deferred. This can happen when NFS-mounted filesystems are +unavailable. + +This option is checked after the \domains\, \local@_parts\, and \senders\ +options, so you cannot use it to check for the existence of a file in which to +look up a domain, local part, or sender. (See section ~~SECTrouprecon for a +full list of the order in which preconditions are evaluated.) However, as +these options are all expanded, you can use the \exists\ expansion condition to +make such tests. The \require@_files\ option is intended for checking files +that the router may be going to use internally, or which are needed by a +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. +This is not a proper permissions check, but just a `rough' check that +operates as follows: + +If an item in a \require@_files\ list does not contain any forward slash +characters, it is taken to be the user (and optional group, separated by a +comma) to be checked for subsequent files in the list. If no group is specified +but the user is specified symbolically, the gid associated with the uid is +used. For example: +.display asis +require_files = mail:/some/file +require_files = $local_part:$home/.procmailrc +.endd +If a user or group name in a \require@_files\ list does not exist, the +\require@_files\ condition fails. + +Exim performs the check by scanning along the components of the file path, and +checking the access for the given uid and gid. It checks for `x' access on +directories, and `r' access on the final file. Note that this means that file +access control lists, if the operating system has them, are ignored. + +\**Warning 1**\: When the router is being run to verify addresses for an +incoming SMTP message, Exim is not running as root, but under its own uid. This +may affect the result of a \require@_files\ check. In particular, \*stat()*\ +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 +without root access. + +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: +.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\ +option false so that the router is skipped when verifying. + + +.conf retry@_use@_local@_part boolean "see below" +.index hints database||retry keys +.index local part||in retry keys +When a delivery suffers a temporary routing failure, a retry record is created +in Exim's hints database. For addresses whose routing depends only on the +domain, the key for the retry record should not involve the local part, but for +other addresses, both the domain and the local part should be included. +Usually, remote routing is of the former kind, and local routing is of the +latter kind. + +This option controls whether the local part is used to form the key for retry +hints for addresses that suffer temporary errors while being handled by this +router. The default value is true for any router that has \check@_local@_user\ +set, and false otherwise. Note that this option does not apply to hints keys +for transport delays; they are controlled by a generic transport option of the +same name. + +.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 +independently; this setting does not become attached to them. +.nem + + +.conf router@_home@_directory string$**$ unset +.index router||home directory for +.index home directory||for router +This option sets a home directory for use while the router is running. (Compare +\transport__home@_directory\, which sets a home directory for later +transporting.) In particular, if used on a \%redirect%\ router, this option +sets a value for \$home$\ while a filter is running. The value is expanded; +forced expansion failure causes the option to be ignored -- other failures +cause the router to defer. + +Expansion of \router@_home@_directory\ happens immediately after the +\check@_local@_user\ test (if configured), before any further expansions take +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 +\$home$\ that came from \check@_local@_user\. + +When a router accepts an address and routes it to a transport (including the +cases when a redirect router generates a pipe, file, or autoreply delivery), +the home directory setting for the transport is taken from the first of these +values that is set: +.numberpars $. +The \home@_directory\ option on the transport; +.nextp +The \transport@_home@_directory\ option on the router; +.nextp +The password data if \check@_local@_user\ is set on the router; +.nextp +The \router@_home@_directory\ option on the router. +.endp +In other words, \router@_home@_directory\ overrides the password data for the +router, but not for the transport. + + +.conf self string "freeze" +.index MX record||pointing to local host +.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. +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 +\%smtp%\ transport. The \self\ option specifies what happens when the first +host on the list turns out to be the local host. +The way in which Exim checks for the local host is described in section +~~SECTreclocipadd. + +Normally this situation indicates either an error in Exim's configuration (for +example, the router should be configured not to process this domain), or an +error in the DNS (for example, the MX should not point to this host). For this +reason, the default action is to log the incident, defer the address, and +freeze the message. The following alternatives are provided for use in special +cases: +.numberpars $. +\defer\ +.newline +Delivery of the message is tried again later, but the message is not frozen. +.nextp +\reroute: <<domain>>\ +.newline +The domain is changed to the given domain, and the address is passed back to +be reprocessed by the routers. No rewriting of headers takes place. This +behaviour is essentially a redirection. +.nextp +\reroute: rewrite: <<domain>>\ +.newline +The domain is changed to the given domain, and the address is passed back to be +reprocessed by the routers. Any headers that contain the original domain are +rewritten. +.nextp +\pass\ +.newline +The router passes the address to the next router, or to the router named in the +\pass@_router\ option if it is set. +.index \more\ option +This overrides \no@_more\. + +During subsequent routing and delivery, the variable +\$self@_hostname$\ contains the name of the local host that the router +encountered. This can be used to distinguish between different cases for hosts +with multiple names. The combination +.display asis +self = pass +no_more +.endd +ensures that only those addresses that routed to the local host are passed on. +Without \no@_more\, addresses that were declined for other reasons would also +be passed to the next router. +.nextp +\fail\ +.newline +Delivery fails and an error report is generated. +.nextp +\send\ +.newline +.index local host||sending to +The anomaly is ignored and the address is queued for the transport. This +setting should be used with extreme caution. For an \%smtp%\ transport, it makes +sense only in cases where the program that is listening on the SMTP port is not +this version of Exim. That is, it must be some other MTA, or Exim with a +different configuration file that handles the domain in another way. +.endp + +.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 +are evaluated. + +There are issues concerning verification when the running of routers is +dependent on the sender. When Exim is verifying the address in an \errors@_to\ +setting, it sets the sender to the null string. When using the \-bt-\ option to +check a configuration file, it is necessary also to use the \-f-\ option to set +an appropriate sender. For incoming mail, the sender is unset when verifying +the sender, but is available when verifying any recipients. If the SMTP +\\VRFY\\ command is enabled, it must be used after \\MAIL\\ if the sender +address matters. + +.conf translate@_ip@_address string$**$ unset +.index IP address||translating +.index packet radio +.index router||IP address translation +There exist some rare networking situations (for example, packet radio) where +it is helpful to be able to translate IP addresses generated by normal routing +mechanisms into other IP addresses, thus performing a kind of manual IP +routing. This should be done only if the normal IP routing of the TCP/IP stack +is inadequate or broken. Because this is an extremely uncommon requirement, the +code to support this option is not included in the Exim binary unless +\\SUPPORT__TRANSLATE__IP__ADDRESS\\=yes is set in \(Local/Makefile)\. + +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. +For any other expansion error, delivery of the message is deferred. +If the result of the expansion is an IP address, that replaces the original +address; otherwise the result is assumed to be a host name -- this is looked up +using \*gethostbyname()*\ (or \*getipnodebyname()*\ when available) to produce +one or more replacement IP addresses. For example, to subvert all IP addresses +in some specific networks, this could be added to a router: +.display +$smc{translate@_ip@_address = @\ + @$@{lookup@{@$@{mask:@$host@_address/26@}@}lsearch@{/some/file@}@{@$value@}fail@}} +.endd +The file would contain lines like +.display asis +10.2.3.128/26 some.host +10.8.4.34/26 10.44.8.15 +.endd +You should not make use of this facility unless you really understand what you +are doing. + + +.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. + +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 +chapter ~~CHAPredirect). + + +.conf transport@_current@_directory string$**$ unset +.index current directory for local transport +This option associates a current directory with any address that is routed +to a local transport. This can happen either because a transport is +explicitly configured for the router, or because it generates a delivery to a +file or a pipe. During the delivery process (that is, at transport time), this +option string is expanded and is set as the current directory, unless +overridden by a setting on the transport. +If the expansion fails for any reason, including forced failure, an error is +logged, and delivery is deferred. +See chapter ~~CHAPenvironment for details of the local delivery environment. + + + +.conf transport@_home@_directory string$**$ "see below" +.index home directory||for local transport +This option associates a home directory with any address that is routed to a +local transport. This can happen either because a transport is explicitly +configured for the router, or because it generates a delivery to a file or a +pipe. During the delivery process (that is, at transport time), the option +string is expanded and is set as the home directory, unless overridden by a +setting of \home@_directory\ on the transport. +If the expansion fails for any reason, including forced failure, an error is +logged, and delivery is deferred. + +If the transport does not specify a home directory, and +\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. + +See chapter ~~CHAPenvironment for further details of the local delivery +environment. + + + +.conf unseen boolean$**$ false +.index router||carrying on after success +The result of string expansion for this option must be a valid boolean value, +that is, one of the strings `yes', `no', `true', or `false'. Any other result +causes an error, and delivery is deferred. If the expansion is forced to fail, +the default value for the option (false) is used. Other failures cause delivery +to be deferred. + +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 +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 +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 +and none specified for removal. + +However, any data that was set by the \address@_data\ option in the current or +previous routers is passed on. Setting this option has a similar effect to the +\unseen\ command qualifier in filter files. + + +.conf user string$**$ "see below" +.index uid (user id)||local delivery +.index local transports||uid and gid +.index transport||local +.index router||user for filter processing +.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 +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, +the default is taken from the password information. If the user is specified as +a name, and \group\ is not set, the group associated with the user is used. See +also \initgroups\ and \group\ and the discussion in chapter ~~CHAPenvironment. + + +.conf verify "boolean (precondition)" true +Setting this option has the effect of setting \verify@_sender\ and +\verify@_recipient\ to the same value. + +.conf verify@_only "boolean (precondition)" false +.index \\EXPN\\||with \verify@_only\ +.index \-bv-\ option +.index router||used only when verifying +If this option is set, the router is used only when verifying an address or +testing with the \-bv-\ option, not when actually doing a delivery, testing +with the \-bt-\ option, or running the SMTP \\EXPN\\ command. It can be further +restricted to verifying only senders or recipients by means of \verify@_sender\ +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 +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 +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 +are evaluated. + +.endconf + + + + + +. +. +. +. +. ============================================================================ +.chapter The accept router +.set runningfoot "accept router" +.index \%accept%\ router +.index routers||\%accept%\ +The \%accept%\ router has no private options of its own. Unless it is being used +purely for verification (see \verify@_only\) a transport is required to be +defined by the generic \transport\ option. If the preconditions that are +specified by generic options are met, the router accepts the address and queues +it for the given transport. The most common use of this router is for setting +up deliveries to local mailboxes. For example: +.display asis +localusers: + driver = accept + domains = mydomain.example + check_local_user + transport = local_delivery +.endd +The \domains\ condition in this example checks the domain of the address, and +\check@_local@_user\ checks that the local part is the login of a local user. +When both preconditions are met, the \%accept%\ router runs, and queues the +address for the \%local@_delivery%\ transport. + + + + + + +. +. +. +. +. ============================================================================ +.chapter The dnslookup router +.rset CHAPdnslookup "~~chapter" +.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. + +.em +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. + +MX records of equal priority are sorted by Exim into a random order. Exim then +looks for address records for the host names obtained from MX or SRV records. +When a host has more than one IP address, they are sorted into a random order, +except that IPv6 addresses are always sorted before IPv4 addresses. If all the +IP addresses found are discarded by a setting of the \ignore@_target@_hosts\ +generic option, the router declines. + +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 +.index \self\ option||in \%dnslookup%\ router +If the host pointed to by the highest priority MX record, or looked up as an +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. + + +.startconf +.index options||\%dnslookup%\ router +.conf check@_secondary@_mx boolean false +.index MX record||checking for secondary +If this option is set, the router declines unless the local host is found in +(and removed from) the list of hosts obtained by MX lookup. This can be used to +process domains for which the local host is a secondary mail exchanger +differently to other domains. The way in which Exim decides whether a host is +the local host is described in section ~~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 +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, +.display asis +check_srv = smtp +.endd +looks for SRV records that refer to the normal smtp service. The option is +expanded, so the service name can vary from message to message or address +to address. This might be helpful if SRV records are being used for a +submission service. If the expansion is forced to fail, the \check@_srv\ +option is ignored, and the router proceeds to look for MX records in the +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. +.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: +.display asis +mx_domains = ! *.discworld.fict.example : *.fict.example +.endd +This specifies that messages addressed to a domain that matches the list but +has no MX record should be bounced immediately instead of being routed using +the address record. + +.conf qualify@_single boolean true +.index DNS||resolver options +.index DNS||qualifying single-component names +When this option is true, the resolver option \\RES@_DEFNAMES\\ is set for DNS +lookups. Typically, but not standardly, this causes the resolver to qualify +single-component names with the default domain. For example, on a machine +called \*dictionary.ref.example*\, the domain \*thesaurus*\ would be changed to +\*thesaurus.ref.example*\ inside the resolver. For details of what your resolver +actually does, consult your man pages for \*resolver*\ and \*resolv.conf*\. + + +.conf rewrite@_headers boolean true +.index rewriting||header lines +.index header lines||rewriting +If the domain name in the address that is being processed is not fully +qualified, it may be expanded to its full form by a DNS lookup. For example, if +an address is specified as \*dormouse@@teaparty*\, the domain might be +expanded to \*teaparty.wonderland.fict.example*\. Domain expansion can also +occur as a result of setting the \widen@_domains\ option. If \rewrite@_headers\ +is true, all occurrences of the abbreviated domain name in any ::Bcc::, ::Cc::, +::From::, ::Reply-to::, ::Sender::, and ::To:: header lines of the message are +rewritten with the full domain name. + +This option should be turned off only when it is known that no message is +ever going to be sent outside an environment where the abbreviation makes +sense. + +When an MX record is looked up in the DNS and matches a wildcard record, name +servers normally return a record containing the name that has been looked up, +making it impossible to detect whether a wildcard was present or not. However, +some name servers have recently been seen to return the wildcard entry. If the +name returned by a DNS lookup begins with an asterisk, it is not used for +header rewriting. + +.conf same@_domain@_copy@_routing boolean false +.index address||copying routing +Addresses with the same domain are normally routed by the \%dnslookup%\ router +to the same list of hosts. However, this cannot be presumed, because the router +options and preconditions may refer to the local part of the address. By +default, therefore, Exim routes each address in a message independently. DNS +servers run caches, so repeated DNS lookups are not normally expensive, and in +any case, personal messages rarely have more than a few recipients. + +If you are running mailing lists with large numbers of subscribers at the same +domain, and you are using a \%dnslookup%\ router which is independent of the +local part, you can set \same__domain__copy@_routing\ to bypass repeated DNS +lookups for identical domains in one message. In this case, when \%dnslookup%\ +routes an address to a remote transport, any other unrouted addresses in the +message that have the same domain are automatically given the same routing +without processing them independently, +provided the following conditions are met: +.numberpars $. +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 domain. +.endp + + +.conf search@_parents boolean false +.index DNS||resolver options +When this option is true, the resolver option \\RES@_DNSRCH\\ is set for DNS +lookups. This is different from the \qualify@_single\ option in that it applies +to domains containing dots. Typically, but not standardly, it causes the +resolver to search for the name in the current domain and in parent domains. +For example, on a machine in the \*fict.example*\ domain, if looking up +\*teaparty.wonderland*\ failed, the resolver would try +\*teaparty.wonderland.fict.example*\. For details of what your resolver +actually does, consult your man pages for \*resolver*\ and \*resolv.conf*\. + +Setting this option true can cause problems in domains that have a wildcard MX +record, because any domain that does not have its own MX record matches the +local wildcard. + +.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 +added onto the end of the domain, and the lookup is tried again. For example, +if +.display asis +widen_domains = fict.example:ref.example +.endd +is set and a lookup of \*klingon.dictionary*\ fails, +\*klingon.dictionary.fict.example*\ is looked up, and if this fails, +\*klingon.dictionary.ref.example*\ is tried. Note that the \qualify@_single\ +and \search@_parents\ options can cause some widening to be undertaken inside +the DNS resolver. + +.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 +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. + +These two options affect only the DNS lookup that takes place inside the router +for the domain of the address that is being routed. They do not affect lookups +such as that implied by +.display asis +domains = @mx_any +.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 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 +generic \transport\ option. The router accepts the address if its domain part +takes the form of an RFC 2822 domain literal, that is, an IP address enclosed +in square brackets. For example, this router handles the address +.display asis +root@[192.168.1.1] +.endd +by setting up delivery to the host with that IP address. + +.em +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. + +The RFCs require support for domain literals; however, their use is +controversial in today's Internet. If you want to use this router, you must +also set the main configuration option \allow@_domain@_literals\. Otherwise, +Exim will not recognize the domain literal syntax in addresses. + + + +. +. +. +. +. ============================================================================ +.chapter The iplookup router +.set runningfoot "iplookup router" +.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 +.display asis +ROUTER_IPLOOKUP=yes +.endd +in your \(Local/Makefile)\ configuration file. + +The \%iplookup%\ router routes an address by sending it over a TCP or UDP +connection to one or more specific hosts. The host can then return the same or +a different address -- in effect rewriting the recipient address in the +message's envelope. The new address is then passed on to subsequent routers. + + +If this process fails, the address can be passed on to +other routers, or delivery can be deferred. + +Background, for those that are interested: We have an Oracle database of all +Cambridge users, and one of the items of data it maintains for each user is +where to send mail addressed to \*user@@cam.ac.uk*\. The MX records for +\*cam.ac.uk*\ point to a central machine that has a large alias list that is +abstracted from the database. Mail from outside is switched by this system, and +originally internal mail was also done this way. However, this resulted in a +fair number of messages travelling from some of our larger systems to the +switch and back again. The Oracle machine now runs a UDP service that can be +called by the \%iplookup%\ router in Exim to find out where \*user@@cam.ac.uk*\ +addresses really have to go; this saves passing through the central switch, and +in many cases saves doing any remote delivery at all. + +Since \%iplookup%\ is just a rewriting router, a transport must not be +specified for it. + +.startconf +.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()*\ +(or \*getipnodebyname()*\ when available) +and are tried in order until one responds to the query. If none respond, what +happens is controlled by \optional\. + +.conf optional boolean false +If \optional\ is true, if no response is obtained from any host, the address is +passed to the next router, overriding \no@_more\. If \optional\ is false, +delivery to the address is deferred. + +.conf port integer 0 +.index port||\%iplookup%\ router +This option must be supplied. It specifies the port number for the TCP or UDP +call. + +.conf protocol string "udp" +This option can be set to `udp' or `tcp' to specify which of the two protocols +is to be used. + +.conf query string$**$ "$tt{@$local@_part@@@$domain @$local@_part@@@$domain}" +This defines the content of the query that is sent to the remote hosts. The +repetition serves as a way of checking that a response is to the correct query +in the default case (see \response@_pattern\ below). + +.conf reroute string$**$ unset +If this option is not set, the rerouted address is precisely the byte string +returned by the remote host, up to the first white space, if any. If set, the +string is expanded to form the rerouted address. It can include parts matched +in the response by \response@_pattern\ by means of numeric variables such as +\$1$\, \$2$\, etc. The variable \$0$\ refers to the entire input string, +whether or not a pattern is in use. In all cases, the rerouted address must end +up in the form \*local@_part@@domain*\. + +.conf response@_pattern string unset +This option can be set to a regular expression that is applied to the string +returned from the remote host. If the pattern does not match the response, the +router declines. If \response@_pattern\ is not set, no checking of the response +is done, unless the query was defaulted, in which case there is a check that +the text returned after the first white space is the original address. This +checks that the answer that has been received is in response to the correct +question. For example, if the response is just a new domain, the following +could be used: +.display asis +response_pattern = ^([^@]+)$ +reroute = $local_part@$1 +.endd + +.conf timeout time 5s +This specifies the amount of time to wait for a response from the remote +machine. The same timeout is used for the \*connect()*\ function for a TCP +call. It does not apply to UDP. + +.endconf + + + + +. +. +. +. +. ============================================================================ +.chapter The manualroute router +.set runningfoot "manualroute router" +.index \%manualroute%\ router +.index routers||\%manualroute%\ +.index domain||manually routing +The \%manualroute%\ router is so-called because it provides a way of manually +routing an address according to its domain. It is mainly used when you want to +route addresses to remote hosts according to your own rules, bypassing the +normal DNS routing that looks up MX records. However, \%manualroute%\ can also +route to local transports, a facility that may be useful if you want to save +messages for dial-in hosts in local files. + +The \%manualroute%\ router compares a list of domain patterns with the domain it +is trying to route. If there is no match, the router declines. Each pattern has +associated with it a list of hosts and some other optional data, which may +include a transport. The combination of a pattern and its data is called a +`routing rule'. For patterns that do not have an associated transport, the +generic \transport\ option must specify a transport, unless the router is being +used purely for verification (see \verify@_only\). + +In the case of verification, matching the domain pattern is sufficient for the +router to accept the address. When actually routing an address for delivery, +an address that matches a domain pattern is queued for the associated +transport. If the transport is not a local one, a host list must be associated +with the pattern; IP addresses are looked up for the hosts, and these are +passed to the transport along with the mail address. For local transports, a +host list is optional. If it is present, it is passed in \$host$\ as a single +text string. + +The list of routing rules can be provided as an inline string in \route@_list\, +or the data can be obtained by looking up the domain in a file or database by +setting \route@_data\. Only one of these settings may appear in any one +instance of \%manualroute%\. The format of routing rules is described below, +following the list of private options. + +.section Private options for manualroute +.rset SECTprioptman "~~chapter.~~section" + +The private options for the \%manualroute%\ router are as follows: + +.startconf +.index options||\%manualroute%\ router + +.conf host@_find@_failed string "freeze" +This option controls what happens when \%manualroute%\ tries to find an IP +address for a host, and the host does not exist. The option can be set to one +of +.display asis +decline +defer +fail +freeze +pass +.endd +The default assumes that this state is a serious configuration error. The +difference between `pass' and `decline' is that the former forces the address +to be passed to the next router (or the router defined by \pass@_router\), +.index \more\ option +overriding \no@_more\, whereas the latter passes the address to the next router +only if \more\ is true. + +This option applies only to a definite `does not exist' state; if a host lookup +gets a temporary error, delivery is deferred unless the generic +\pass@_on@_timeout\ option is set. + +.conf hosts@_randomize boolean false +.index randomized host list +.index host||list of, randomized +If this option is set, the order of the items in a host list in a routing rule +is randomized each time the list is used, unless an option in the routing rule +overrides (see below). Randomizing the order of a host list can be used to do +crude load sharing. However, if more than one mail address is routed by the +same router to the same host list, the host lists are considered to be the same +(even though they may be randomized into different orders) for the purpose of +deciding whether to batch the deliveries into a single SMTP transaction. + +When \hosts@_randomize\ is true, a host list may be split +into groups whose order is separately randomized. This makes it possible to +set up MX-like behaviour. The boundaries between groups are indicated by an +item that is just \"+"\ in the host list. For example: +.display asis +route_list = * host1:host2:host3:+:host4:host5 +.endd +The order of the first three hosts and the order of the last two hosts is +randomized for each use, but the first three always end up before the last two. +If \hosts@_randomize\ is not set, a \"+"\ item in the list is ignored. If a +randomized host list is passed to an \%smtp%\ transport that also has +\hosts@_randomize set\, the list is not re-randomized. + +.conf route@_data string$**$ unset +If this option is set, it must expand to yield the data part of a routing rule. +Typically, the expansion string includes a lookup based on the domain. For +example: +.display asis +route_data = ${lookup{$domain}dbm{/etc/routes}} +.endd +If the expansion is forced to fail, or the result is an empty string, the +router declines. Other kinds of expansion failure cause delivery to be +deferred. + +.conf route@_list "string list, semicolon-separated" unset +This string is a list of routing rules, in the form defined below. Note that, +unlike most string lists, the items are separated by semicolons. This is so +that they may contain colon-separated host lists. + +.conf same@_domain@_copy@_routing boolean false +.index address||copying routing +Addresses with the same domain are normally routed by the \%manualroute%\ router +to the same list of hosts. However, this cannot be presumed, because the router +options and preconditions may refer to the local part of the address. By +default, therefore, Exim routes each address in a message independently. DNS +servers run caches, so repeated DNS lookups are not normally expensive, and in +any case, personal messages rarely have more than a few recipients. + +If you are running mailing lists with large numbers of subscribers at the same +domain, and you are using a \%manualroute%\ router which is independent of the +local part, you can set \same@_domain@_copy@_routing\ to bypass repeated DNS +lookups for identical domains in one message. In this case, when \%manualroute%\ +routes an address to a remote transport, any other unrouted addresses in the +message that have the same domain are automatically given the same routing +without processing them independently. However, this is only done if +\headers@_add\ and \headers@_remove\ are unset. + +.endconf + + +.section Routing rules in route@_list +The value of \route@_list\ is a string consisting of a sequence of routing +rules, separated by semicolons. If a semicolon is needed in a rule, it can be +entered as two semicolons. Empty rules are ignored. The format of each rule is +.display +<<domain pattern>> <<list of hosts>> <<options>> +.endd +The following example contains two rules, each with a simple domain pattern and +no options: +.display asis +route_list = \ + 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 +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), +except that it may not be the name of an interpolated file. +That is, it may be wildcarded, or a regular expression, or a file or database +lookup (with semicolons doubled, because of the use of semicolon as a separator +in a \route@_list\). + +The rules in \route@_list\ are searched in order until one of the patterns +matches the domain that is being routed. The list of hosts and then options are +then used as described below. If there is no match, the router declines. When +\route@_list\ is set, \route@_data\ must not be set. + + +.section Routing rules in route@_data +The use of \route@_list\ is convenient when there are only a small number of +routing rules. For larger numbers, it is easier to use a file or database to +hold the routing information, and use the \route@_data\ option instead. +The value of \route@_data\ is a list of hosts, followed by (optional) options. +Most commonly, \route@_data\ is set as a string that contains an +expansion lookup. For example, suppose we place two routing rules in a file +like this: +.display asis +dict.ref.example: mail-1.ref.example:mail-2.ref.example +thes.ref.example: mail-3.ref.example:mail-4.ref.example +.endd +This data can be accessed by setting +.display asis +route_data = ${lookup{$domain}lsearch{/the/file/name}} +.endd +Failure of the lookup results in an empty string, causing the router to +decline. However, you do not have to use a lookup in \route@_data\. The only +requirement is that the result of expanding the string is a list of hosts, +possibly followed by options, separated by white space. The list of hosts must +be enclosed in quotes if it contains white space. + + + +.section Format of the list of hosts +A list of hosts, whether obtained via \route@_data\ or \route@_list\, is always +separately expanded before use. If the expansion fails, the router declines. +The result of the expansion must be a colon-separated list of names and/or +IP addresses. IP addresses are not enclosed in brackets. + +If the list of hosts was obtained from a \route@_list\ item, the following +variables are set during its expansion: +.index numerical variables (\$1$\, \$2$\, etc)||in \%manualroute%\ router +.numberpars $. +If the domain was matched against a regular expression, the numeric variables +\$1$\, \$2$\, etc. may be set. +.nextp +\$0$\ is always set to the entire domain. +.nextp +\$1$\ is also set when partial matching is done in a file lookup. +.nextp +.index \$value$\ +If the pattern that matched the domain was a lookup item, the data that was +looked up is available in the expansion variable \$value$\. +.endp + + +.em +.section How the list of hosts is used +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 +transport. + +Hosts may be listed by name or by IP address. An unadorned name in the list of +hosts is interpreted as a host name. A name that is followed by \"/MX"\ is +interpreted as an indirection to a sublist of hosts obtained by looking up MX +records in the DNS. For example: +.display asis +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 +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 +.index \self\ option||in \%manualroute%\ router +\self\ option of the router. + +A name on the list that is followed by \"/MX"\ is replaced with the list of +hosts obtained by looking up MX records for the name. This is always a DNS +lookup; the \bydns\ and \byname\ options (see section ~~SECThowoptused below) +are not relevant here. The order of these hosts is determined by the preference +values in the MX records, according to the usual rules. Because randomizing +happens before the MX lookup, it does not affect the order that is defined by +MX preferences. +.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 +preferred hosts are removed before the sublist is inserted into the main list. + +If the local host is the most preferred host in the MX list, what happens +depends on where in the original list of hosts the \"/MX"\ item appears. If it +is not the first item (that is, there are previous hosts in the main list), +Exim discards this name and any subsequent items in the main list. + +If the MX item is first in the list of hosts, and the local host is the +most preferred host, what happens is controlled by the \self\ option of the +router. + +DNS failures when lookup up the MX records are treated in the same way as DNS +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 +.rset SECThowoptused "~~chapter.~~section" +The options are a sequence of words; in practice no more than three are ever +present. One of the words can be the name of a transport; this overrides the +\transport\ option on the router for this particular routing rule only. The +other words (if present) control randomization of the list of hosts on a +per-rule basis, and how the IP addresses of the hosts are to be found when +routing to a remote transport. These options are as follows: +.numberpars $. +\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, +overriding the setting of \hosts@_randomize\ for this routing rule only. +.nextp +\byname\: use \*getipnodebyname()*\ (\*gethostbyname()*\ on older systems) to +find IP addresses. This function may ultimately cause a DNS lookup, but it may +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. +.endp +For example: +.display asis +route_list = domain1 host1:host2:host3 randomize bydns;\ + domain2 host4:host5 +.endd +If neither \byname\ nor \bydns\ is given, Exim behaves as follows: First, a DNS +lookup is done. If this yields anything other than \\HOST@_NOT@_FOUND\\, that +result is used. Otherwise, Exim goes on to try a call to \*getipnodebyname()*\ +or \*gethostbyname()*\, and the result of the lookup is the result of that +call. + +\**Warning**\: It has been discovered that on some systems, if a DNS lookup +called via \*getipnodebyname()*\ times out, \\HOST@_NOT@_FOUND\\ is returned +instead of \\TRY@_AGAIN\\. That is why the default action is to try a DNS +lookup first. Only if that gives a definite `no such host' is the local +function called. + + + +If no IP address for a host can be found, what happens is controlled by the +\host@_find@_failed\ option. + +When an address is routed to a local transport, IP addresses are not looked up. +The host list is passed to the transport in the \$host$\ variable. + + +.section Manualroute examples +In some of the examples that follow, the presence of the \remote@_smtp\ +transport, as defined in the default configuration file, is assumed: + +.numberpars $. +.index smart host||example router +The \%manualroute%\ router can be used to forward all external mail to a +\*smart host*\. If you have set up, in the main part of the configuration, a +named domain list that contains your local domains, for example, +.display asis +domainlist local_domains = my.domain.example +.endd +you can arrange for all other domains to be routed to a smart host by making +your first router something like this: +.display asis +smart_route: + driver = manualroute + domains = !+local_domains + transport = remote_smtp + route_list = * smarthost.ref.example +.endd +This causes all non-local addresses to be sent to the single host +\*smarthost.ref.example*\. If a colon-separated list of smart hosts is given, +they are tried in order +(but you can use \hosts@_randomize\ to vary the order each time). +Another way of configuring the same thing is this: +.display asis +smart_route: + driver = manualroute + transport = remote_smtp + route_list = !+local_domains smarthost.ref.example +.endd +There is no difference in behaviour between these two routers as they stand. +However, they behave differently if \no@_more\ is added to them. In the first +example, the router is skipped if the domain does not match the \domains\ +precondition; the following router is always tried. If the router runs, it +always matches the domain and so can never decline. Therefore, \no@_more\ would +have no effect. In the second case, the router is never skipped; it always +runs. However, if it doesn't match the domain, it declines. In this case +\no@_more\ would prevent subsequent routers from running. + +.nextp +.index mail hub example +A \*mail hub*\ is a host which receives mail for a number of domains via MX +records in the DNS and delivers it via its own private routing mechanism. Often +the final destinations are behind a firewall, with the mail hub being the one +machine that can connect to machines both inside and outside the firewall. The +\%manualroute%\ router is usually used on a mail hub to route incoming messages +to the correct hosts. For a small number of domains, the routing can be inline, +using the \route@_list\ option, but for a larger number a file or database +lookup is easier to manage. + +If the domain names are in fact the names of the machines to which the mail is +to be sent by the mail hub, the configuration can be quite simple. For +example, +.display asis +hub_route: + driver = manualroute + transport = remote_smtp + route_list = *.rhodes.tvs.example $domain +.endd +This configuration routes domains that match \"*.rhodes.tvs.example"\ to hosts +whose names are the same as the mail domains. A similar approach can be taken +if the host name can be obtained from the domain name by a string manipulation +that the expansion facilities can handle. Otherwise, a lookup based on the +domain can be used to find the host: +.display asis +through_firewall: + driver = manualroute + transport = remote_smtp + route_data = ${lookup {$domain} cdb {/internal/host/routes}} +.endd +The result of the lookup must be the name or IP address of the host (or +hosts) to which the address is to be routed. If the lookup fails, the route +data is empty, causing the router to decline. The address then passes to the +next router. + +.nextp +.index batched SMTP output example +.index SMTP||batched outgoing, example +You can use \%manualroute%\ to deliver messages to pipes or files in batched +SMTP format for onward transportation by some other means. This is one way of +storing mail for a dial-up host when it is not connected. The route list entry +can be as simple as a single domain name in a configuration like this: +.display asis +save_in_file: + driver = manualroute + transport = batchsmtp_appendfile + route_list = saved.domain.example +.endd +though often a pattern is used to pick up more than one domain. If there are +several domains or groups of domains with different transport requirements, +different transports can be listed in the routing information: +.display asis +save_in_file: + driver = manualroute + route_list = \ + *.saved.domain1.example $domain batch_appendfile; \ + *.saved.domain2.example \ + ${lookup{$domain}dbm{/domain2/hosts}{$value}fail} \ + batch_pipe +.endd +The first of these just passes the domain in the \$host$\ variable, which +doesn't achieve much (since it is also in \$domain$\), but the second does a +file lookup to find a value to pass, causing the router to decline to handle +the address if the lookup fails. +.nextp +.index UUCP||example of router for +Routing mail directly to UUCP software is a specific case of the use of +\%manualroute%\ in a gateway to another mail environment. This is an example of +one way it can be done: +.display asis +# Transport +uucp: + driver = pipe + user = nobody + command = /usr/local/bin/uux -r - \ + ${substr_-5:$host}!rmail ${local_part} + return_fail_output = true +.endd +.display asis +# Router +uucphost: + transport = uucp + driver = manualroute + route_data = \ + ${lookup{$domain}lsearch{/usr/local/exim/uucphosts}} +.endd +The file \(/usr/local/exim/uucphosts)\ contains entries like +.display asis +darksite.ethereal.example: darksite.UUCP +.endd +It can be set up more simply without adding and removing `.UUCP' but this way +makes clear the distinction between the domain name +\*darksite.ethereal.example*\ and the UUCP host name \*darksite*\. +.endp + + + + + + +. +. +. +. +. ============================================================================ +.chapter The queryprogram router +.set runningfoot "queryprogram router" +.rset CHAPdriverlast "~~chapter" +.index \%queryprogram%\ router +.index routers||\%queryprogram%\ +.index routing||by external program +The \%queryprogram%\ router routes an address by running an external command and +acting on its output. This is an expensive way to route, and is intended mainly +for use in lightly-loaded systems, or for performing experiments. However, if +it is possible to use the precondition options (\domains\, \local@_parts\, +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 +.index options||\%queryprogram%\ router +.conf command string$**$ unset +This option must be set. It specifies the command that is to be run. The +command is split up into a command name and arguments, and then each is +expanded separately (exactly as for a \%pipe%\ transport, described in chapter +~~CHAPpipetransport). + +.conf command@_group string unset +.index gid (group id)||in \%queryprogram%\ router +This option specifies a gid to be set when running the command. It must be set +if \command@_user\ specifies a numerical uid. If it begins with a digit, it is +interpreted as the numerical value of the gid. Otherwise it is looked up using +\*getgrnam()*\. + +.conf command@_user string unset +.index uid (user id)||for \%queryprogram%\ +This option must be set. It specifies the uid which is set when running the +command. If it begins with a digit it is interpreted as the numerical value of +the uid. Otherwise, it is looked up using \*getpwnam()*\ to obtain a value for +the uid and, if \command@_group\ is not set, a value for the gid also. + +.conf current@_directory string / +This option specifies an absolute path which is made the current directory +before running the command. + +.conf timeout time 1h +If the command does not complete within the timeout period, its process group +is killed and the message is frozen. A value of zero time specifies no +timeout. + +.endconf + +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): +.numberpars $. +\*Accept*\: routing succeeded; the remaining fields specify what to do (see +below). +.nextp +\*Decline*\: the router declines; pass the address to the next router, unless +\no@_more\ is set. +.nextp +\*Fail*\: routing failed; do not pass the address to any more routers. Any +subsequent text on the line is an error message. If the router is run as part +of address verification during an incoming SMTP message, the message is +included in the SMTP response. +.nextp +\*Defer*\: routing could not be completed at this time; try again later. Any +subsequent text on the line is an error message which is logged. It is not +included in any SMTP response. +.nextp +\*Freeze*\: the same as \*defer*\, except that the message is frozen. +.nextp +\*Pass*\: pass the address to the next router (or the router specified by +\pass@_router\), overriding \no@_more\. +.nextp +\*Redirect*\: the message is redirected. The remainder of the line is a list of +new addresses, which are routed independently, starting with the first router, +or the router specified by \redirect@_router\, if set. +.endp +When the first word is \*accept*\, the remainder of the line consists of a +number of keyed data values, as follows (split into two lines here, to fit on +the page): +.display +ACCEPT TRANSPORT=<<transport>> HOSTS=<<list of hosts>> + LOOKUP=byname|bydns DATA=<<text>> +.endd +The data items can be given in any order, and all are optional. If no transport +is included, the transport specified by the generic \transport\ option is used. +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. +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 +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 +result of the lookup is the result of that call. + +If the DATA field is set, its value is placed in the \$address@_data$\ +variable. For example, this return line +.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$\. + + + +. +. +. +. +. ============================================================================ +.chapter The redirect router +.set runningfoot "redirect router" +.rset CHAPredirect "~~chapter" +.index \%redirect%\ router +.index routers||\%redirect%\ +.index alias file||in a \%redirect%\ router +.index address redirection||\%redirect%\ router +The \%redirect%\ router handles several kinds of address redirection. Its most +common uses are for resolving local part aliases from a central alias file +(usually called \(/etc/aliases)\) and for handling users' personal \(.forward)\ +files, but it has many other potential uses. The incoming address can be +redirected in several different ways: +.numberpars $. +It can be replaced by one or more new addresses which are themselves routed +independently. +.nextp +It can be routed to be delivered to a given file or directory. +.nextp +It can be routed to be delivered to a specified pipe command. +.nextp +It can cause an automatic reply to be generated. +.nextp +It can be forced to fail, with a custom error message. +.nextp +It can be temporarily deferred. +.nextp +It can be discarded. +.endp +The generic \transport\ option must not be set for \%redirect%\ routers. +However, there are some private options which define transports for delivery to +files and pipes, and for generating autoreplies. See the \file@_transport\, +\pipe@_transport\ and \reply@_transport\ descriptions below. + + +.section Redirection data +The router operates by interpreting a text string which it obtains either by +expanding the contents of the \data\ option, or by reading the entire contents +of a file whose name is given in the \file\ option. These two options are +mutually exclusive. The first is commonly used for handling system aliases, in +a configuration like this: +.display asis +system_aliases: + 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 +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: +.display asis +userforward: + driver = redirect + check_local_user + file = $home/.forward + no_verify +.endd +If the file does not exist, or causes no action to be taken (for example, it is +empty or consists only of comments), the router declines. \**Warning**\: This +is not the case when the file contains syntactically valid items that happen to +yield empty addresses, for example, items containing only RFC 2822 address +comments. + + +.section Forward files and address verification +.index address redirection||while verifying +It is usual to set \no@_verify\ on \%redirect%\ routers which handle users' +\(.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 +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 +operate. +.nextp +However, even when the router can operate, the existence of a \(.forward)\ file +is unimportant when verifying an address. What should be checked is whether the +local part is a valid user name or not. Cutting out the redirection processing +saves some resources. +.endp + + + + +.section Interpreting redirection data +.index Sieve filter||specifying in redirection data +.index filter||specifying in redirection data +The contents of the data string, whether obtained from \data\ or \file\, can be +interpreted in two different ways: +.numberpars $. +If the \allow@_filter\ option is set true, and the data begins with the text +`@#Exim filter' or `@#Sieve filter', it is interpreted as a list of +\*filtering*\ instructions in the form of an Exim or Sieve filter file, +respectively. Details of the syntax and semantics of filter files are described +in a separate document entitled \*Exim's interfaces to mail filtering*\; this +document is intended for use by end users. +.nextp +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 +the \%appendfile%\ transport. + + +.section Items in a non-filter redirection list +.rset SECTitenonfilred "~~chapter.~~section" +.index address redirection||non-filter list items +When the redirection data is not an Exim or Sieve filter, for example, if it +comes from a conventional alias or forward file, it consists of a list of +addresses, file names, pipe commands, or certain special items (see section +~~SECTspecitredli below). The special items can be individually enabled or +disabled by means of options whose names begin with \allow@_\ or \forbid@_\, +depending on their default values. The items in the list are separated by +commas or newlines. +If a comma is required in an item, the entire item must be enclosed in double +quotes. + +Lines starting with a @# character are comments, and are ignored, and @# may +also appear following a comma, in which case everything between the @# and the +next newline character is ignored. + +If an item is entirely enclosed in double quotes, these are removed. Otherwise +double quotes are retained because some forms of mail address require their use +(but never to enclose the entire address). In the following description, `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 +setting: +.display asis +data = ${quote:$local_part}@newdomain.example +.endd + + +.section Redirecting to a local mailbox +.rset SECTredlocmai "~~chapter.~~section" +.index routing||loops in +.index loop||while routing, avoidance of +.index address redirection||to local mailbox +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 +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. + +.index address redirection||local part without domain +Specifying the same local part without a domain is a common usage in personal +filter files when the user wants to have messages delivered to the local +mailbox and also forwarded elsewhere. For example, the user whose login is +\*cleo*\ might have a \(.forward)\ file containing this: +.display asis +cleo, cleopatra@egypt.example +.endd +.index backslash in alias file +.index alias file||backslash in +For compatibility with other MTAs, such unqualified local parts may be +preceeded by `@\', but this is not a requirement for loop prevention. However, +it does make a difference if more than one domain is being handled +synonymously. + +If an item begins with `@\' and the rest of the item parses as a valid RFC 2822 +address that does not include a domain, the item is qualified using the domain +of the incoming address. In the absence of a leading `@\', unqualified +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 +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 +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 +and the following routers presumably cannot handle the alias. The forward file +should really contain +.display asis +spqr, spqr@reme.elsewhere.example +.endd +but because this is such a common error, the \check@_ancestor\ option (see +below) exists to provide a way to get round it. This is normally set on a +\%redirect%\ router that is handling users' \(.forward)\ files. + + +.section Special items in redirection lists +.rset SECTspecitredli "~~chapter.~~section" +In addition to addresses, the following types of item may appear in redirection +lists (that is, in non-filter redirection data): + +.numberpars $. +.index pipe||in redirection list +.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 +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 +the command contains a comma character, it is necessary to put the whole item +in double quotes, for example: +.display asis +"|/some/command ready,steady,go" +.endd +since items in redirection lists are terminated by commas. Do not, however, +quote just the command. An item such as +.display asis +|"/some/command ready,steady,go" +.endd +is interpreted as a pipe with a rather strange command name, and no arguments. +.nextp +.index file||in redirection list +.index address redirection||to file +An item is interpreted as a path name if it begins with `/' and does not parse +as a valid RFC 2822 address that includes a domain. For example, +.display asis +/home/world/minbari +.endd +is treated as a file name, but +.display asis +/s=molari/o=babylon/@x400gate.way +.endd +is treated as an address. For a file name, a transport must be specified using +the \file@_transport\ option. However, if the generated path name ends with a +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 +If an item is of the form +.display +: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 +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 +\%lsearch%\ file, a colon must be used to terminate the alias name. This +example is incorrect: +.display asis +list1 :include:/opt/lists/list1 +.endd +It must be given as +.display asis +list1: :include:/opt/lists/list1 +.endd +.nextp +.index address redirection||to black hole +Sometimes you want to throw away mail to a particular local part. Making the +\data\ option expand to an empty string does not work, because that causes the +router to decline. Instead, the alias item +.index black hole +.index abandoning mail +.display +:blackhole: +.endd +can be used. It does what its name implies. No delivery is done, and no error +message is generated. This has the same effect as 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 +\(/dev/null)\. + +.nextp +.index delivery||forcing failure +.index delivery||forcing deferral +.index failing delivery||forcing +.index deferred delivery, forcing +.index customizing||failure message +An attempt to deliver a particular address can be deferred or forced to fail by +redirection items of the form +.display +:defer: +$rm{or} +:fail: +.endd +respectively. When a redirection list contains such an item, it applies to the +entire redirection; any other items in the list are ignored (:::blackhole:: is +different). Any text following :::fail:: or :::defer:: is placed in the error +text associated with the failure. For example, an alias file might contain: +.display asis +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. + + + +Normally the error text is the rest of the redirection list -- a comma does not +terminate it -- but a newline does act as a terminator. Newlines are not +normally present in alias expansions. In \%lsearch%\ lookups they are removed as +part of the continuation process, but they may exist in other kinds of lookup +and in :::include:: files. + +During routing for message delivery (as opposed to verification), a redirection +containing :::fail:: causes an immediate failure of the incoming address, +whereas :::defer:: causes the message to remain on the queue so that a +subsequent delivery attempt can happen at a later time. If an address is +deferred for too long, it will ultimately fail, because the normal retry +rules still apply. +.nextp +.index alias file||exception to default +Sometimes it is useful to use a single-key search type with a default (see +chapter ~~CHAPfdlookup) to look up aliases. However, there may be a need for +exceptions to the default. These can be handled by aliasing them to +.display asis +:unknown: +.endd +This differs from :::fail:: in that it causes the \%redirect%\ router to decline, +whereas :::fail:: forces routing to fail. A lookup which results in an empty +redirection list has the same effect. +.endp + +.section Duplicate addresses +.index duplicate addresses +.index address||duplicate, discarding +.index pipe||duplicated +Exim removes duplicate addresses from the list to which it is delivering, so as +to deliver just one copy to each address. This does not apply to deliveries +routed to pipes by different immediate parent addresses, but an indirect +aliasing scheme of the type +.display asis +pipe: |/some/command $local_part +localpart1: pipe +localpart2: pipe +.endd +does not work with a message that is addressed to both local parts, because +when the second is aliased to the intermediate local part `pipe' it gets +discarded as being the same as a previously handled address. However, a scheme +such as +.display asis +localpart1: |/some/command $local_part +localpart2: |/some/command $local_part +.endd +does result in two different pipe deliveries, because the immediate parents of +the pipes are distinct. + + +.section Repeated redirection expansion +.index repeated redirection expansion +.index address redirection||repeated for each delivery attempt +When a message cannot be delivered to all of its recipients immediately, +leading to two or more delivery attempts, redirection expansion is carried out +afresh each time for those addresses whose children were not all previously +delivered. If redirection is being used as a mailing list, this can lead to new +members of the list receiving copies of old messages. The \one@_time\ option +can be used to avoid this. + +.section Errors in redirection lists +.index address redirection||errors +If \skip@_syntax@_errors\ is set, a malformed address that causes a parsing +error is skipped, and an entry is written to the main log. This may be useful +for mailing lists that are automatically managed. Otherwise, if an error is +detected while generating the list of new addresses, the original address is +deferred. See also \syntax@_errors@_to\. + + +.section Private options for the redirect router + +The private options for the \%redirect%\ router are as follows: + +.startconf +.index options||\%redirect%\ router + +.conf allow@_defer boolean false +Setting this option allows the use of :::defer:: in non-filter redirection +data, +or the \defer\ command in an Exim filter file. + +.conf allow@_fail boolean false +.index failing delivery||from filter +If this option is true, the :::fail:: item can be used in a redirection list, +and the \fail\ command may be used in a filter file. + +.conf allow@_filter boolean false +.index filter||enabling use of +.index Sieve filter||enabling use of +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. + + +.conf allow@_freeze boolean false +.index freezing messages||allowing in filter +Setting this option allows the use of the \freeze\ command in an Exim filter. +This command is more normally encountered in system filters, and is disabled by +default for redirection filters because it isn't something you usually want to +let ordinary users do. + + +.conf check@_ancestor boolean false +This option is concerned with handling generated addresses that are the same +as some address in the list of redirection ancestors of the current address. +Although it is turned off by default in the code, it is set in the default +configuration file for handling users' \(.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 +domain, the local part `Joe.Bloggs' is aliased to `jb' and \(@~jb/.forward)\ +contains: +.nem +.display +@\Joe.Bloggs, <<other item(s)>> +.endd +Without the \check@_ancestor\ setting, either local part (`jb' or `joe.bloggs') +gets processed once by each router and so ends up as it was originally. If `jb' +is the real mailbox name, mail to `jb' gets delivered (having been turned into +`joe.bloggs' by the \(.forward)\ file and back to `jb' by the alias), but mail +to `joe.bloggs' fails. Setting \check@_ancestor\ on the \%redirect%\ router that +handles the \(.forward)\ file prevents it from turning `jb' back into +`joe.bloggs' when that was the original address. See also the \repeat@_use\ +option below. + +.conf check@_group boolean "see below" +When the \file\ option is used, the group owner of the file is checked only +when this option is set. The permitted groups are those listed in the +\owngroups\ option, together with the user's default group if +\check@_local@_user\ is set. If the file has the wrong group, routing is +deferred. The default setting for this option is true if \check@_local@_user\ +is set and the \modemask\ option permits the group write bit, or if the +\owngroups\ option is set. Otherwise it is false, and no group check occurs. + + +.conf check@_owner boolean "see below" +When the \file\ option is used, the owner of the file is checked only when this +option is set. If \check@_local@_user\ is set, the local user is permitted; +otherwise the owner must be one of those listed in the \owners\ option. The +default value for this option is true if \check@_local@_user\ or \owners\ is +set. Otherwise the default is false, and no owner check occurs. + +.conf data string$**$ unset +This option is mutually exclusive with \file\. One or other of them must be +set, but not both. The contents of \data\ are expanded, and then used as the +list of forwarding items, or as a set of filtering instructions. If the +expansion is forced to fail, or the result is an empty string or a string that +has no effect (consists entirely of comments), the router declines. + +When filtering instructions are used, the string must begin with `@#Exim +filter', and all comments in the string, including this initial one, must be +terminated with newline characters. For example: +.display asis +data = #Exim filter\n\ + if $h_to: contains Exim then save $home/mail/exim endif +.endd +If you are reading the data from a database where newlines cannot be included, +you can use the \$@{sg@}$\ expansion item to turn the escape string of your +choice into a newline. + +.conf directory@_transport string$**$ unset +A \%redirect%\ router sets up a direct delivery to a directory when a path name +ending with 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. This should normally be an \%appendfile%\ transport. + +.conf file string$**$ unset +This option specifies the name of a file that contains the redirection data. It +is mutually exclusive with the \data\ option. The string is expanded before +use; if the expansion is forced to fail, the router declines. Other expansion +failures cause delivery to be deferred. The result of a successful expansion +must be an absolute path. The entire file is read and used as the redirection +data. If the data is an empty string or a string that has no effect (consists +entirely of comments), the router declines. + +.index NFS||checking for file existence +If the attempt to open the file fails with a `does not exist' error, Exim +runs a check on the containing directory, +unless \ignore@_enotdir\ is true (see below). +If the directory does not appear to exist, delivery is deferred. This can +happen when users' \(.forward)\ files are in NFS-mounted directories, and there +is a mount problem. If the containing directory does exist, but the file does +not, the router declines. + +.conf file@_transport string$**$ unset +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. +This should normally be an \%appendfile%\ transport. +When it is running, the file name is in \$address@_file$\. + +.conf forbid@_blackhole boolean false +If this option is true, the :::blackhole:: item may not appear in a redirection +list. + +.conf forbid@_file boolean false +.index delivery||to file, forbidding +.index Sieve filter||forbidding delivery to a file +.index Sieve filter||`keep' facility, disabling +If this option is true, this router may not generate a new address that +specifies delivery to a local file or directory, either from a filter or from a +conventional forward file. This option is forced to be true if \one@_time\ is +set. It applies to Sieve filters as well as to Exim filters, but if true, it +locks out the Sieve's `keep' facility. + +.conf forbid@_filter@_existstest boolean false +.index filter||locking out certain features +If this option is true, string expansions in Exim filters are not allowed to +make use of the \exists\ condition. + +.conf forbid@_filter@_logwrite boolean false +If this option is true, use of the logging facility in Exim filters is not +permitted. Logging is in any case available only if the filter is being run +under some unprivileged uid (which is normally the case for ordinary users' +\(.forward)\ files). + +.conf forbid@_filter@_lookup boolean false +If this option is true, string expansions in Exim filter files are not allowed +to make use of \lookup\ items. + +.conf forbid@_filter@_perl boolean false +This option is available only if Exim is built with embedded Perl support. If +it is true, string expansions in Exim filter files are not allowed to make use +of the embedded Perl support. + +.conf forbid@_filter@_readfile boolean false +If this option is true, string expansions in Exim filter files are not allowed +to make use of \readfile\ items. + +.conf forbid@_filter@_readsocket boolean false +If this option is true, string expansions in Exim filter files are not allowed +to make use of \readsocket\ items. + +.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. + +.conf forbid@_filter@_run boolean false +If this option is true, string expansions in Exim filter files are not allowed +to make use of \run\ items. + +.conf forbid@_include boolean false +If this option is true, items of the form +.display +:include:<<path name>> +.endd +are not permitted in non-filter redirection lists. + +.conf forbid@_pipe boolean false +.index delivery||to pipe, forbidding +If this option is true, this router may not generate a new address which +specifies delivery to a pipe, either from an Exim filter or from a conventional +forward file. This option is forced to be true if \one@_time\ is set. + +.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 +generates a bounce or delay message for it. Instead it says `an address +generated from <<the top level address>>'. Of course, this applies only to +bounces generated locally. If a message is forwarded to another host, $it{its} +bounce may well quote the generated address. + +.conf ignore@_eacces boolean false +.index \\EACCES\\ +If this option is set and an attempt to open a redirection file yields the +\\EACCES\\ error (permission denied), the \%redirect%\ router behaves as if the +file did not exist. + +.conf ignore@_enotdir boolean false +.index \\ENOTDIR\\ +If this option is set and an attempt to open a redirection file yields the +\\ENOTDIR\\ error (something on the path is not a directory), the \%redirect%\ +router behaves as if the file did not exist. + +Setting \ignore@_enotdir\ has another effect as well: When a \%redirect%\ +router that has the \file\ option set discovers that the file does not exist +(the \\ENOENT\\ error), it tries to \*stat()*\ the parent directory, as a check +against unmounted NFS directories. If the parent can not be statted, delivery +is deferred. However, it seems wrong to do this check when \ignore@_enotdir\ is +set, because that option tells Exim to ignore `something on the path is not a +directory' (the \\ENOTDIR\\ error). This is a confusing area, because it seems +that some operating systems give \\ENOENT\\ where others give \\ENOTDIR\\. + + +.conf include@_directory string unset +If this option is set, the path names of any :::include:: items in a redirection +list must start with this directory. + +.conf modemask "octal integer" 022 +This specifies mode bits which must not be set for a file specified by the +\file\ option. If any of the forbidden bits are set, delivery is deferred. + +.conf one@_time boolean false +.index one-time aliasing/forwarding expansion +.index alias file||one-time expansion +.index forward file||one-time expansion +.index mailing lists||one-time expansion +.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 +to handle that -- but of what happens when the redirection list changes during +the time that the message is on Exim's queue. This is particularly true in the +case of mailing lists, where new subscribers might receive copies of messages +that were posted before they subscribed. + +If \one@_time\ is set and any addresses generated by the router fail to +deliver at the first attempt, the failing addresses are added to the message as +`top level' addresses, and the parent address that generated them is marked +`delivered'. Thus, redirection does not happen again at the next +delivery attempt. + +\**Warning 1**\: This means that any header line addition or removal that is +specified by this router would be lost if delivery did not succeed at the +first attempt. For this reason, the \headers@_add\ and \headers@_remove\ +generic options are not permitted when \one@_time\ is set. + +\**Warning 2**\: To ensure that the router generates only addresses (as opposed +to pipe or file deliveries or auto-replies) \forbid@_file\, \forbid@_pipe\, +and \forbid@_filter@_reply\ are forced to be true when \one@_time\ is set. + +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 +\all__parents\ log selector is set. It is expected that \one@_time\ will +typically be used for mailing lists, where there is normally just one level of +expansion. + +.conf owners "string list" unset +.index ownership||alias file +.index ownership||forward file +.index alias file||ownership +.index forward file||ownership +This specifies a list of permitted owners for the file specified by \file\. +This list is in addition to the local user when \check@_local@_user\ is set. +See \check@_owner\ above. + +.conf owngroups "string list" unset +This specifies a list of permitted groups for the file specified by \file\. The +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. +This should normally be a \%pipe%\ transport. +When the transport is run, the pipe command is in \$address@_pipe$\. + +.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 +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 +any ancestor that was routed by this router. This test happens before any of +the other preconditions are tested. Exim's default anti-looping rules skip +only when the ancestor is the same as the current address. See also +\check@_ancestor\ above and the generic \redirect@_router\ option. + +.conf reply@_transport string$**$ unset +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 +unlikely to do anything sensible or useful. + +.conf rewrite boolean true +.index address redirection||disabling rewriting +If this option is set false, addresses generated by the router are not +subject to address rewriting. Otherwise, they are treated like new addresses +and are rewritten according to the global rewriting rules. + +.conf skip@_syntax@_errors boolean false +.index forward file||broken +.index address redirection||broken files +.index alias file||broken +.index broken alias or forward files +.index ignoring faulty addresses +.index skipping faulty addresses +.index error||skipping bad syntax +If \skip@_syntax@_errors\ is set, syntactically malformed addresses in +non-filter redirection data are skipped, and each failing address is logged. If +\syntax@_errors@_to\ is set, a message is sent to the address it defines, +giving details of the failures. If \syntax@_errors@_text\ is set, its contents +are expanded and placed at the head of the error message generated by +\syntax@_errors@_to\. Usually it is appropriate to set \syntax@_errors@_to\ to +be the same address as the generic \errors@_to\ option. The +\skip@_syntax@_errors\ option is often used when handling mailing lists. + +If all the addresses in a redirection list are skipped because of syntax +errors, the router declines to handle the original address, and it is passed to +the following routers. + +If \skip@_syntax@_errors\ is set when an Exim filter is interpreted, any syntax +error in the filter causes filtering to be abandoned without any action being +taken. The incident is logged, and the router declines to handle the address, +so it is passed to the following routers. + +.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 +\syntax@_errors@_text\ are not used. + +\skip@_syntax@_errors\ can be used to specify that errors in users' forward +lists or filter files should not prevent delivery. The \syntax@_errors@_to\ +option, used with an address that does not get redirected, can be used to +notify users of these errors, by means of a router like this: +.display flow asis +userforward: + driver = redirect + allow_filter + check_local_user + file = $home/.forward + file_transport = address_file + pipe_transport = address_pipe + reply_transport = address_reply + no_verify + skip_syntax_errors + syntax_errors_to = real-$local_part@$domain + syntax_errors_text = \ + This is an automatically generated message. An error has\n\ + been found in your .forward file. Details of the error are\n\ + reported below. While this error persists, you will receive\n\ + a copy of this message for every message that is addressed\n\ + to you. If your .forward file is a filter file, or if it is\n\ + a non-filter file containing no valid forwarding addresses,\n\ + a copy of each incoming message will be put in your normal\n\ + mailbox. If a non-filter file contains at least one valid\n\ + forwarding address, forwarding to the valid addresses will\n\ + happen, and those will be the only deliveries that occur. +.endd +You also need a router to ensure that local addresses that are prefixed by +\"real-"\ are recognized, but not forwarded or filtered. For example, you could +put this immediately before the \%userforward%\ router: +.display asis +real_localuser: + driver = accept + check_local_user + local_part_prefix = real- + transport = local_delivery +.endd + +.conf syntax@_errors@_text string$**$ unset +See \skip@_syntax@_errors\ above. + +.conf syntax@_errors@_to string unset +See \skip@_syntax@_errors\ above. + +.endconf + + + + + +. +. +. +. ============================================================================ +.chapter Environment for running local transports +.rset CHAPenvironment "~~chapter" +.set runningfoot "local transport environment" +.index local transports||environment for +.index environment for local transports +.index transport||local, environment for +Local transports handle deliveries to files and pipes. (The \%autoreply%\ +transport can be thought of as similar to a pipe.) Exim always runs transports +in subprocesses, under specified uids and gids. Typical deliveries to local +mailboxes run under the uid and gid of the local user. + +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 +~~SECTpipeenv for details. + +The values used for the uid, gid, and the directories may come from several +different places. In many cases, the router that handles the address associates +settings with that address as a result of its \check@_local@_user\, \group\, or +\user\ options. However, values may also be given in the transport's own +configuration, and these override anything that comes from the router. + +.section Uids and gids +.rset SECTenvuidgid "~~chapter.~~section" +.index local transports||uid and gid +.index transport||local, uid and gid +All transports have the options \group\ and \user\. If \group\ is set, it +overrides any group that the router set in the address, even if \user\ is not +set for the transport. This makes it possible, for example, to run local mail +delivery under the uid of the recipient (set by the router), but in a special +group (set by the transport). For example: +.display asis +# Routers ... +# User/group are set by check_local_user in this router +local_users: + driver = accept + check_local_user + transport = group_delivery + +# Transports ... +# This transport overrides the group +group_delivery: + driver = appendfile + file = /var/spool/mail/$local_part + group = mail +.endd +If \user\ is set for a transport, its value overrides what is set in the +address. If \user\ is non-numeric and \group\ is not set, the gid associated +with the user is used. If \user\ is numeric, \group\ must be set. + +.index \initgroups\ option +When the uid is taken from the transport's configuration, the \*initgroups()*\ +function is called for the groups associated with that uid if the \initgroups\ +option is set for the transport. When the uid is not specified by the +transport, but is associated with the address by a router, the option for +calling \*initgroups()*\ is taken from the router configuration. + +.index \%pipe%\ transport||uid for +The \%pipe%\ transport contains the special option \pipe@_as@_creator\. If this +is set and \user\ is not set, the uid of the process that called Exim to +receive the message is used, and if \group\ is not set, the corresponding +original gid is also used. + + +.section Current and home directories +.index current directory for local transport +.index home directory||for local transport +.index transport||local, home directory for +.index transport||local, current directory for +Routers may set current and home directories for local transports by means of +the \transport__current@_directory\ and \transport@_home@_directory\ options. +However, if the transport's \current__directory\ or \home@_directory\ options +are set, they override the router's values. In detail, the home directory +for a local transport is taken from the first of these values that is set: +.numberpars $. +The \home@_directory\ option on the transport; +.nextp +The \transport@_home@_directory\ option on the router; +.nextp +The password data if \check@_local@_user\ is set on the router; +.nextp +The \router@_home@_directory\ option on the router. +.endp +The current directory is taken from the first of these values that is set: +.numberpars $. +The \current@_directory\ option on the transport; +.nextp +The \transport@_current@_directory\ option on the router. +.endp + +If neither the router nor the transport sets a current directory, Exim uses the +value of the home directory, if it is set. Otherwise it sets the current +directory to \(/)\ before running a local transport. + + +.section Expansion variables derived from the address +Normally a local delivery is handling a single address, and in that case the +variables such as \$domain$\ and \$local@_part$\ are set during local +deliveries. However, in some circumstances more than one address may be handled +at once (for example, while writing batch SMTP for onward transmission by some +other means). In this case, the variables associated with the local part are +never set, \$domain$\ is set only if all the addresses have the same +domain, and \$original@_domain$\ is never set. + + + + + + + +. +. +. +. ============================================================================ +.chapter Generic options for transports +.rset CHAPtransportgeneric "~~chapter" +.set runningfoot "generic transport options" + +.index generic options||transport +.index options||generic, for transports +.index transport||generic options for +The following generic options apply to all transports: + +.startconf +.conf body@_only boolean false +.index transport||body only +.index message||transporting body only +.index body of message||transporting +If this option is set, the message's headers are not transported. It is +mutually exclusive with \headers@_only\. If it is used with the \%appendfile%\ or +\%pipe%\ transports, the settings of \message@_prefix\ and \message@_suffix\ +should be checked, because this option does not automatically suppress them. + +.conf current@_directory string$**$ unset +.index transport||current directory for +This specifies the current directory that is to be set while running the +transport, overriding any value that may have been set by the router. +If the expansion fails for any reason, including forced failure, an error is +logged, and delivery is deferred. + +.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 +transport errors. You should not set this option unless you really, really know +what you are doing. + +.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 when the +transport is run. +If expansion of the string fails, the error message is written to the debugging +output, and Exim carries on processing. +This facility is provided to help with checking out the values of variables and +so on when debugging driver configurations. For example, if a \headers@_add\ +option is not working properly, \debug@_print\ could be used to output the +variables it references. A newline is added to the text if it does not end with +one. + +.conf delivery@_date@_add boolean false +.index ::Delivery-date:: header line +If this option is true, a ::Delivery-date:: header is added to the message. This +gives the actual time the delivery was made. As this is not a standard header, +Exim has a configuration option (\delivery@_date@_remove\) which requests its +removal from incoming messages, so that delivered messages can safely be resent +to other recipients. + +.conf driver string unset +This specifies which of the available transport drivers is to be used. +There is no default, and this option must be set for every transport. + +.conf envelope@_to@_add boolean false +.index ::Envelope-to:: header line +If this option is true, an ::Envelope-to:: header is added to the message. This +gives the original address(es) in the incoming envelope that caused this +delivery to happen. More than one address may be present if the transport is +configured to handle several addresses at once, or if more than one original +address was redirected to the same final address. As this is not a standard +header, Exim has a configuration option (\envelope@_to@_remove\) which requests +its removal from incoming messages, so that delivered messages can safely be +resent to other recipients. + +.conf group string$**$ "Exim group" +.index transport||group, specifying +This option specifies a gid for running the transport process, overriding any +value that the router supplies, and also overriding any value associated with +\user\ (see below). + +.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. + +.conf headers@_only boolean false +.index transport||header lines only +.index message||transporting headers only +.index header lines||transporting +If this option is set, the message's body is not transported. It is mutually +exclusive with \body@_only\. If it is used with the \%appendfile%\ or \%pipe%\ +transports, the settings of \message@_prefix\ and \message__suffix\ should be +checked, since this option does not automatically suppress them. + +.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 +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. + +.conf headers@_rewrite string unset +.index transport||header lines, rewriting +.index rewriting||at transport time +This option allows addresses in header lines to be rewritten at transport time, +that is, as the message is being copied to its destination. The contents of the +option are a colon-separated list of rewriting rules. Each rule is in exactly +the same form as one of the general rewriting rules that are applied when a +message is received. These are described in chapter ~~CHAPrewrite. For example, +.display asis +headers_rewrite = a@b c@d f : \ + x@y w@z +.endd +changes \a@@b\ into \c@@d\ in ::From:: header lines, and \x@@y\ into \w@@z\ in +all address-bearing header lines. The rules are applied to the header lines +just before they are written out at transport time, so they affect only those +copies of the message that pass through the transport. However, only the +message's original header lines, and any that were added by a system filter, +are rewritten. If a router or transport adds header lines, they are +not affected by this option. These rewriting rules are $it{not} applied to the +envelope. You can change the return path using \return@_path\, but you cannot +change envelope recipients at this time. + +.conf home@_directory string$**$ unset +.index transport||home directory for +This option specifies a home directory setting for the transport, overriding +any value that may be set by the router. The home directory is placed in +\$home$\ while expanding the transport's private options. It is also used as +the current directory if no current directory is set by the +\current__directory\ option on the transport or the +\transport__current__directory\ option on the router. +If the expansion fails for any reason, including forced failure, an error is +logged, and delivery is deferred. + + +.index additional groups +.index groups, additional +.index transport||group, additional +.conf initgroups boolean false +If this option is true and the uid for the delivery process is provided by the +transport, the \*initgroups()*\ function is called when running the transport +to ensure that any additional groups associated with the uid are set up. + +.conf message@_size@_limit string$**$ 0 +.index limit||message size per transport +.index size||of message, limit +.index transport||message size, limiting +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 +result is not of the required form, delivery is deferred. +If the value is greater than zero and the size of a message exceeds this +limit, the address is failed. If there is any chance that the resulting bounce +message could be routed to the same transport, you should ensure that +\return@_size@_limit\ is less than the transport's \message@_size@_limit\, as +otherwise the bounce message will fail to get delivered. + + +.conf rcpt@_include@_affixes boolean false +.index prefix||for local part, including in envelope +.index suffix||for local part, including in envelope +.index local part||prefix +.index local part||suffix +When this option is false (the default), and an address that has had any +affixes (prefixes or suffixes) removed from the local part is delivered by any +form of SMTP or LMTP, the affixes are not included. For example, if a router +that contains +.display asis +local_part_prefix = *- +.endd +routes the address \*abc-xyz@@some.domain*\ to an SMTP transport, the envelope +is delivered with +.display asis +RCPT TO:<xyz@some.domain> +.endd +If \rcpt@_include@_affixes\ is set true, the whole local part is included in +the \\RCPT\\ command. This option applies to BSMTP deliveries by the +\%appendfile%\ and \%pipe%\ transports as well as to the \%lmtp%\ and \%smtp%\ +transports. + +.conf retry@_use@_local@_part boolean "see below" +.index hints database||retry keys +When a delivery suffers a temporary failure, a retry record is created +in Exim's hints database. For remote deliveries, the key for the retry record +is based on the name and/or IP address of the failing remote host. For local +deliveries, the key is normally the entire address, including both the local +part and the domain. This is suitable for most common cases of local delivery +temporary failure -- for example, exceeding a mailbox quota should delay only +deliveries to that mailbox, not to the whole domain. + +However, in some special cases you may want to treat a temporary local delivery +as a failure associated with the domain, and not with a particular local part. +(For example, if you are storing all mail for some domain in files.) You can do +this by setting \retry@_use@_local@_part\ false. + +For all the local transports, its default value is true. For remote transports, +the default value is false for tidiness, but changing the value has no effect +on a remote transport in the current implementation. + +.conf return@_path string$**$ unset +.index envelope sender +.index transport||return path, changing +.index return path||changing in transport +If this option is set, the string is expanded at transport time and replaces +the existing return path (envelope sender) value in the copy of the message +that is being delivered. An empty return path is permitted. This feature is +designed for remote deliveries, where the value of this option is used in the +SMTP \\MAIL\\ command. If you set \return@_path\ for a local transport, the +only effect is to change the address that is placed in the ::Return-path:: +header line, if one is added to the message (see the next option). + +The expansion can refer to the existing value via \$return@_path$\. This is +either the message's envelope sender, or an address set by the +\errors@_to\ option on a router. If the expansion is forced to fail, no +replacement occurs; if it fails for another reason, delivery is deferred. This +option can be used to support VERP (Variable Envelope Return Paths) -- see +chapter ~~CHAPSMTP. + +\**Note**\: If a delivery error is detected locally, +.em +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 +.index ::Return-path:: header line +If this option is true, a ::Return-path:: header is added to the message. +Although the return path is normally available in the prefix line of BSD +mailboxes, this is commonly not displayed by MUAs, and so the user does not +have easy access to it. + +RFC 2821 states that the ::Return-path:: header is added to a message `when the +delivery SMTP server makes the final delivery'. This implies that this header +should not be present in incoming messages. Exim has a configuration option, +\return@_path@_remove\, which requests removal of this header from incoming +messages, so that delivered messages can safely be resent to other recipients. + +.conf shadow@_condition string$**$ unset +See \shadow@_transport\ below. + +.conf shadow@_transport string unset +.index shadow transport +.index transport||shadow +A local transport may set the \shadow@_transport\ option to the name of another +local transport. Shadow remote transports are not supported. + +Whenever a delivery to the main transport succeeds, and either +\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 +failures cause a log line to be written. + +The result of the shadow transport is discarded and does not affect the +subsequent processing of the message. Only a single level of shadowing is +provided; the \shadow@_transport\ option is ignored on any transport when it is +running as a shadow. Options concerned with output from pipes are also ignored. + +The log line for the successful delivery has an item added on the end, of the +form +.display +ST=<<shadow transport name>> +.endd +If the shadow transport did not succeed, the error message is put in +parentheses afterwards. + +Shadow transports can be used for a number of different purposes, including +keeping more detailed log information than Exim normally provides, and +implementing automatic acknowledgement policies based on message headers that +some sites insist on. + +.conf transport@_filter string$**$ unset +.index transport||filter +.index filter||transport filter +This option sets up a filtering (in the Unix shell sense) process for messages +at transport time. It should not be confused with mail filtering as set up by +individual users or via a system filter. + +When the message is about to be written out, the command specified by +\transport@_filter\ is started up in a separate process, and the entire +message, including the header lines, is passed to it on its standard input +(this in fact is done from a third process, to avoid deadlock). +The command must be specified as an absolute path. + +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. +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 +show the possibilities. Exim does not check the result, except to test for a +final newline when SMTP is in use. All messages transmitted over SMTP must end +with a newline, so Exim supplies one if it is missing. + +.index SMTP||\\SIZE\\ +A problem might arise if the filter increases the size of a message that is +being sent down an SMTP connection. If the receiving SMTP server has indicated +support for the \\SIZE\\ parameter, Exim will have sent the size of the message +at the start of the SMTP session. If what is actually sent is substantially +more, the server might reject the message. This can be worked round by setting +the \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.) + +.index \$host$\ +.index \$host@_address$\ +The expansion variables \$host$\ and \$host@_address$\ are available when the +transport is a remote one. They contain the name and IP address of the host to +which the message is being sent. For example: +.display asis +transport_filter = /some/directory/transport-filter.pl \ + $host $host_address $sender_address $pipe_addresses +.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. + +If a transport filter is set on an autoreply transport, the original message is +passed through the filter as it is being copied into the newly generated +message, which happens if the \return@_message\ option is set. + +.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 +temporary delivery failure. + + +.conf user string$**$ "Exim user" +.index uid (user id)||local delivery +.index transport||user, specifying +This option specifies the user under whose uid the delivery process is to be +run, overriding any uid that may have been set by the router. If the user is +given as a name, the uid is looked up from the password data, and the +associated group is taken as the value of the gid to be used if the \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 +sure you know what you are doing. When a remote transport is running, it needs +to be able to access Exim's hints databases, because each host may have its own +retry data. + +.endconf + + + + + +. +. +. +. ============================================================================ +.chapter Address batching in local transports +.set runningfoot "address batching" +.rset CHAPbatching ~~chapter +.index transport||local, address batching in +The only remote transport (\%smtp%\) is normally configured to handle more than +one address at a time, so that when several addresses are routed to the same +remote host, just one copy of the message is sent. Local transports, however, +normally handle one address at a time. That is, a separate instance of the +transport is run for each address that is routed to the transport. A separate +copy of the message is delivered each time. + +.index batched local delivery +.index \batch@_max\ +.index \batch@_id\ +In special cases, it may be desirable to handle several addresses at once in a +local transport, for example: +.numberpars $. +In an \%appendfile%\ transport, when storing messages in files for later +delivery by some other means, a single copy of the message with multiple +recipients saves space. +.nextp +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 +to some other delivery mechanism such as UUCP, multiple recipients may be +acceptable. +.endp +The three local transports (\%appendfile%\, \%lmtp%\, and \%pipe%\) all have +the same options for controlling multiple (`batched') deliveries, namely +\batch@_max\ and \batch@_id\. To save repeating the information for each +transport, these options are described here. + +The \batch@_max\ option specifies the maximum number of addresses that can be +delivered together in a single run of the transport. Its default value is one. +When more than one address is routed to a transport that has a \batch@_max\ +value greater than one, the addresses are delivered in a batch (that is, in a +single run of the transport), subject to certain conditions: +.numberpars $. +If any of the transport's options contain a reference to \$local@_part$\, no +batching is possible. +.nextp +If any of the transport's options contain a reference to \$domain$\, only +addresses with the same domain are batched. +.nextp +.index customizing||batching condition +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. +.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 +group for the transport, and if a host list is present, the first host must +be the same. +.endp +.index ::Envelope-to:: header line +If the generic \envelope@_to@_add\ option is set for the transport, the +::Envelope-to:: header that is added to the message contains all the addresses +that are batched together. + +The \%appendfile%\ and \%pipe%\ transports have an option called \use@_bsmtp\, +which causes them to deliver the message in `batched SMTP' format, with the +envelope represented as SMTP commands. The \check@_string\ and \escape@_string\ +options are forced to the values +.display asis +check_string = "." +escape_string = ".." +.endd +when batched SMTP is in use. A full description of the batch SMTP mechanism is +given in section ~~SECTbatchSMTP. The \%lmtp%\ transport does not have a +\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 +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, +containing all the recipients. + + + +. +. +. +. ============================================================================ +.chapter The appendfile transport +.set runningfoot "appendfile transport" +.rset CHAPappendfile ~~chapter +.index \%appendfile%\ transport +.index transports||\%appendfile%\ +.index directory creation +.index creating directories +The \%appendfile%\ transport delivers a message by appending it to an existing +file, or by creating an entirely new file in a specified directory. Single +files to which messages are appended can be in the traditional Unix mailbox +format, or optionally in the MBX format supported by the Pine MUA and +University of Washington IMAP daemon, $it{inter alia}. When each message is +being delivered as a separate file, `maildir' format can optionally be used to +give added protection against failures that happen part-way through the +delivery. A third form of separate-file delivery known as `mailstore' is also +supported. For all file formats, Exim attempts to create as many levels of +directory as necessary, provided that \create@_directory\ is set. + +The code for the optional formats is not included in the Exim binary by +default. It is necessary to set \\SUPPORT@_MBX\\, \\SUPPORT@_MAILDIR\\ and/or +\\SUPPORT@_MAILSTORE\\ in \(Local/Makefile)\ to have the appropriate code +included. + +.index quota||system +Exim recognises system quota errors, and generates an appropriate message. Exim +also supports its own quota control within the transport, for use when the +system facility is unavailable or cannot be used for some reason. + +If there is an error while appending to a file (for example, quota exceeded or +partition filled), Exim attempts to reset the file's length and last +modification time back to what they were before. If there is an error while +creating an entirely new file, the new file is removed. + +Before appending to a file, a number of security checks are made, and the +file is locked. A detailed description is given below, after the list of +private options. + +\%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). + + +.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 message is created. Only one of these two options can be set, and for +normal deliveries to mailboxes, one of them \*must*\ be set. + +However, \%appendfile%\ is also used for delivering messages to files or +directories whose names (or parts of names) are obtained from alias, +forwarding, or filtering operations (for example, a \save\ command in a user's +Exim filter). When such a transport is running, \$local@_part$\ contains the +local part that was aliased or forwarded, and \$address@_file$\ contains the +name (or partial name) of the file or directory generated by the redirection +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 +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 +\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. +.endp + +.index Sieve filter||configuring \%appendfile%\ +.index Sieve filter||relative mailbox path handling +As an example of the second case, consider an environment where users do not +have home directories. They may be permitted to use Exim filter commands of the +form: +.display asis +save folder23 +.endd +or Sieve filter commands of the form: +.display asis +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 +of handling this requirement: +.display asis +file = ${if eq{$address_file}{inbox} \ + {/var/mail/$local_part} \ + {${if eq{${substr_0_1:$address_file}}{/} \ + {$address_file} \ + {$home/mail/$address_file} \ + }} \ + } +.endd +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. + +\**Note 1**\: While processing an Exim filter, a relative path such as +\(folder23)\ is turned into an absolute path if a home directory is known to +the router. In particular, this is the case if \check@_local@_user\ is set. If +you want to prevent this happening at routing time, you can set +\router@_home@_directory\ empty. This forces the router to pass the relative +path to the transport. + +\**Note 2**\: An absolute path in \$address@_file$\ is not treated specially; +the \file\ or \directory\ option is still used if it is set. + + + +.section Private options for appendfile +.index options||\%appendfile%\ transport + +.startconf + +.conf allow@_fifo boolean false +.index fifo (named pipe) +.index named pipe (fifo) +.index pipe||named (fifo) +Setting this option permits delivery to named pipes (FIFOs) as well as to +regular files. If no process is reading the named pipe at delivery time, the +delivery is deferred. + +.conf allow@_symlink boolean false +.index symbolic link||to mailbox +.index mailbox||symbolic link +By default, \%appendfile%\ will not deliver if the path name for the file is +that of a symbolic link. Setting this option relaxes that constraint, but there +are security issues involved in the use of symbolic links. Be sure you know +what you are doing if you set this. Details of exactly what this option affects +are included in the discussion which follows this list of options. + +.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 +file. + +.conf batch@_max integer 1 +See the description of local delivery batching in chapter ~~CHAPbatching. + +.conf check@_group boolean false +When this option is set, the group owner of the file defined by the \file\ +option is checked to see that it is the same as the group under which the +delivery process is running. The default setting is false because the default +file mode is 0600, which means that the group is irrelevant. + +.conf check@_owner boolean true +When this option is set, the owner of the file defined by the \file\ option is +checked to ensure that it is the same as the user under which the delivery +process is running. + +.conf check@_string string "see below" +.index `From' line +As \%appendfile%\ writes the message, the start of each line is tested for +matching \check@_string\, and if it does, the initial matching characters are +replaced by the contents of \escape@_string\. The value of \check@_string\ is a +literal string, not a regular expression, and the case of any letters it +contains is significant. + +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 +any of the \directory\, \maildir\, or \mailstore\ options are set. + +The default settings, along with \message@_prefix\ and \message@_suffix\, are +suitable for traditional `BSD' mailboxes, where a line beginning with `From ' +indicates the start of a new message. All four options need changing if another +format is used. For example, to deliver to mailboxes in MMDF format: +.index MMDF format mailbox +.index mailbox||MMDF format +.display asis +check_string = "\1\1\1\1\n" +escape_string = "\1\1\1\1 \n" +message_prefix = "\1\1\1\1\n" +message_suffix = "\1\1\1\1\n" +.endd + +.index directory creation +.conf create@_directory boolean true +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. + +.conf create@_file string "anywhere" +This option constrains the location of files and directories that are created +by this transport. It applies to files defined by the \file\ option and +directories defined by the \directory\ option. In the case of maildir delivery, +it applies to the top level directory, not the maildir directories beneath. + +The option must be set to one of the words `anywhere', `inhome', or +`belowhome'. In the second and third cases, a home directory must have been set +for the transport. This option is not useful when an explicit file name is +given for normal mailbox deliveries. It is intended for the case when file +names are generated from users' \(.forward)\ files. These are usually handled +by an \%appendfile%\ transport called \address@_file\. See also +\file@_must@_exist\. + +.conf directory string$**$ unset +This option is mutually exclusive with the \file\ option, but one of \file\ or +\directory\ must be set, unless the delivery is the direct result of a +redirection (see section ~~SECTfildiropt). + +When \directory\ is set, the string is expanded, and the message is delivered +into a new file or files in or below the given directory, instead of being +appended to a single mailbox file. A number of different formats are provided +(see \maildir@_format\ and \mailstore@_format\), and see section ~~SECTopdir +for further details of this form of delivery. + +.conf directory@_file string$**$ "$tt{q@$@{base62:@$tod@_epoch@}-@$inode}" +.index base62 +When \directory\ is set, but neither \maildir@_format\ nor \mailstore@_format\ +is set, \%appendfile%\ delivers each message into a file whose name is obtained +by expanding this string. The default value generates a unique name from the +current time, in base 62 form, and the inode of the file. The variable +\$inode$\ is available only when expanding this option. + +.conf directory@_mode "octal integer" 0700 +If \%appendfile%\ creates any directories as a result of the \create@_directory\ +option, their mode is specified by this option. + +.conf escape@_string string "see description" +See \check@_string\ above. + +.conf file string$**$ unset +This option is mutually exclusive with the \directory\ option, but one of +\file\ or \directory\ must be set, unless the delivery is the direct result of +a redirection (see section ~~SECTfildiropt). The \file\ option specifies a +single file, to which the message is appended. One or more of +\use@_fcntl@_lock\, \use@_flock@_lock\, or \use@_lockfile\ must be set with +\file\. +.index NFS||lock file +.index locking files +.index lock files +If you are using more than one host to deliver over NFS into the same +mailboxes, you should always use lock files. + +The string value is expanded for each delivery, and must yield an absolute +path. The most common settings of this option are variations on one of these +examples: +.display asis +file = /var/spool/mail/$local_part +file = /home/$local_part/inbox +file = $home/inbox +.endd +.index `sticky' bit +In the first example, all deliveries are done into the same directory. If Exim +is configured to use lock files (see \use@_lockfile\ below) it must be able to +create a file in the directory, so the `sticky' bit must be turned on for +deliveries to be possible, or alternatively the \group\ option can be used to +run the delivery under a group id which has write access to the directory. + + +.conf file@_format string unset +.index file||mailbox, checking existing format +This option requests the transport to check the format of an existing file +before adding to it. The check consists of matching a specific string at the +start of the file. The value of the option consists of an even number of +colon-separated strings. The first of each pair is the test string, and the +second is the name of a transport. If the transport associated with a matched +string is not the current transport, control is passed over to the other +transport. For example, suppose the standard \%local@_delivery%\ transport has +this added to it: +.display asis +file_format = "From : local_delivery :\ + \1\1\1\1\n : local_mmdf_delivery" +.endd +Mailboxes that begin with `From' are still handled by this transport, but if a +mailbox begins with four binary ones followed by a newline, control is passed +to a transport called \local__mmdf__delivery\, which presumably is configured +to do the delivery in MMDF format. If a mailbox does not exist or is empty, it +is assumed to match the current transport. If the start of a mailbox doesn't +match any string, or if the transport named for a given string is not defined, +delivery is deferred. + +.conf file@_must@_exist boolean false +If this option is true, the file specified by the \file\ option must exist, and +an error occurs if it does not. Otherwise, it is created if it does not exist. + +.conf lock@_fcntl@_timeout time 0s +.index timeout||mailbox locking +.index mailbox locking||blocking and non-blocking +.index locking files +By default, the \%appendfile%\ transport uses non-blocking calls to \*fcntl()*\ +when locking an open mailbox file. If the call fails, the delivery process +sleeps for \lock@_interval\ and tries again, up to \lock@_retries\ times. +Non-blocking calls are used so that the file is not kept open during the wait +for the lock; the reason for this is to make it as safe as possible for +deliveries over NFS in the case when processes might be accessing an NFS +mailbox without using a lock file. This should not be done, but +misunderstandings and hence misconfigurations are not unknown. + +On a busy system, however, the performance of a non-blocking lock approach is +not as good as using a blocking lock with a timeout. In this case, the waiting +is done inside the system call, and Exim's delivery process acquires the lock +and can proceed as soon as the previous lock holder releases it. + +If \lock@_fcntl@_timeout\ is set to a non-zero time, blocking locks, with that +timeout, are used. There may still be some retrying: the maximum number of +retries is +.display asis +(lock_retries * lock_interval) / lock_fcntl_timeout +.endd +rounded up to the next whole number. In other words, the total time during +which \%appendfile%\ is trying to get a lock is roughly the same, unless +\lock@_fcntl@_timeout\ is set very large. + +You should consider setting this option if you are getting a lot of delayed +local deliveries because of errors of the form +.display asis +failed to lock mailbox /some/file (fcntl) +.endd + +.conf lock@_flock@_timeout time 0s +This timeout applies to file locking when using \*flock()*\ (see \use@_flock\); +the timeout operates in a similar manner to \lock@_fcntl@_timeout\. + +.conf lock@_interval time 3s +This specifies the time to wait between attempts to lock the file. See below +for details of locking. + +.conf lock@_retries integer 10 +This specifies the maximum number of attempts to lock the file. A value of zero +is treated as 1. See below for details of locking. + +.conf lockfile@_mode "octal integer" 0600 +This specifies the mode of the created lock file, when a lock file is being +used (see \use@_lockfile\). + +.conf lockfile@_timeout time 30m +.index timeout||mailbox locking +When a lock file is being used (see \use@_lockfile\), if a lock file already +exists and is older than this value, it is assumed to have been left behind by +accident, and Exim attempts to remove it. + +.conf maildir@_format boolean false +.index maildir format||specifying +If this option is set with the \directory\ option, the delivery is into a new +file, in the `maildir' format that is used by other mail software. When the +transport is activated directly from a \%redirect%\ router (for example, the +\%address@_file%\ transport in the default configuration), setting +\maildir@_format\ causes the path received from the router to be treated as a +directory, whether or not it ends with \"/"\. This option is available only if +\\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 +This option is relevant only when \maildir@_use@_size@_file\ is set. It defines +a regular expression for specifying directories that should be included in the +quota calculation. The default value is +.display asis +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 +\(Trash)\ +folder from the count (as some sites do), you need to change this setting to +.display asis +maildir_quota_directory_regex = ^(?:cur|new|\.(?!Trash).*)$ +.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 +`maildir' format. See section ~~SECTmaildirdelivery below. + +.conf maildir@_tag string$**$ unset +This option applies only to deliveries in maildir format, and is described in +section ~~SECTmaildirdelivery below. + +.conf maildir@_use@_size@_file boolean false +.index maildir format||\(maildirsize)\ file +Setting this option true enables support for \(maildirsize)\ files. Exim +creates a \(maildirsize)\ file in a maildir if one does not exist, taking the +quota from the \quota\ option of the transport. If \quota\ is unset, the value +is zero. See section ~~SECTmaildirdelivery below for further details. + +.conf mailstore@_format boolean false +.index mailstore format||specifying +If this option is set with the \directory\ option, the delivery is into two new +files in `mailstore' format. The option is available only if +\\SUPPORT@_MAILSTORE\\ is present in \(Local/Makefile)\. See section +~~SECTopdir below for further details. + +.conf mailstore@_prefix string$**$ unset +This option applies only to deliveries in mailstore format, and is described in +section ~~SECTopdir below. + +.conf mailstore@_suffix string$**$ unset +This option applies only to deliveries in mailstore format, and is described in +section ~~SECTopdir below. + +.conf mbx@_format boolean false +.index locking files +.index file||locking +.index file||MBX format +.index MBX format, specifying +This option is available only if Exim has been compiled with \\SUPPORT@_MBX\\ +set in \(Local/Makefile)\. If \mbx@_format\ is set with the \file\ option, +the message is appended to the mailbox file in MBX format instead of +traditional Unix format. This format is supported by Pine4 and its associated +IMAP and POP daemons, by means of the \*c-client*\ library that they all use. + +\**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 +combination: +.display asis +mbx_format = true +message_prefix = +message_suffix = +.endd + +If none of the locking options are mentioned in the configuration, +\use@_mbx@_lock\ is assumed and the other locking options default to false. It +is possible to specify the other kinds of locking with \mbx@_format\, but +\use@_fcntl@_lock\ and \use@_mbx@_lock\ are mutually exclusive. MBX locking +interworks with \*c-client*\, providing for shared access to the mailbox. It +should not be used if any program that does not use this form of locking is +going to access the mailbox, nor should it be used if the mailbox file is NFS +mounted, because it works only when the mailbox is accessed from a single host. + +If you set \use@_fcntl@_lock\ with an MBX-format mailbox, you cannot use +the standard version of \*c-client*\, because as long as it has a mailbox open +(this means for the whole of a Pine or IMAP session), Exim will not be able to +append messages to it. + +.conf message@_prefix string$**$ "see below" +.index `From' line +The string specified here is expanded and output at the start of every message. +The default is unset unless \file\ is specified and \use@_bsmtp\ is not set, in +which case it is: +.display asis +message_prefix = "From ${if def:return_path{$return_path}\ + {MAILER-DAEMON}} $tod_bsdinbox\n" +.endd + +.conf message@_suffix string$**$ "see below" +The string specified here is expanded and output at the end of every message. +The default is unset unless \file\ is specified and \use@_bsmtp\ is not set, in +which case it is a single newline character. The suffix can be suppressed by +setting +.display asis +message_suffix = +.endd + +.conf mode "octal integer" 0600 +If the output file is created, it is given this mode. If it already exists and +has wider permissions, they are reduced to this mode. If it has narrower +permissions, an error occurs unless \mode__fail__narrower\ is false. However, +if the delivery is the result of a \save\ command in a filter file specifing a +particular mode, the mode of the output file is always forced to take that +value, and this option is ignored. + +.conf mode@_fail@_narrower boolean true +This option applies in the case when an existing mailbox file has a narrower +mode than that specified by the \mode\ option. If \mode@_fail@_narrower\ is +true, the delivery is deferred (`mailbox has the wrong mode'); otherwise Exim +continues with the delivery attempt, using the existing mode of the file. + +.conf notify@_comsat boolean false +If this option is true, the \*comsat*\ daemon is notified after every successful +delivery to a user mailbox. This is the daemon that notifies logged on users +about incoming mail. + +.conf quota string$**$ unset +.index quota||imposed by Exim +This option imposes a limit on the size of the file to which Exim is appending, +or to the total space used in the directory tree when the \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 +(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. +If the sizes of a number of files are being added up, the rounding effect can +become quite noticeable, especially on systems that have large block sizes. +Nevertheless, it seems best to stick to the \*used*\ figure, because this is +the obvious value which users understand most easily. + +The value of the option is expanded, and must then be a numerical value +(decimal point allowed), optionally followed by one of the letters K or M. The +expansion happens while Exim is running as root, before it changes uid for the +delivery. This means that files which are inaccessible to the end user can be +used to hold quota values that are looked up in the expansion. When delivery +fails because this quota is exceeded, the handling of the error is as for +system quota failures. + +.em +\**Note**\: A value of zero is interpreted as `no quota'. +.nem + +By default, Exim's quota checking mimics system quotas, and restricts the +mailbox to the specified maximum size, though the value is not accurate to the +last byte, owing to separator lines and additional headers that may get added +during message delivery. When a mailbox is nearly full, large messages may get +refused even though small ones are accepted, because the size of the current +message is added to the quota when the check is made. This behaviour can be +changed by setting \quota@_is@_inclusive\ false. When this is done, the check +for exceeding the quota does not include the current message. Thus, deliveries +continue until the quota has been exceeded; thereafter, no further messages are +delivered. See also \quota@_warn@_threshold\. + +.conf quota@_directory string$**$ unset +This option defines the directory to check for quota purposes when delivering +into individual files. The default is the delivery directory, or, if a file +called \(maildirfolder)\ exists in a maildir directory, the parent of the +delivery directory. + +.conf quota@_filecount string$**$ 0 +This option applies when the \directory\ option is set. It limits the total +number of files in the directory (compare the inode limit in system quotas). It +can only be used if \quota\ is also set. The value is expanded; an expansion +failure causes delivery to be deferred. + +.conf quota@_is@_inclusive boolean true +See \quota\ above. + +.conf quota@_size@_regex string unset +This option applies when one of the delivery modes that writes a separate file +for each message is being used. When Exim wants to find the size of one of +these files in order to test the quota, it first checks \quota@_size@_regex\. +If this is set to a regular expression that matches the file name, and it +captures one string, that string is interpreted as a representation of the +file's size. The value of \quota@_size@_regex\ is not expanded. + +This feature is useful only when users have no shell access to their mailboxes +-- otherwise they could defeat the quota simply by renaming the files. This +facility can be used with maildir deliveries, by setting \maildir@_tag\ to add +the file length to the file name. For example: +.display asis +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 +sometimes add other information onto the ends of message file names. + +.conf quota@_warn@_message string$**$ "see below" +See below for the use of this option. If it is not set when +\quota@_warn@_threshold\ is set, it defaults to +.display asis +quota_warn_message = "\ + To: $local_part@$domain\n\ + Subject: Your mailbox\n\n\ + This message is automatically created \ + by mail delivery software.\n\n\ + The size of your mailbox has exceeded \ + a warning threshold that is\n\ + set by the system administrator.\n" +.endd + +.conf quota@_warn@_threshold string$**$ 0 +.index quota||warning threshold +.index mailbox||size warning +.index size||of mailbox +This option is expanded in the same way as \quota\ (see above). If the +resulting value is greater than zero, and delivery of the message causes the +size of the file or total space in the directory tree to cross the given +threshold, a warning message is sent. If \quota\ is also set, the threshold may +be specified as a percentage of it by following the value with a percent sign. +For example: +.display asis +quota = 10M +quota_warn_threshold = 75% +.endd +If \quota\ is not set, a setting of \quota@_warn@_threshold\ that ends with a +percent sign is ignored. + +The warning message itself is specified by the \quota@_warn@_message\ option, +and it must start with a ::To:: header line containing the recipient(s). A +::Subject:: line should also normally be supplied. The \quota\ option does not +have to be set in order to use this option; they are independent of one +another except when the threshold is specified as a percentage. + +.conf use@_bsmtp boolean false +.index envelope sender +If this option is set true, \%appendfile%\ writes messages in `batch SMTP' +format, with the envelope sender and recipient(s) included as SMTP commands. If +you want to include a leading \\HELO\\ command with such messages, you can do +so by setting the \message@_prefix\ option. See section ~~SECTbatchSMTP for +details of batch SMTP. + +.conf use@_crlf boolean false +.index carriage return +.index linefeed +This option causes lines to be terminated with the two-character CRLF sequence +(carriage return, linefeed) instead of just a linefeed character. In the case +of batched SMTP, the byte sequence written to the file is then an exact image +of what would be sent down a real SMTP connection. + +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 +must +be changed to end with \"@\r@\n"\ if \use@_crlf\ is set. + +.conf use@_fcntl@_lock boolean "see below" +This option controls the use of the \*fcntl()*\ function to lock a file for +exclusive use when a message is being appended. It is set by default unless +\use@_flock@_lock\ is set. Otherwise, it should be turned off only if you know +that all your MUAs use lock file locking. When both \use@_fcntl@_lock\ and +\use@_flock@_lock\ are unset, \use@_lockfile\ must be set. + +.conf use@_flock@_lock boolean false +This option is provided to support the use of \*flock()*\ for file locking, for +the few situations where it is needed. Most modern operating systems support +\*fcntl()*\ and \*lockf()*\ locking, and these two functions interwork with +each other. Exim uses \*fcntl()*\ locking by default. + +This option is required only if you are using an operating system where +\*flock()*\ is used by programs that access mailboxes (typically MUAs), and +where \*flock()*\ does not correctly interwork with \*fcntl()*\. You can use +both \*fcntl()*\ and \*flock()*\ locking simultaneously if you want. + +.index Solaris||\*flock()*\ support +Not all operating systems provide \*flock()*\. Some versions of Solaris do not +have it (and some, I think, provide a not quite right version built on top of +\*lockf()*\). If the OS does not have \*flock()*\, Exim will be built without +the ability to use it, and any attempt to do so will cause a configuration +error. + +\**Warning**\: \*flock()*\ locks do not work on NFS files (unless \*flock()*\ +is just being mapped onto \*fcntl()*\ by the OS). + +.conf use@_lockfile boolean "see below" +If this option is turned off, Exim does not attempt to create a lock file when +appending to a mailbox file. In this situation, the only locking is by +\*fcntl()*\. You should only turn \use@_lockfile\ off if you are absolutely +sure that every MUA that is ever going to look at your users' mailboxes uses +\*fcntl()*\ rather than a lock file, and even then only when you are not +delivering over NFS from more than one host. + +.index NFS||lock file +In order to append to an NFS file safely from more than one host, it is +necessary to take out a lock $it{before} opening the file, and the lock file +achieves this. Otherwise, even with \*fcntl()*\ locking, there is a risk of +file corruption. + +The \use@_lockfile\ option is set by default unless \use@_mbx@_lock\ is set. It +is not possible to turn both \use@_lockfile\ and \use@_fcntl@_lock\ off, except +when \mbx@_format\ is set. + +.conf use@_mbx@_lock boolean "see below" +This option is available only if Exim has been compiled with \\SUPPORT@_MBX\\ +set in \(Local/Makefile)\. Setting the option specifies that special MBX +locking rules be used. It is set by default if \mbx@_format\ is set and none of +the locking options are mentioned in the configuration. The locking rules are +the same as are used by the \*c-client*\ library that underlies Pine and the +IMAP4 and POP daemons that come with it (see the discussion below). The rules +allow for shared access to the mailbox. However, this kind of locking does not +work when the mailbox is NFS mounted. + +You can set \use@_mbx@_lock\ with either (or both) of \use@_fcntl@_lock\ and +\use@_flock@_lock\ to control what kind of locking is used in implementing the +MBX locking rules. The default is to use \*fcntl()*\ if \use@_mbx@_lock\ is set +without \use@_fcntl@_lock\ or \use@_flock@_lock\. +.endconf + + +.section Operational details for appending +.rset SECTopappend "~~chapter.~~section" +.index appending to a file +.index file||appending +Before appending to a file, the following preparations are made: +.numberpars $. +If the name of the file is \(/dev/null)\, no action is taken, and a success +return is given. +.nextp +.index directory creation +If any directories on the file's path are missing, Exim creates them if the +\create@_directory\ option is set. A created directory's mode is given by the +\directory@_mode\ option. +.nextp +If \file@_format\ is set, the format of an existing file is checked. If this +indicates that a different transport should be used, control is passed to that +transport. +.nextp +.index file||locking +.index locking files +.index NFS||lock file +If \use@_lockfile\ is set, a lock file is built in a way that will work +reliably over NFS, as follows: +.numberpars $. +Create a `hitching post' file whose name is that of the lock file with the +current time, primary host name, and process id added, by opening for writing +as a new file. If this fails with an access error, delivery is deferred. +.nextp +Close the hitching post file, and hard link it to the lock file name. +.nextp +If the call to \*link()*\ succeeds, creation of the lock file has succeeded. +Unlink the hitching post name. +.nextp +Otherwise, use \*stat()*\ to get information about the hitching post file, and +then unlink hitching post name. If the number of links is exactly two, creation +of the lock file succeeded but something (for example, an NFS server crash and +restart) caused this fact not to be communicated to the \*link()*\ call. +.nextp +If creation of the lock file failed, wait for \lock@_interval\ and try again, +up to \lock@_retries\ times. However, since any program that writes to a +mailbox should complete its task very quickly, it is reasonable to time out old +lock files that are normally the result of user agent and system crashes. If an +existing lock file is older than \lockfile@_timeout\ Exim attempts to unlink it +before trying again. +.endp +.nextp +A call is made to \*lstat()*\ to discover whether the main file exists, and if +so, what its characteristics are. If \*lstat()*\ fails for any reason other +than non-existence, delivery is deferred. +.nextp +.index symbolic link||to mailbox +.index mailbox||symbolic link +If the file does exist and is a symbolic link, delivery is deferred, unless the +\allow@_symlink\ option is set, in which case the ownership of the link is +checked, and then \*stat()*\ is called to find out about the real file, which +is then subjected to the checks below. The check on the top-level link +ownership prevents one user creating a link for another's mailbox in a sticky +directory, though allowing symbolic links in this case is definitely not a good +idea. If there is a chain of symbolic links, the intermediate ones are not +checked. +.nextp +If the file already exists but is not a regular file, or if the file's owner +and group (if the group is being checked -- see \check@_group\ above) are +different from the user and group under which the delivery is running, +delivery is deferred. +.nextp +If the file's permissions are more generous than specified, they are reduced. +If they are insufficient, delivery is deferred, unless \mode@_fail@_narrower\ +is set false, in which case the delivery is tried using the existing +permissions. +.nextp +The file's inode number is saved, and the file is then opened for appending. If +this fails because the file has vanished, \%appendfile%\ behaves as if it hadn't +existed (see below). For any other failures, delivery is deferred. +.nextp +If the file is opened successfully, check that the inode number hasn't +changed, that it is still a regular file, and that the owner and permissions +have not changed. If anything is wrong, defer delivery and freeze the message. +.nextp +If the file did not exist originally, defer delivery if the \file@_must@_exist\ +option is set. Otherwise, check that the file is being created in a permitted +directory if the \create@_file\ option is set (deferring on failure), and then +open for writing as a new file, with the \\O@_EXCL\\ and \\O@_CREAT\\ options, +except when dealing with a symbolic link (the \allow@_symlink\ option must be +set). In this case, which can happen if the link points to a non-existent file, +the file is opened for writing using \\O@_CREAT\\ but not \\O@_EXCL\\, because +that prevents link following. +.nextp +.index loop||while file testing +If opening fails because the file exists, obey the tests given above for +existing files. However, to avoid looping in a situation where the file is +being continuously created and destroyed, the exists/not-exists loop is broken +after 10 repetitions, and the message is then frozen. +.nextp +If opening fails with any other error, defer delivery. +.nextp +.index file||locking +.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. +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 +.display +/tmp/.<<device-number>>.<<inode-number>> +.endd +using the device and inode numbers of the open mailbox file, in accordance with +the MBX locking rules. + +If Exim fails to lock the file, there are two possible courses of action, +depending on the value of the locking timeout. This is obtained from +\lock@_fcntl@_timeout\ or \lock@_flock@_timeout\, as appropriate. + +If the timeout value is zero, the file is closed, Exim waits for +\lock@_interval\, and then goes back and re-opens the file as above and tries +to lock it again. This happens up to \lock@_retries\ times, after which the +delivery is deferred. + +If the timeout has a value greater than zero, blocking calls to \*fcntl()*\ or +\*flock()*\ are used (with the given timeout), so there has already been some +waiting involved by the time locking fails. Nevertheless, Exim does not give up +immediately. It retries up to +.display +(lock@_retries * lock@_interval) / <<timeout>> +.endd +times (rounded up). +.endp + +At the end of delivery, Exim closes the file (which releases the \*fcntl()*\ +and/or \*flock()*\ locks) and then deletes the lock file if one was created. + +.section Operational details for delivery to a new file +.rset SECTopdir "~~chapter.~~section" +.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 +\maildir@_format\ or \mailstore@_format\ option is set. + +No locking is required while writing the message to a new file, so the various +locking options of the transport are ignored. The `From' line that by default +separates messages in a single file is not normally needed, nor is the escaping +of message lines that start with `From', and there is no need to ensure a +newline at the end of each message. Consequently, the default values for +\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 +(see below) the \(maildirfolder)\ convention is honoured. + + +.index maildir format +.index mailstore format +There are three different ways in which delivery to individual files can be +done, controlled by the settings of the \maildir@_format\ and +\mailstore@_format\ options. Note that code to support maildir or mailstore +formats is not included in the binary unless \\SUPPORT@_MAILDIR\\ or +\\SUPPORT@_MAILSTORE\\, respectively, is set in \(Local/Makefile)\. + +.index directory creation +In all three cases an attempt is made to create the directory and any necessary +sub-directories if they do not exist, provided that the \create@_directory\ +option is set (the default). The location of a created directory can be +constrained by setting \create@_file\. A created directory's mode is given by +the \directory@_mode\ option. If creation fails, or if the \create@_directory\ +option is not set when creation is required, delivery is deferred. + + +.section Maildir delivery +.rset SECTmaildirdelivery "~~chapter.~~section" +.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 +\(new)\ subdirectory. + +In the file name, <<stime>> is the current time of day in seconds, and +<<mtime>> is the microsecond fraction of the time. After a maildir delivery, +Exim checks that the time-of-day clock has moved on by at least one microsecond +before terminating the delivery process. This guarantees uniqueness for the +file name. However, as a precaution, Exim calls \*stat()*\ for the file before +opening it. If any response other than \\ENOENT\\ (does not exist) is given, +Exim waits 2 seconds and tries again, up to \maildir@_retries\ times. + +.index quota||in maildir delivery +.index maildir++ +If Exim is required to check a \quota\ setting before a maildir delivery, and +\quota@_directory\ is not set, it looks for a file called \(maildirfolder)\ in +the maildir directory (alongside \(new)\, \(cur)\, \(tmp)\). If this exists, +Exim assumes the directory is a maildir++ folder directory, which is one level +down from the user's top level mailbox directory. This causes it to start at +the parent directory instead of the current directory when calculating the +amount of space used. + + +.section Using tags to record message sizes +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. + +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\ +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 +be deferred. The expanded tag may contain any printing characters except `/'. +Non-printing characters in the string are ignored; if the resulting string is +empty, it is ignored. If it starts with an alphanumeric character, a leading +colon is inserted. + + +.em +.section Using a maildirsize file +.index quota||in maildir delivery +.index maildir format||\(maildirsize)\ file +If \maildir@_use@_size@_file\ is true, Exim implements the maildir++ rules for +storing quota and message size information in a file called \(maildirsize)\ +within the maildir directory. If this file does not exist, Exim creates it, +setting the quota from the \quota\ option of the transport. If the maildir +directory itself does not exist, it is created before any attempt to write a +\(maildirsize)\ file. + +The \(maildirsize)\ file is used to hold information about the sizes of +messages in the maildir, thus speeding up quota calculations. The quota value +in the file is just a cache; if the quota is changed in the transport, the new +value overrides the cached value when the next message is delivered. The cache +is maintained for the benefit of other programs that access the maildir and +need to know the quota. + +If the \quota\ option in the transport is unset or zero, the \(maildirsize)\ +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@_quota@_directory@_regex\ option above for details. +.nem + + +.section Mailstore delivery +.index mailstore format||description of +If the \mailstore@_format\ option is true, each message is written as two files +in the given directory. A unique base name is constructed from the message id +and the current delivery process, and the files that are written use this base +name plus the suffixes \(.env)\ and \(.msg)\. The \(.env)\ file contains the +message's envelope, and the \(.msg)\ file contains the message itself. + +During delivery, the envelope is first written to a file with the suffix +\(.tmp)\. The \(.msg)\ file is then written, and when it is complete, the +\(.tmp)\ file is renamed as the \(.env)\ file. Programs that access messages in +mailstore format should wait for the presence of both a \(.msg)\ and a \(.env)\ +file before accessing either of them. An alternative approach is to wait for +the absence of a \(.tmp)\ file. + +The envelope file starts with any text defined by the \mailstore@_prefix\ +option, expanded and terminated by a newline if there isn't one. Then follows +the sender address on one line, then all the recipient addresses, one per line. +There can be more than one recipient only if the \batch@_max\ option is set +greater than one. Finally, \mailstore@_suffix\ is expanded and the result +appended to the file, followed by a newline if it does not end with one. + +If expansion of \mailstore@_prefix\ or \mailstore@_suffix\ ends with a forced +failure, it is ignored. Other expansion errors are treated as serious +configuration errors, and delivery is deferred. + + +.section Non-special new file delivery +If neither \maildir@_format\ nor \mailstore@_format\ is set, a single new file +is created directly in the named directory. For example, when delivering +messages into files in batched SMTP format for later delivery to some host (see +section ~~SECTbatchSMTP), a setting such as +.display asis +directory = /var/bsmtp/$host +.endd +might be used. A message is written to a file with a temporary name, which is +then renamed when the delivery is complete. The final name is obtained by +expanding the contents of the \directory@_file\ option. + + + + + +. +. +. +. +. ============================================================================ +.chapter The autoreply transport +.set runningfoot "autoreply transport" +.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 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 +\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 +that define the message are then ignored (so they are not usually set in this +case). The message is specified entirely by the filter or by the transport; it +is never built from a mixture of options. However, the \file@_optional\, +\mode\, and \return@_message\ options apply in all cases. + +\%Autoreply%\ is implemented as a local transport. When used as a result of a +command in a user's filter file, \%autoreply%\ normally runs under the uid and +gid of the user, and with appropriate current and home directories (see chapter +~~CHAPenvironment). + +There is a subtle difference between routing a message to a \%pipe%\ transport +that generates some text to be returned to the sender, and routing it to an +\%autoreply%\ transport. This difference is noticeable only if more than one +address from the same message is so handled. In the case of a pipe, the +separate outputs from the different addresses are gathered up and returned to +the sender in a single message, whereas if \%autoreply%\ is used, a separate +message is generated for each address that is passed to it. + +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, +the transport defers. +Whether characters with the top bit set count as printing characters or not is +controlled by the \print@_topbitchars\ global option. + +If any of the generic options for manipulating headers (for example, +\headers@_add\) are set on an \%autoreply%\ transport, they apply to the copy of +the original message that is included in the generated message when +\return@_message\ is set. They do not apply to the generated message itself. + +If the \%autoreply%\ transport receives return code 2 from Exim when it submits +the message, indicating that there were no recipients, it does not treat this +as an error. This means that autoreplies sent to \$sender@_address$\ when this +is empty (because the incoming message is a bounce message) do not cause +problems. They are just discarded. + + +.section Private options for autoreply + +.startconf +.index options||\%autoreply%\ transport +.conf bcc string$**$ unset +This specifies the addresses that are to receive `blind carbon copies' of the +message when the message is specified by the transport. + +.conf cc string$**$ unset +This specifies recipients of the message and the contents of the ::Cc:: header +when the message is specified by the transport. + +.conf file string$**$ unset +The contents of the file are sent as the body of the message when the message +is specified by the transport. If both \file\ and \text\ are set, the text +string comes first. + +.conf file@_expand boolean false +If this is set, the contents of the file named by the \file\ option are +subjected to string expansion as they are added to the message. + +.conf file@_optional boolean false +If this option is true, no error is generated if the file named by the \file\ +option or passed with the address does not exist or cannot be read. + +.conf from string$**$ unset +This specifies the contents of the ::From:: header when the message is specified +by the transport. + +.conf headers string$**$ unset +This specifies additional RFC 2822 headers that are to be added to the message when +the message is specified by the transport. Several can be given by using `@\n' +to separate them. There is no check on the format. + +.conf log string$**$ unset +This option names a file in which a record of every message sent is logged when +the message is specified by the transport. + +.conf mode "octal integer" 0600 +If either the log file or the `once' file has to be created, this mode is used. + +.conf once string$**$ unset +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 +grow as large as necessary. If a potential recipient is already in the +database, no message is sent by default. However, if \once@_repeat\ specifies a +time greater than zero, the message is sent if that much time has elapsed since +a message was last sent to this recipient. If \once\ is unset, the message is +always sent. + +If \once@_file@_size\ is set greater than zero, it changes the way Exim +implements the \once\ option. Instead of using a DBM file to record every +recipient it sends to, it uses a regular file, whose size will never get larger +than the given value. In the file, it keeps a linear list of recipient +addresses and times at which they were sent messages. If the file is full when +a new address needs to be added, the oldest address is dropped. If +\once@_repeat\ is not set, this means that a given recipient may receive +multiple messages, but at unpredictable intervals that depend on the rate of +turnover of addresses in the file. If \once@_repeat\ is set, it specifies a +maximum time between repeats. + +.conf once@_file@_size integer 0 +See \once\ above. + +.conf once@_repeat time$**$ 0s +See \once\ above. +After expansion, the value of this option must be a valid time value. + +.conf reply@_to string$**$ unset +This specifies the contents of the ::Reply-To:: header when the message is +specified by the transport. + +.conf return@_message boolean false +If this is set, a copy of the original message is returned with the new +message, subject to the maximum size set in the \return@_size@_limit\ global +configuration option. + +.conf subject string$**$ unset +This specifies the contents of the ::Subject:: header when the message is +specified by the transport. + +.conf text string$**$ unset +This specifies a single string to be used as the body of the message when the +message is specified by the transport. If both \text\ and \file\ are set, the +text comes first. + +.conf to string$**$ unset +This specifies recipients of the message and the contents of the ::To:: header +when the message is specified by the transport. + +.endconf + + + +. +. +. +. +. ============================================================================ +.chapter The lmtp transport +.set runningfoot "lmtp transport" +.index transports||\%lmtp%\ +.index \%lmtp%\ transport +.index LMTP||over a pipe +.index LMTP||over a socket +.rset CHAPLMTP "~~chapter" +The \%lmtp%\ transport runs the LMTP protocol (RFC 2033) over a pipe to a +specified command +or by interacting with a Unix domain socket. +This transport is something of a cross between the \%pipe%\ and \%smtp%\ +transports. Exim also has support for using LMTP over TCP/IP; this is +implemented as an option for the \%smtp%\ transport. Because LMTP is expected +to be of minority interest, the default build-time configure in \(src/EDITME)\ +has it commented out. You need to ensure that +.display asis +TRANSPORT_LMTP=yes +.endd +is present in your \(Local/Makefile)\ in order to have the \%lmtp%\ transport +included in the Exim binary. + +The private options of the \%lmtp%\ transport are as follows: + +.startconf +.index options||\%lmtp%\ transport + +.conf batch@_id string$**$ unset +See the description of local delivery batching in chapter ~~CHAPbatching. + +.conf batch@_max integer 1 +This limits the number of addresses that can be handled in a single delivery. +Most LMTP servers can handle several addresses at once, so it is normally a +good idea to increase this value. See the description of local delivery +batching in chapter ~~CHAPbatching. + +.conf command string$**$ unset +This option must be set if \socket\ is not set. +The string is a command which is run in a separate process. It is split up into +a command name and list of arguments, each of which is separately expanded (so +expansion cannot change the number of arguments). The command is run directly, +not via a shell. The message is passed to the new process using the standard +input and output to operate the LMTP protocol. + +.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 +delivers the message to it using the LMTP protocol. + +.conf timeout time 5m +The transport is aborted if the created process +or Unix domain socket +does not respond to LMTP commands or message input within this timeout. + +.endconf + +Here is an example of a typical LMTP transport: +.display asis +lmtp: + driver = lmtp + command = /some/local/lmtp/delivery/program + batch_max = 20 + user = exim +.endd +This delivers up to 20 addresses at a time, in a mixture of domains if +necessary, running as the user \*exim*\. + + + +. +. +. +. +. ============================================================================ +.chapter The pipe transport +.rset CHAPpipetransport "~~chapter" +.set runningfoot "pipe transport" +.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: +.numberpars $. +A router routes an 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). +.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 +that was redirected, and \$address@_pipe$\ contains the text of the pipe +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 +implemented by the \%lmtp%\ transport. + +In the case when \%pipe%\ is run as a consequence of an entry in a local user's +\(.forward)\ file, the command runs under the uid and gid of that user. In +other cases, the uid and gid have to be specified explicitly, either on the +transport or on the router that handles the address. Current and `home' +directories are also controllable. See chapter ~~CHAPenvironment for details of +the local delivery environment. + +.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 +have failed, unless either the \ignore@_status\ option is set (in which case +the return code is treated as zero), or the return code is one of those listed +in the \temp@_errors\ option, which are interpreted as meaning `try again +later'. In this case, delivery is deferred. Details of a permanent failure are +logged, but are not included in the bounce message, which merely contains +`local delivery failed'. + +If the return code is greater than 128 and the command being run is a shell +script, it normally means that the script was terminated by a signal whose +value is the return code minus 128. + +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 +set and the command produces any output on its standard output or standard +error streams, the command is considered to have failed, even if it gave a zero +return code or if \ignore@_status\ is set. The output from the command is +included as part of the bounce message. The \return@_fail@_output\ option is +similar, except that output is returned only when the command exits with a +failure return code, that is, a value other than zero or a code that matches +\temp@_errors\. + + +.section How the command is run +.rset SECThowcommandrun "~~chapter.~~section" +.index \%pipe%\ transport||path for command +The command line is (by default) broken down into a command name and arguments +by the \%pipe%\ transport itself. The \allow@_commands\ and \restrict@_to@_path\ +options can be used to restrict the commands that may be run. +.index quoting||in pipe command +Unquoted arguments are delimited by white space. If an argument appears in +double quotes, backslash is interpreted as an escape character in the usual +way. If an argument appears in single quotes, no escaping is done. + +String expansion is applied to the command line except when it comes from a +traditional \(.forward)\ file (commands from a filter file are expanded). The +expansion is applied to each argument in turn rather than to the whole line. +For this reason, any string expansion item that contains white space must be +quoted so as to be contained within a single argument. A setting such as +.display asis +command = /some/path ${if eq{$local_part}{postmaster}{xxx}{yyy}} +.endd +will not work, because the expansion item gets split between several +arguments. You have to write +.display asis +command = /some/path "${if eq{$local_part}{postmaster}{xxx}{yyy}}" +.endd +to ensure that it is all in one argument. The expansion is done in this way, +argument by argument, so that the number of arguments cannot be changed as a +result of expansion, and quotes or backslashes in inserted variables do not +interact with external quoting. + +.index transport||filter +.index filter||transport filter +Special handling takes place when an argument consists of precisely the text +`$tt{@$pipe@_addresses}'. This is not a general expansion variable; the only +place this string is recognized is when it appears as an argument for a pipe or +transport filter command. It causes each address that is being handled to be +inserted in the argument list at that point $it{as a separate argument}. This +avoids any problems with spaces or shell metacharacters, and is of use when a +\%pipe%\ transport is handling groups of addresses in a batch. + +After splitting up into arguments and expansion, the resulting command is run +in a subprocess directly from the transport, $it{not} under a shell. The +message that is being delivered is supplied on the standard input, and the +standard output and standard error are both connected to a single pipe that is +read by Exim. The \max@_output\ option controls how much output the command may +produce, and the \return@_output\ and \return@_fail@_output\ options control +what is done with it. + +Not running the command under a shell (by default) lessens the security risks +in cases when a command from a user's filter file is built out of data that was +taken from an incoming message. If a shell is required, it can of course be +explicitly specified as the command to be run. However, there are circumstances +where existing commands (for example, in \(.forward)\ files) expect to be run +under a shell and cannot easily be modified. To allow for these cases, there is +an option called \use@_shell\, which changes the way the \%pipe%\ transport +works. Instead of breaking up the command line as just described, it expands it +as a single string and passes the result to \(/bin/sh)\. The +\restrict@_to@_path\ option and the \$pipe@_addresses$\ facility cannot be used +with \use@_shell\, and the whole mechanism is inherently less secure. + + +.section Environment variables +.rset SECTpipeenv "~~chapter.~~section" +.index \%pipe%\ transport||environment for command +.index environment for pipe transport +The environment variables listed below are set up when the command is invoked. +This list is a compromise for maximum compatibility with other MTAs. Note that +the \environment\ option can be used to add additional variables to this +environment. +.display flow +.tabs 20 +DOMAIN $t $rm{the domain of the address} +HOME $t $rm{the home directory, if set} +HOST $t $rm{the host name when called from a router (see below)} +LOCAL@_PART $t $rm{see below} +LOCAL@_PART@_PREFIX $t $rm{see below} +LOCAL@_PART@_SUFFIX $t $rm{see below} +LOGNAME $t $rm{see below} +MESSAGE@_ID $t $rm{the message's id} +PATH $t $rm{as specified by the \path\ option below} +QUALIFY@_DOMAIN $t $rm{the sender qualification domain} +RECIPIENT $t $rm{the complete recipient address} +SENDER $t $rm{the sender of the message (empty if a bounce)} +SHELL $t `$tt{/bin/sh}' +TZ $t $rm{the value of the \timezone\ option, if set} +USER $t $rm{see below} +.endd + +When a \%pipe%\ transport is called directly from (for example) an \%accept%\ +router, \\LOCAL@_PART\\ is set to the local part of the address. When it is +called as a result of a forward or alias expansion, \\LOCAL@_PART\\ is set to +the local part of the address that was expanded. In both cases, any affixes are +removed from the local part, and made available in \\LOCAL@_PART@_PREFIX\\ and +\\LOCAL@_PART@_SUFFIX\\, respectively. \\LOGNAME\\ and \\USER\\ are set to the +same value as \\LOCAL@_PART\\ for compatibility with other MTAs. + +.index \\HOST\\ +\\HOST\\ is set only when a \%pipe%\ transport is called from a router that +associates hosts with an address, typically when using \%pipe%\ as a +pseudo-remote transport. \\HOST\\ is set to the first host name specified by +the router. + +.index \\HOME\\ +If the transport's generic \home@_directory\ option is set, its value is used +for the \\HOME\\ environment variable. Otherwise, a home directory may be set +by the router's \transport@_home@_directory\ option, which defaults to the +user's home directory if \check@_local@_user\ is set. + +.section Private options for pipe +.index options||\%pipe%\ transport +.startconf + +.conf allow@_commands "string list$**$" unset +.index \%pipe%\ transport||permitted commands +The string is expanded, and is then interpreted as a colon-separated list of +permitted commands. If \restrict@_to@_path\ is not set, the only commands +permitted are those in the \allow@_commands\ list. They need not be absolute +paths; the \path\ option is still used for relative paths. If +\restrict@_to@_path\ is set with \allow@_commands\, the command must either be +in the \allow@_commands\ list, or a name without any slashes that is found on +the path. In other words, if neither \allow@_commands\ nor \restrict@_to@_path\ +is set, there is no restriction on the command, but otherwise only commands +that are permitted by one or the other are allowed. For example, if +.display asis +allow_commands = /usr/bin/vacation +.endd +and \restrict@_to@_path\ is not set, the only permitted command is +\(/usr/bin/vacation)\. The \allow@_commands\ option may not be set if +\use@_shell\ is set. + +.conf batch@_id string$**$ unset +See the description of local delivery batching in chapter ~~CHAPbatching. + +.conf batch@_max integer 1 +This limits the number of addresses that can be handled in a single delivery. +See the description of local delivery batching in chapter ~~CHAPbatching. + +.conf check@_string string unset +As \%pipe%\ writes the message, the start of each line is tested for matching +\check@_string\, and if it does, the initial matching characters are replaced +by the contents of \escape@_string\, provided both are set. The value of +\check@_string\ is a literal string, not a regular expression, and the case of +any letters it contains is significant. When \use@_bsmtp\ is set, the contents +of \check@_string\ and \escape@_string\ are forced to values that implement the +SMTP escaping protocol. Any settings made in the configuration file are +ignored. + +.conf command string$**$ unset +This option need not be set when \%pipe%\ is being used to deliver to pipes +obtained directly from address redirections. In other cases, the option must be +set, to provide a command to be run. It need not yield an absolute path (see +the \path\ option below). The command is split up into separate arguments by +Exim, and each argument is separately expanded, as described in section +~~SECThowcommandrun above. + +.conf environment string$**$ unset +.index \%pipe%\ transport||environment for command +.index environment for \%pipe%\ transport +This option is used to add additional variables to the environment in which the +command runs (see section ~~SECTpipeenv for the default list). Its value is a +string which is expanded, and then interpreted as a colon-separated list of +environment settings of the form `<<name>>=<<value>>'. + +.conf escape@_string string unset +See \check@_string\ above. + +.conf freeze@_exec@_fail boolean false +.index exec failure +.index failure of exec +.index \%pipe%\ transport||failure of exec +Failure to exec the command in a pipe transport is by default treated like +any other failure while running the command. However, if \freeze@_exec@_fail\ +is set, failure to exec is treated specially, and causes the message to be +frozen, whatever the setting of \ignore@_status\. + +.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 +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 +tried again later. + +.conf log@_defer@_output boolean false +.index \%pipe%\ transport||logging output +If this option is set, and the status returned by the command is +one of the codes listed in \temp@_errors\ (that is, delivery was deferred), +and any output was produced, the first line of it is written to the main log. + +.conf log@_fail@_output boolean false +If this option is set, and the command returns any output, and also ends with a +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. + +.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. + +.conf max@_output integer 20K +This specifies the maximum amount of output that the command may produce on its +standard output and standard error file combined. If the limit is exceeded, the +process running the command is killed. This is intended as a safety measure to +catch runaway processes. The limit is applied independently of the settings of +the options that control what is done with such output (for example, +\return@_output\). Because of buffering effects, the amount of output may +exceed the limit by a small amount before Exim notices. + +.conf message@_prefix string$**$ "see below" +The string specified here is expanded and output at the start of every message. +The default is unset if \use@_bsmtp\ is set. Otherwise it is +.display asis +message_prefix = \ + From ${if def:return_path{$return_path}{MAILER-DAEMON}}\ + ${tod_bsdinbox}\n +.endd +.index Cyrus +.index \tmail\ +.index `From' line +This is required by the commonly used \(/usr/bin/vacation)\ program. +However, it must $it{not} be present if delivery is to the Cyrus IMAP server, +or to the \tmail\ local delivery agent. The prefix can be suppressed by setting +.display asis +message_prefix = +.endd + +.conf message@_suffix string$**$ "see below" +The string specified here is expanded and output at the end of every message. +The default is unset if \use@_bsmtp\ is set. Otherwise it is a single newline. +The suffix can be suppressed by setting +.display asis +message_suffix = +.endd + +.conf path string $tt{/usr/bin} +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 +filter. + +.conf pipe@_as@_creator boolean false +.index uid (user id)||local delivery +If the generic \user\ option is not set and this option is true, the delivery +process is run under the uid that was in force when Exim was originally called +to accept the message. If the group id is not otherwise set (via the generic +\group\ option), the gid that was in force when Exim was originally called to +accept the message is used. + +.conf restrict@_to@_path boolean false +When this option is set, any command name not listed in \allow@_commands\ must +contain no slashes. The command is searched for only in the directories listed +in the \path\ option. This option is intended for use in the case when a pipe +command has been generated from a user's \(.forward)\ file. This is usually +handled by a \%pipe%\ transport called \address@_pipe\. + +.conf return@_fail@_output boolean false +If this option is true, and the command produced any output and ended with a +return code other than zero or one of the codes listed in \temp@_errors\ (that +is, the delivery failed), the output is returned in the bounce message. +However, if the message has a null sender (that is, it is itself a bounce +message), output from the command is discarded. + +.conf return@_output boolean false +If this option is true, and the command produced any output, the delivery is +deemed to have failed whatever the return code from the command, and the output +is returned in the bounce message. Otherwise, the output is just discarded. +However, if the message has a null sender (that is, it is a bounce message), +output from the command is always discarded, whatever the setting of this +option. + +.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 +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 +codes are treated as permanent errors. The default setting contains the codes +defined by \\EX@_TEMPFAIL\\ and \\EX@_CANTCREAT\\ in \(sysexits.h)\. If Exim is +compiled on a system that does not define these macros, it assumes values of 75 +and 73, respectively. + +.conf timeout time 1h +If the command fails to complete within this time, it is killed. This normally +causes the delivery to fail. A zero time interval specifies no timeout. In +order to ensure that any subprocesses created by the command are also killed, +Exim makes the initial process a process group leader, and kills the whole +process group on a timeout. However, this can be defeated if one of the +processes starts a new process group. + +.conf umask "octal integer" 022 +This specifies the umask setting for the subprocess that runs the command. + +.conf use@_bsmtp boolean false +.index envelope sender +If this option is set true, the \%pipe%\ transport writes messages in `batch +SMTP' format, with the envelope sender and recipient(s) included as SMTP +commands. If you want to include a leading \\HELO\\ command with such messages, +you can do so by setting the \message@_prefix\ option. See section +~~SECTbatchSMTP for details of batch SMTP. + +.conf use@_crlf boolean false +.index carriage return +.index linefeed +This option causes lines to be terminated with the two-character CRLF sequence +(carriage return, linefeed) instead of just a linefeed character. In the case +of batched SMTP, the byte sequence written to the pipe is then an exact image +of what would be sent down a real SMTP connection. + +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. Since the default values for both \message@_prefix\ and +\message@_suffix\ end with a single linefeed, their values +must +be changed to end with \"@\r@\n"\ if \use@_crlf\ is set. + +.conf use@_shell boolean false +If this option is set, it causes the command to be passed to \(/bin/sh)\ +instead of being run directly from the transport, as described in section +~~SECThowcommandrun. This is less secure, but is needed in some situations +where the command is expected to be run under a shell and cannot easily be +modified. The \allow@_commands\ and \restrict@_to@_path\ options, and the +`$tt{@$pipe@_addresses}' facility are incompatible with \use@_shell\. The +command is expanded as a single string, and handed to \(/bin/sh)\ as data for +its \-c-\ option. + +.endconf + +.section Using an external local delivery agent +.index local delivery||using an external agent +.index \*procmail*\ +.index external local delivery +.index delivery||\*procmail*\ +.index delivery||by external agent +The \%pipe%\ transport can be used to pass all messages that require local +delivery to a separate local delivery agent such as \procmail\. When doing +this, care must be taken to ensure that the pipe is run under an appropriate +uid and gid. In some configurations one wants this to be a uid that is trusted +by the delivery agent to supply the correct sender of the message. It may be +necessary to recompile or reconfigure the delivery agent so that it trusts an +appropriate user. The following is an example transport and router +configuration for \procmail\: +.display asis +# transport +procmail_pipe: + driver = pipe + command = /usr/local/bin/procmail -d $local_part + return_path_add + delivery_date_add + envelope_to_add + check_string = "From " + escape_string = ">From " + user = $local_part + group = mail +.endd +.display asis +# router +procmail: + driver = accept + check_local_user + transport = procmail_pipe +.endd + +In this example, the pipe is run as the local user, but with the group set to +\*mail*\. An alternative is to run the pipe as a specific user such as \*mail*\ +or \*exim*\, but in this case you must arrange for \procmail\ to trust that +user to supply a correct sender address. If you do not specify either a \group\ +or a \user\ option, the pipe command is run as the local user. The home +directory is the user's home directory by default. + +Note that the command that the pipe transport runs does $it{not} begin with +.display asis +IFS=" " +.endd +as shown in the \procmail\ documentation, because Exim does not by default use +a shell to run pipe commands. + +.index Cyrus +The next example shows a transport and a router for a system where local +deliveries are handled by the Cyrus IMAP server. +.display asis +# transport +local_delivery_cyrus: + driver = pipe + command = /usr/cyrus/bin/deliver \ + -m ${substr_1:$local_part_suffix} -- $local_part + user = cyrus + group = mail + return_output + log_output + message_prefix = + message_suffix = +.endd +.display asis +# router +local_user_cyrus: + driver = accept + check_local_user + local_part_suffix = .* + transport = local_delivery_cyrus +.endd +Note the unsetting of \message@_prefix\ and \message@_suffix\, and the use of +\return@_output\ to cause any text written by Cyrus to be returned to the +sender. + + +. +. +. +. +. ============================================================================ +.chapter The smtp transport +.rset CHAPsmtptrans "~~chapter" +.set runningfoot "smtp transport" +.index transports||\%smtp%\ +.index \%smtp%\ transport +The \%smtp%\ transport delivers messages over TCP/IP connections using the SMTP +or LMTP protocol. The list of hosts to try can either be taken from the address +that is being processed (having been set up by the router), or specified +explicitly for the transport. Timeout and retry processing (see chapter +~~CHAPretry) is applied to each IP address independently. + +.section Multiple messages on a single connection +The sending of multiple messages over a single TCP/IP connection can arise in +two ways: +.numberpars $. +If a message contains more than \max@_rcpt\ (see below) addresses that are +routed to the same host, more than one copy of the message has to be sent to +that host. In this situation, multiple copies may be sent in a single run of +the \%smtp%\ transport over a single TCP/IP connection. (What Exim actually does +when it has too many addresses to send in one message also depends on the value +of the global \remote@_max@_parallel\ option. Details are given in section +~~SECToutSMTPTCP.) +.nextp +.index hints database||remembering routing +When a message has been successfully delivered over a TCP/IP connection, Exim +looks in its hints database to see if there are any other messages awaiting a +connection to the same host. If there are, a new delivery process is started +for one of them, and the current TCP/IP connection is passed on to it. The new +process may in turn send multiple copies and possibly create yet another +process. +.endp + +For each copy sent over the same TCP/IP connection, a sequence counter is +incremented, and if it ever gets to the value of \connection@_max@_messages\, +no further messages are sent over that connection. + + +.section Use of the @$host variable +.index \$host$\ +.index \$host@_address$\ +At the start of a run of the \%smtp%\ transport, the values of \$host$\ and +\$host@_address$\ are the name and IP address of the first host on the host list +passed by the router. However, when the transport is about to connect to a +specific host, and while it is connected to that host, \$host$\ and +\$host@_address$\ are set to the values for that host. These are the values +that are in force when the \helo@_data\, \hosts@_try@_auth\, \interface\, +\serialize@_hosts\, and the various TLS options are expanded. + + +.section Private options for smtp +The private options of the \%smtp%\ transport are as follows: + +.index options||\%smtp%\ transport +.startconf +.conf allow@_localhost boolean false +.index local host||sending to +.index fallback||hosts specified on transport +When a host specified in \hosts\ or \fallback@_hosts\ (see below) turns out to +be the local host, or is listed in \hosts@_treat@_as@_local\, delivery is +deferred by default. However, if \allow@_localhost\ is set, Exim goes on to do +the delivery anyway. This should be used only in special cases when the +configuration ensures that no looping will result (for example, a differently +configured Exim is listening on the port to which the message is sent). + +.conf authenticated@_sender string$**$ unset +.index Cyrus +When Exim has authenticated as a client, this option sets a value for the +\\AUTH=\\ item on outgoing \\MAIL\\ commands, overriding any existing +authenticated sender value. If the string expansion is forced to fail, the +option is ignored. Other expansion failures cause delivery to be deferred. If +the result of expansion is an empty string, that is also ignored. + +If the SMTP session is not authenticated, the expansion of +\authenticated@_sender\ still happens (and can cause the delivery to be +deferred if it fails), but no \\AUTH=\\ item is added to \\MAIL\\ commands. + +This option allows you to use the \%smtp%\ transport in LMTP mode to +deliver mail to Cyrus IMAP and provide the proper local part as the +`authenticated sender', via a setting such as: +.display asis +authenticated_sender = $local_part +.endd +This removes the need for IMAP subfolders to be assigned special ACLs to +allow direct delivery to those subfolders. + +Because of expected uses such as that just described for Cyrus (when no +domain is involved), there is no checking on the syntax of the provided +value. + +.conf command@_timeout time 5m +This sets a timeout for receiving a response to an SMTP command that has been +sent out. It is also used when waiting for the initial banner line from the +remote host. Its value must not be zero. + +.conf connect@_timeout time 5m +This sets a timeout for the \*connect()*\ function, which sets up a TCP/IP call +to a remote host. A setting of zero allows the system timeout (typically +several minutes) to act. To have any effect, the value of this option must be +less than the system timeout. However, it has been observed that on some +systems there is no system timeout, which is why the default value for this +option is 5 minutes, a value recommended by RFC 1123. + +.index SMTP||passed connection +.index SMTP||multiple deliveries +.index multiple SMTP deliveries +.conf connection@_max@_messages integer 500 +This controls the maximum number of separate message deliveries that are sent +over a single TCP/IP connection. If the value is zero, there is no limit. +For testing purposes, this value can be overridden by the \-oB-\ command line +option. + +.conf data@_timeout time 5m +This sets a timeout for the transmission of each block in the data portion of +the message. As a result, the overall timeout for a message depends on the size +of the message. Its value must not be zero. See also \final@_timeout\. + +.conf delay@_after@_cutoff boolean true +This option controls what happens when all remote IP addresses for a given +domain have been inaccessible for so long that they have passed their retry +cutoff times. + +In the default state, if the next retry time has not been reached for any of +them, the address is bounced without trying any deliveries. In other words, +Exim delays retrying an IP address after the final cutoff time until a new +retry time is reached, and can therefore bounce an address without ever trying +a delivery, when machines have been down for a long time. Some people are +unhappy at this prospect, so... + +If \delay@_after@_cutoff\ is set false, Exim behaves differently. If all IP +addresses are past their final cutoff time, Exim tries to deliver to those +IP addresses that have not been tried since the message arrived. If there are +none, of if they all fail, the address is bounced. In other words, it does not +delay when a new message arrives, but immediately tries those expired IP +addresses that haven't been tried since the message arrived. If there is a +continuous stream of messages for the dead hosts, unsetting +\delay@_after@_cutoff\ means that there will be many more attempts to deliver +to them. + +.conf dns@_qualify@_single boolean true +If the \hosts\ or \fallback@_hosts\ option is being used, +and the \gethostbyname\ option is false, +the \\RES@_DEFNAMES\\ resolver option is set. See the \qualify@_single\ option +in chapter ~~CHAPdnslookup for more details. + +.conf dns@_search@_parents boolean false +.index \search@_parents\ +If the \hosts\ or \fallback@_hosts\ option is being used, and the +\gethostbyname\ option is false, the \\RES@_DNSRCH\\ resolver option is set. +See the \search@_parents\ option in chapter ~~CHAPdnslookup for more details. + + +.conf fallback@_hosts "string list" unset +.index fallback||hosts specified on transport +String expansion is not applied to this option. The argument must be a +colon-separated list of host names or IP addresses. Fallback hosts can also be +specified on routers, which associate them with the addresses they process. As +for the \hosts\ option without \hosts@_override\, \fallback@_hosts\ specified +on the transport is used only if the address does not have its own associated +fallback host list. Unlike \hosts\, a setting of \fallback@_hosts\ on an +address is not overridden by \hosts@_override\. However, \hosts@_randomize\ +does apply to fallback host lists. + +If Exim is unable to deliver to any of the hosts for a particular address, and +the errors are not permanent rejections, the address is put on a separate +transport queue with its host list replaced by the fallback hosts, unless the +address was routed via MX records and the current host was in the original MX +list. In that situation, the fallback host list is not used. + +Once normal deliveries are complete, the fallback queue is delivered by +re-running the same transports with the new host lists. If several failing +addresses have the same fallback hosts (and \max@_rcpt\ permits it), a single +copy of the message is sent. + +The resolution of the host names on the fallback list is controlled by the +\gethostbyname\ option, as for the \hosts\ option. Fallback hosts apply +both to cases when the host list comes with the address and when it is taken +from \hosts\. This option provides a `use a smart host only if delivery fails' +facility. + +.conf final@_timeout time 10m +This is the timeout that applies while waiting for the response to the final +line containing just `.' that terminates a message. Its value must not be zero. + +.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()*\ +(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 \\HELO\\||argument, setting +.index \\EHLO\\||argument, setting +.conf helo@_data string$**$ $tt{@$primary@_hostname} +The value of this option is expanded, and used as the argument for the \\EHLO\\ +or \\HELO\\ command that starts the outgoing SMTP session. + +.conf hosts "string list$**$" unset +Hosts are associated with an address by a router such as \%dnslookup%\, which +finds the hosts by looking up the address domain in the DNS. However, addresses +can be passed to the \%smtp%\ transport by any router, and not all of them can +provide an associated host list. The \hosts\ option specifies a list of hosts +which are used if the address being processed does not have any hosts +associated with it. The hosts specified by \hosts\ are also used, whether or +not the address has its own hosts, if \hosts@_override\ is set. + +The string is first expanded, before being interpreted as a colon-separated +list of host names or IP addresses. If the expansion fails, delivery is +deferred. Unless the failure was caused by the inability to complete a lookup, +the error is logged to the panic log as well as the main log. Host names are +looked up either by searching directly for address records in the DNS or by +calling \*gethostbyname()*\ +(or \*getipnodebyname()*\ when available), +depending on the setting of the \gethostbyname\ option. When Exim is compiled +with IPv6 support, if a host that is looked up in the DNS has both IPv4 and +IPv6 addresses, both types of address are used. + +During delivery, the hosts are tried in order, subject to their retry status, +unless \hosts@_randomize\ is set. + +.conf hosts@_avoid@_esmtp "host list$**$" unset +.index ESMTP, avoiding use of +.index \\HELO\\||forcing use of +.index \\EHLO\\||avoiding use of +.index \\PIPELINING\\||avoiding the use of +This option is for use with broken hosts that announce ESMTP facilities (for +example, \\PIPELINING\\) and then fail to implement them properly. When a host +matches \hosts@_avoid@_esmtp\, Exim sends \\HELO\\ rather than \\EHLO\\ at the +start of the SMTP session. This means that it cannot use any of the ESMTP +facilities such as \\AUTH\\, \\PIPELINING\\, \\SIZE\\, and \\STARTTLS\\. + +.conf hosts@_avoid@_tls "host list$**$" unset +.index TLS||avoiding for certain hosts +Exim will not try to start a TLS session when delivering to any host that +matches this list. See chapter ~~CHAPTLS for details of TLS. + +.conf hosts@_max@_try integer 5 +.index host||maximum number to try +.index limit||number of hosts tried +.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 +.em +in cases where there are temporary delivery errors. +.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 multiple SMTP deliveries +.index TLS||multiple message deliveries +For any host that matches this list, a connection on which a TLS session has +been started will not be passed to a new delivery process for sending another +message on the same connection. See section ~~SECTmulmessam for an explanation +of when this might be needed. + +.conf hosts@_override boolean false +If this option is set and the \hosts\ option is also set, any hosts that are +attached to the address are ignored, and instead the hosts specified by the +\hosts\ option are always used. This option does not apply to +\fallback@_hosts\. + +.conf hosts@_randomize boolean false +.index randomized host list +.index host||list of, randomized +.index fallback||randomized hosts +If this option is set, and either the list of hosts is taken from the +\hosts\ or the \fallback@_hosts\ option, or the hosts supplied by the router +were not obtained from MX records (this includes fallback hosts from the +router), and were not randomizied by the router, the order of trying the hosts +is randomized each time the transport runs. Randomizing the order of a host +list can be used to do crude load sharing. + +When \hosts@_randomize\ is true, a host list may be split into groups whose +order is separately randomized. This makes it possible to set up MX-like +behaviour. The boundaries between groups are indicated by an item that is just +\"+"\ in the host list. For example: +.display asis +hosts = host1:host2:host3:+:host4:host5 +.endd +The order of the first three hosts and the order of the last two hosts is +randomized for each use, but the first three always end up before the last two. +If \hosts@_randomize\ is not set, a \"+"\ item in the list is ignored. + +.index authentication||required by client +.conf hosts@_require@_auth "host list$**$" unset +This option provides a list of servers for which authentication must succeed +before Exim will try to transfer a message. If authentication fails for +servers which are not in this list, Exim tries to send unauthenticated. If +authentication fails for one of these servers, delivery is deferred. This +temporary error is detectable in the retry rules, so it can be turned into a +hard failure if required. See also \hosts@_try@_auth\, and chapter +~~CHAPSMTPAUTH for details of authentication. + +.conf hosts@_require@_tls "host list$**$" unset +.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 +incoming messages, use an appropriate ACL. + +.index authentication||optional in client +.conf hosts@_try@_auth "host list$**$" unset +This option provides a list of servers to which, provided they announce +authentication support, Exim will attempt to authenticate as a client when it +connects. If authentication fails, Exim will try to transfer the message +unauthenticated. See also \hosts@_require@_auth\, and chapter ~~CHAPSMTPAUTH +for details of authentication. + +.index bind IP address +.index IP address||binding +.conf interface "string list$**$" unset +This option specifies which interface to bind to when making an outgoing SMTP +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 +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 +.endd +The first interface of the correct type (IPv4 or IPv6) is used for the outgoing +connection. If none of them are the correct type, the option is ignored. If +\interface\ is not set, or is ignored, the system's IP functions choose which +interface to use if the host has more than one. + +.conf keepalive boolean true +.index keepalive||on outgoing connection +This option controls the setting of \\SO@_KEEPALIVE\\ on outgoing TCP/IP socket +connections. When set, it causes the kernel to probe idle connections +periodically, by sending packets with `old' sequence numbers. The other end of +the connection should send a acknowledgement if the connection is still okay or +a reset if the connection has been aborted. The reason for doing this is that +it has the beneficial effect of freeing up certain types of connection that can +get stuck when the remote host is disconnected without tidying up the TCP/IP +call properly. The keepalive mechanism takes several hours to detect +unreachable hosts. + +.conf max@_rcpt integer 100 +.index \\RCPT\\||maximum number of outgoing +This option limits the number of \\RCPT\\ commands that are sent in a single +SMTP message transaction. Each set of addresses is treated independently, and +so can cause parallel connections to the same host if \remote@_max@_parallel\ +permits this. + +.conf multi@_domain boolean true +When this option is set, the \%smtp%\ transport can handle a number of addresses +containing a mixture of different domains provided they all resolve to the same +list of hosts. Turning the option off restricts the transport to handling only +one domain at a time. This is useful if you want to use \$domain$\ in an +expansion for the transport, because it is set only when there is a single +domain involved in a remote delivery. + +.conf port string$**$ "see below" +.index port||sending TCP/IP +.index TCP/IP||setting outgoing port +This option specifies the TCP/IP port on the server to which Exim connects. If +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 +deferred. + + +.conf protocol string "smtp" +.index LMTP||over TCP/IP +If this option is set to `lmtp' instead of `smtp', the default value for the +\port\ option changes to `lmtp', and the transport operates the LMTP protocol +(RFC 2033) instead of SMTP. This protocol is sometimes used for local +deliveries into closed message stores. Exim also has support for running LMTP +over a pipe to a local process -- see chapter ~~CHAPLMTP. + +.conf retry@_include@_ip@_address boolean true +Exim normally includes both the host name and the IP address in the key it +constructs for indexing retry data after a temporary delivery failure. This +means that when one of several IP addresses for a host is failing, it gets +tried periodically (controlled by the retry rules), but use of the other IP +addresses is not affected. + +However, in some dialup environments hosts are assigned a different IP address +each time they connect. In this situation the use of the IP address as part of +the retry key leads to undesirable behaviour. Setting this option false causes +Exim to use only the host name. This should normally be done on a separate +instance of the \%smtp%\ transport, set up specially to handle the dialup hosts. + +.conf serialize@_hosts "host list$**$" unset +.index serializing connections +.index host||serializing connections +Because Exim operates in a distributed manner, if several messages for the same +host arrive at around the same time, more than one simultaneous connection to +the remote host can occur. This is not usually a problem except when there is a +slow link between the hosts. In that situation it may be helpful to restrict +Exim to one connection at a time. This can be done by setting +\serialize@_hosts\ to match the relevant hosts. + +.index hints database||serializing deliveries to a host +Exim implements serialization by means of a hints database in which a record is +written whenever a process connects to one of the restricted hosts. The record +is deleted when the connection is completed. Obviously there is scope for +records to get left lying around if there is a system or program crash. To +guard against this, Exim ignores any records that are more than six hours old. + +If you set up this kind of serialization, you should also arrange to delete the +relevant hints database whenever your system reboots. The names of the files +start with \(misc)\ and they are kept in the \(spool/db)\ directory. There +may be one or two files, depending on the type of DBM in use. The same files +are used for ETRN serialization. + +.conf size@_addition integer 1024 +.index SMTP||\\SIZE\\ +.index message||size issue for transport filter +.index size||of message +.index transport||filter +.index filter||transport filter +If a remote SMTP server indicates that it supports the \\SIZE\\ option of the +\\MAIL\\ command, Exim uses this to pass over the message size at the start of +an SMTP transaction. It adds the value of \size@_addition\ to the value it +sends, to allow for headers and other text that may be added during delivery by +configuration options or in a transport filter. It may be necessary to increase +this if a lot of text is added to messages. + +Alternatively, if the value of \size@_addition\ is set negative, it disables +the use of the \\SIZE\\ option altogether. + +.conf tls@_certificate string$**$ unset +.index TLS||client certificate, location of +.index certificate||for client, location of +The value of this option must be the absolute path to a file which contains the +client's certificate, 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. 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 +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 +the certificate. +See chapter ~~CHAPTLS for details of TLS. + +.conf tls@_require@_ciphers string$**$ unset +.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 +.em +outgoing encrypted connection. (There is a global option of the same name for +controlling incoming connections.) +.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 +setting up a TLS session, this option determines whether or not Exim should try +to deliver the message unencrypted. If it is set false, delivery to the +current host is deferred; if there are other hosts, they are tried. If this +option is set true, Exim attempts to deliver unencrypted after a 4\*xx*\ +response to \\STARTTLS\\. Also, if \\STARTTLS\\ is accepted, but the subsequent +TLS negotiation fails, Exim closes the current connection (because it is in an +unknown state), opens a new one to the same host, and then tries the delivery +in clear. + +.conf tls@_verify@_certificates string$**$ unset +.index TLS||server certificate verification +.index certificate||verification of server +The value of this option must be the absolute path to a file containing +permitted server certificates, for use when setting up an encrypted connection. +Alternatively, if you are using OpenSSL, you can set +\tls@_verify@_certificates\ to the name of a directory containing certificate +files. This does not work with GnuTLS; the option must be set to the name of a +single file if you are using GnuTLS. The values of \$host$\ and +\$host@_address$\ are set to the name and address of the server during the +expansion of this option. See chapter ~~CHAPTLS for details of TLS. + +.endconf + + +.section How the value of hosts@_max@_try is used +.rset SECTvalhosmax "~~chapter.~~section" +.index host||maximum number to try +.index limit||hosts, maximum number tried +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 +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 +multihomed hosts. As a result, a list of a dozen or more IP addresses may be +created as a result of routing one of these domains. + +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 +delivery. However, the logic cannot be quite that simple. + +Firstly, IP addresses that are skipped because their retry times have not +arrived do not count, and in addition, addresses that are past their retry +limits are also not counted, even when they are tried. This means that when +some IP addresses are past their retry limits, more than the value of +\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. + +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: + +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 +tried when those at the top of the list are skipped because they have not +reached their retry times. + +However, it is common practice to put a fixed short retry time on domains for +large ISPs, on the grounds that their servers are rarely down for very long. +Unfortunately, these are exactly the domains that tend to resolve to long lists +of hosts. The short retry time means that the lowest MX hosts are tried every +time. The attempts may be in a different order because of random sorting, but +without the special MX check 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. + + + + + + +. +. +. +. +. ============================================================================ +.chapter Address rewriting +.set runningfoot "address rewriting" +.rset CHAPrewrite ~~chapter +.index rewriting||addresses +There are some circumstances in which Exim automatically rewrites domains in +addresses. The two most common are when an address is given without a domain +(referred to as an `unqualified address') or when an address contains an +abbreviated domain that is expanded by DNS lookup. + +Unqualified envelope addresses are accepted only for locally submitted +messages, or messages from hosts that match \sender@_unqualified@_hosts\ or +\recipient@_unqualified@_hosts\, respectively. Unqualified addresses in header +lines are qualified if they are in locally submitted messages, or messages from +hosts that are permitted to send unqualified envelope addresses. Otherwise, +unqualified addresses in header lines are neither qualified nor rewritten. + +One situation in which Exim does $it{not} automatically rewrite a domain is +when it is the name of a CNAME record in the DNS. The older RFCs suggest that +such a domain should be rewritten using the `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 +\headers@_rewrite\ option that can be set on any transport. + +Some people believe that configured address rewriting is a Mortal Sin. +Others believe that life is not possible without it. Exim provides the +facility; you do not have to use it. + +.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 +that were added by a system filter. That is, it applies only to those headers +that are common to all copies of the message. Header lines that are added by +individual routers or transports (and which are therefore specific to +individual recipient addresses) are not rewritten. + +In general, rewriting addresses from your own system or domain has some +legitimacy. Rewriting other addresses should be done only with great care and +in special circumstances. The author of Exim believes that rewriting should be +used sparingly, and mainly for `regularizing' addresses in your own domains. +Although it can sometimes be used as a routing tool, this is very strongly +discouraged. + +There are two commonly encountered circumstances where rewriting is used, as +illustrated by these examples: +.numberpars $. +The company whose domain is \*hitch.fict.example*\ has a number of hosts that +exchange mail with each other behind a firewall, but there is only a single +gateway to the outer world. The gateway rewrites \*@*.hitch.fict.example*\ as +\*hitch.fict.example*\ when sending mail off-site. +.nextp +A host rewrites the local parts of its own users so that, for example, +\*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. + +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 +rewritten thereafter. The subsequent value of \$sender@_address$\ is the +rewritten address. This also applies if sender verification happens in a +\\RCPT\\ ACL. Otherwise, when the sender address is not verified, it is +rewritten as soon as a message's header lines have been received. + +Similarly, at the start of an ACL for \\RCPT\\, the current recipient's address +may have been rewritten by a special SMTP-time rewrite rule, but no ordinary +rewrite rules have yet been applied to it. However, the behaviour is different +from the sender address when a recipient is verified. The address is rewritten +for the verification, but the rewriting is not remembered at this stage. The +value of \$local@_part$\ and \$domain$\ after verification are always the same +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 +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 +Thus, all the rewriting is completed before the \\DATA\\ ACL and +\*local@_scan()*\ functions are run. + +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 +At transport time, additional rewriting of addresses in header lines can be +specified by setting the generic \headers@_rewrite\ option on a transport. This +option contains rules that are identical in form to those in the rewrite +section of the configuration file. In addition, the outgoing envelope sender +can be rewritten by means of the \return@_path\ transport option. However, it +is not possible to rewrite envelope recipients at transport time. + + + +.section Testing the rewriting rules that apply on input +.index rewriting||testing +.index testing||rewriting +Exim's input rewriting configuration appears in a part of the run time +configuration file headed by `begin rewrite'. It can be tested by the \-brw-\ +command line option. This takes an address (which can be a full RFC 2822 +address) as its argument. The output is a list of how the address would be +transformed by the rewriting rules for each of the different places it might +appear in an incoming message, that is, for each different header and for the +envelope sender and recipient fields. For example, +.display asis +exim -brw ph10@exim.workshop.example +.endd +might produce the output +.display asis + sender: Philip.Hazel@exim.workshop.example + from: Philip.Hazel@exim.workshop.example + to: ph10@exim.workshop.example + cc: ph10@exim.workshop.example + bcc: ph10@exim.workshop.example +reply-to: Philip.Hazel@exim.workshop.example +env-from: Philip.Hazel@exim.workshop.example + env-to: ph10@exim.workshop.example +.endd +which shows that rewriting has been set up for that address when used in any of +the source fields, but not when it appears as a recipient address. At the +present time, there is no equivalent way of testing rewriting rules that are +set for a particular transport. + +.section Rewriting rules +.index rewriting||rules +The rewrite section of the configuration file consists of lines of rewriting +rules in the form +.display +<<source pattern>> <<replacement>> <<flags>> +.endd +Rewriting rules that are specified for the \headers@_rewrite\ generic transport +option are given as a colon-separated list. Each item in the list takes the +same form as a line in the main rewriting configuration +(except that any colons must be doubled, of course). + +The formats of source patterns and replacement strings are described below. +Each is terminated by white space, unless enclosed in double quotes, in which +case normal quoting conventions apply inside the quotes. The flags are single +characters which may appear in any order. Spaces and tabs between them are +ignored. + +For each address that could potentially be rewritten, the rules are scanned in +order, and replacements for the address from earlier rules can themselves be +replaced by later rules (but see the `q' and `R' flags). + +The order in which addresses are rewritten is undefined, may change between +releases, and must not be relied on, with one exception: when a message is +received, the envelope sender is always rewritten first, before any header +lines are rewritten. For example, the replacement string for a rewrite of an +address in ::To:: must not assume that the message's address in ::From:: has (or +has not) already been rewritten. However, a rewrite of ::From:: may assume that +the envelope sender has already been rewritten. + +The variables \$local@_part$\ and \$domain$\ can be used in the replacement +string to refer to the address that is being rewritten. Note that lookup-driven +rewriting can be done by a rule of the form +.display asis +*@* ${lookup ... +.endd +where the lookup key uses \$1$\ and \$2$\ or \$local@_part$\ and \$domain$\ to +refer to the address that is being rewritten. + +.section Rewriting patterns +.index rewriting||patterns +.index address list||in a rewriting pattern +The source pattern in a rewriting rule is any item which may appear in an +address list (see section ~~SECTaddresslist). It is in fact processed as a +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 +can use a regular expression that starts with \"^(?i)"\. + +.index numerical variables (\$1$\, \$2$\, etc)||in rewriting rules +After matching, the numerical variables \$1$\, \$2$\, etc. may be set, +depending on the type of match which occurred. These can be used in the +replacement string to insert portions of the incoming address. \$0$\ always +refers to the complete incoming address. When a regular expression is used, the +numerical variables are set from its capturing subexpressions. For other types +of pattern they are set as follows: + +.numberpars $. +If a local part or domain starts with an asterisk, the numerical variables +refer to the character strings matched by asterisks, with \$1$\ associated with +the first asterisk, and \$2$\ with the second, if present. For example, if the +pattern +.display +*queen@@*.fict.example +.endd +is matched against the address \*hearts-queen@@wonderland.fict.example*\ then +.display asis +$0 = hearts-queen@wonderland.fict.example +$1 = hearts- +$2 = wonderland +.endd +Note that if the local part does not start with an asterisk, but the domain +does, it is \$1$\ that contains the wild part of the domain. +.nextp +If the domain part of the pattern is a partial lookup, the wild and fixed parts +of the domain are placed in the next available numerical variables. Suppose, +for example, that the address \*foo@@bar.baz.example*\ is processed by a +rewriting rule of the form +.display +*@@partial-dbm;/some/dbm/file <<replacement string>> +.endd +and the key in the file that matches the domain is \"*.baz.example"\. Then +.display asis +$1 = foo +$2 = bar +$3 = baz.example +.endd +If the address \*foo@@baz.example*\ is looked up, this matches the same +wildcard file entry, and in this case \$2$\ is set to the empty string, but +\$3$\ is still set to \*baz.example*\. If a non-wild key is matched in a +partial lookup, \$2$\ is again set to the empty string and \$3$\ is set to the +whole domain. For non-partial domain lookups, no numerical variables are set. +.endp + +.section Rewriting replacements +.index rewriting||replacements +If the replacement string for a rule is a single asterisk, addresses that +match the pattern and the flags are $it{not} rewritten, and no subsequent +rewriting rules are scanned. For example, +.display asis +hatta@lookingglass.fict.example * f +.endd +specifies that \*hatta@@lookingglass.fict.example*\ is never to be rewritten in +::From:: headers. + +If the replacement string is not a single asterisk, it is expanded, and must +yield a fully qualified address. Within the expansion, the variables +\$local@_part$\ and \$domain$\ refer to the address that is being rewritten. +Any letters they contain retain their original case -- they are not lower +cased. The numerical variables are set up according to the type of pattern that +matched the address, as described above. If the expansion is forced to fail by +the presence of `fail' in a conditional or lookup item, rewriting by the +current rule is abandoned, but subsequent rules may take effect. Any other +expansion failure causes the entire rewriting operation to be abandoned, and an +entry written to the panic log. + + +.section Rewriting flags +There are three different kinds of flag that may appear on rewriting rules: +.numberpars $. +Flags that specify which headers and envelope addresses to rewrite: E, F, T, b, +c, f, h, r, s, t. +.nextp +A flag that specifies rewriting at SMTP time: S. +.nextp +Flags that control the rewriting process: Q, q, R, w. +.endp +For rules that are part of the \headers@_rewrite\ generic transport option, +E, F, T, and S are not permitted. + + +.section Flags specifying which headers and envelope addresses to rewrite +.index rewriting||flags +If none of the following flag letters, nor the `S' flag (see section +~~SECTrewriteS) are present, a main rewriting rule applies to all headers and +to both the sender and recipient fields of the envelope, whereas a +transport-time rewriting rule just applies to all headers. Otherwise, the +rewriting rule is skipped unless the relevant addresses are being processed. +.display +E $rm{rewrite all envelope fields} +F $rm{rewrite the envelope From field} +T $rm{rewrite the envelope To field} +b $rm{rewrite the ::Bcc:: header} +c $rm{rewrite the ::Cc:: header} +f $rm{rewrite the ::From:: header} +h $rm{rewrite all headers} +r $rm{rewrite the ::Reply-To:: header} +s $rm{rewrite the ::Sender:: header} +t $rm{rewrite the ::To:: header} +.endd +You should be particularly careful about rewriting ::Sender:: headers, and +restrict this to special known cases in your own domains. + +.section The SMTP-time rewriting flag +.rset SECTrewriteS "~~chapter.~~section" +.index SMTP||rewriting malformed addresses +.index \\RCPT\\||rewriting argument of +.index \\MAIL\\||rewriting argument of +The rewrite flag `S' specifies a rewrite of incoming envelope addresses at SMTP +time, as soon as an address is received in a \\MAIL\\ or \\RCPT\\ command, and +before any other processing; even before syntax checking. The pattern is +required to be a regular expression, and it is matched against the whole of the +data for the command, including any surrounding angle brackets. + +This form of rewrite rule allows for the handling of addresses that are not +compliant with RFCs 2821 and 2822 (for example, `bang paths' in batched SMTP +input). Because the input is not required to be a syntactically valid address, +the variables \$local@_part$\ and \$domain$\ are not available during the +expansion of the replacement string. The result of rewriting replaces the +original address in the \\MAIL\\ or \\RCPT\\ command. + +.section Flags controlling the rewriting process +There are four flags which control the way the rewriting process works. These +take effect only when a rule is invoked, that is, when the address is of the +correct type (matches the flags) and matches the pattern: +.numberpars $. +If the `Q' flag is set on a rule, the rewritten address is permitted to be an +unqualified local part. It is qualified with \qualify@_recipient\. In the +absence of `Q' the rewritten address must always include a domain. +.nextp +If the `q' flag is set on a rule, no further rewriting rules are considered, +even if no rewriting actually takes place because of a `fail' in the expansion. +The `q' flag is not effective if the address is of the wrong type (does not +match the flags) or does not match the pattern. +.nextp +The `R' flag causes a successful rewriting rule to be re-applied to the new +address, up to ten times. It can be combined with the `q' flag, to stop +rewriting once it fails to match (after at least one successful rewrite). +.nextp +.index rewriting||whole addresses +When an address in a header is rewritten, the rewriting normally applies only +to the working part of the address, with any comments and RFC 2822 `phrase' +left unchanged. For example, rewriting might change +.display asis +From: Ford Prefect <fp42@restaurant.hitch.fict.example> +.endd +into +.display asis +From: Ford Prefect <prefectf@hitch.fict.example> +.endd +Sometimes there is a need to replace the whole address item, and this can be +done by adding the flag letter `w' to a rule. If this is set on a rule that +causes an address in a header line to be rewritten, the entire address is +replaced, not just the working part. The replacement must be a complete RFC +2822 address, including the angle brackets if necessary. If text outside angle +brackets contains a character whose value is greater than 126 or less than 32 +(except for tab), the text is encoded according to RFC 2047. +The character set is taken from \headers@_charset\, which defaults to +ISO-8859-1. + +When the `w' flag is set on a rule that causes an envelope address to be +rewritten, all but the working part of the replacement address is discarded. +.endp + +.section Rewriting examples +Here is an example of the two common rewriting paradigms: +.display asis +*@*.hitch.fict.example $1@hitch.fict.example +*@hitch.fict.example ${lookup{$1}dbm{/etc/realnames}\ + {$value}fail}@hitch.fict.example bctfrF +.endd +Note the use of `fail' in the lookup expansion in the second rule, forcing +the string expansion to fail if the lookup does not succeed. In this context it +has the effect of leaving the original address unchanged, but Exim goes on to +consider subsequent rewriting rules, if any, because the `q' flag is not +present in that rule. An alternative to `fail' would be to supply \$1$\ +explicitly, which would cause the rewritten address to be the same as before, +at the cost of a small bit of processing. Not supplying either of these is an +error, since the rewritten address would then contain no local part. + +The first example above replaces the domain with a superior, more general +domain. This may not be desirable for certain local parts. If the rule +.display asis +root@*.hitch.fict.example * +.endd +were inserted before the first rule, rewriting would be suppressed for the +local part \*root*\ at any domain ending in \*hitch.fict.example*\. + +Rewriting can be made conditional on a number of tests, by making use of +\${if$\ in the expansion item. For example, to apply a rewriting rule only to +messages that originate outside the local host: +.display asis +*@*.hitch.fict.example "${if !eq {$sender_host_address}{}\ + {$1@hitch.fict.example}fail}" +.endd +The replacement string is quoted in this example because it contains white +space. + +.index rewriting||bang paths +.index bang paths||rewriting +Exim does not handle addresses in the form of `bang paths'. If it sees such an +address it treats it as an unqualified local part which it qualifies with the +local qualification domain (if the source of the message is local or if the +remote host is permitted to send unqualified addresses). Rewriting can +sometimes be used to handle simple bang paths with a fixed number of +components. For example, the rule +.display asis +\N^([^!]+)!(.*)@your.domain.example$\N $2@$1 +.endd +rewrites a two-component bang path \*host.name!user*\ as the domain address +\*user@@host.name*\. However, there is a security implication in using this as +a global rewriting rule for envelope addresses. It can provide a backdoor +method for using your system as a relay, because the incoming addresses appear +to be local. If the bang path addresses are received via SMTP, it is safer to +use the `S' flag to rewrite them as they are received, so that relay checking +can be done on the rewritten addresses. + + + + + +. +. +. +. +. ============================================================================ +.chapter Retry configuration +.set runningfoot "retry configuration" +.rset CHAPretry ~~chapter +.index retry||configuration, description of +.index configuration file||retry section +The `retry' section of the run time configuration file contains a list of retry +rules which control how often Exim tries to deliver messages that cannot be +delivered at the first attempt. If there are no retry rules, temporary errors +are treated as permanent. The \-brt-\ command line option can be used to test +which retry rule will be used for a given address or domain. + +The most common cause of retries is temporary failure to deliver to a remote +host because the host is down, or inaccessible because of a network problem. +Exim's retry processing in this case is applied on a per-host (strictly, per IP +address) basis, not on a per-message basis. Thus, if one message has recently +been delayed, delivery of a new message to the same host is not immediately +tried, but waits for the host's retry time to arrive. If the \retry@_defer\ log +selector is set, the message +.index retry||time not reached +`retry time not reached' is written to the main log whenever a delivery is +skipped for this reason. Section ~~SECToutSMTPerr contains more details of the +handling of errors during remote deliveries. + +Retry processing applies to routing as well as to delivering, except as covered +in the next paragraph. The retry rules do not distinguish between these +actions. It is not possible, for example, to specify different behaviour for +failures to route the domain \*snark.fict.example*\ and failures to deliver to +the host \*snark.fict.example*\. I didn't think anyone would ever need this +added complication, so did not implement it. However, although they share the +same retry rule, the actual retry times for routing and transporting a given +domain are maintained independently. + +When a delivery is not part of a queue run (typically an immediate delivery on +receipt of a message), the routers are always run, and local deliveries are +always attempted, even if retry times are set for them. This makes for better +behaviour if one particular message is causing problems (for example, causing +quota overflow, or provoking an error in a filter file). If such a delivery +suffers a temporary failure, the retry data is updated as normal, and +subsequent delivery attempts from queue runs occur only when the retry time for +the local address is reached. + + +.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. + +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 +means that it is expanded before being tested against the address that has +been delayed. Address list processing treats a plain domain name as if it were +preceded by `*@@', which makes it possible for many retry rules to start with +just a domain. For example, +.display asis +lookingglass.fict.example * F,24h,30m; +.endd +provides a rule for any address in the \*lookingglass.fict.example*\ domain, +whereas +.display asis +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 +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. +.display +^@\Nxyz@\d+@\.abc@\.example@$@\N * G,1h,10m,2 \Wrong\ +^@\N[^@@]+@@xyz@\d+@\.abc@\.example@$@\N * G,1h,10m,2 \Right\ +.endd + + +.section Choosing which retry rule to use +When Exim is looking for a retry rule after a routing attempt has failed (for +example, after a DNS timeout), each line in the retry configuration is tested +against the complete address only if \retry__use@_local@_part\ is set for the +router. Otherwise, only the domain is used, except when matching against a +regular expression, when the local part of the address is replaced with `*'. A +domain on its own can match a domain pattern, or a pattern that starts with +`*@@'. By default, \retry@_use@_local@_part\ is true for routers where +\check@_local@_user\ is true, and false for other routers. + +Similarly, when Exim is looking for a retry rule after a local delivery has +failed (for example, after a mailbox full error), each line in the retry +configuration is tested against the complete address only if +\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 +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 +the line, the domain from the email address is tried in a similar fashion. For +example, suppose the MX records for \*a.b.c.example*\ are +.display asis +a.b.c.example MX 5 x.y.z.example + MX 6 p.q.r.example + MX 7 m.n.o.example +.endd +and the retry rules are +.display asis +p.q.r.example * F,24h,30m; +a.b.c.example * F,4d,45m; +.endd +and a delivery to the host \*x.y.z.example*\ fails. The first rule matches +neither the host nor the domain, so Exim looks at the second rule. This does +not match the host, but it does match the domain, so it is used to calculate +the retry time for the host \*x.y.z.example*\. Meanwhile, Exim tries to deliver +to \*p.q.r.example*\. If this fails, the first retry rule is used, because it +matches the host. + +In other words, failures to deliver to host \*p.q.r.example*\ use the first +rule to determine retry times, but for all the other hosts for the domain +\*a.b.c.example*\, the second rule is used. The second rule is also used if +routing to \*a.b.c.example*\ suffers a temporary failure. + +.section Retry rules for specific errors +.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 +.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. + +.em +.index mailbox||time of last read +\**Warning**\: It is not always possible to determine a `time of last read' for +a mailbox: +.numberpars $. +If the mailbox is a single file, the time of last access is used. +.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. +.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 +.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 +.display +<<letter>>,<<cutoff time>>,<<arguments>> +.endd +The letter identifies the algorithm for computing a new retry time; the cutoff +time is the time beyond which this algorithm no longer applies, and the +arguments vary the algorithm's action. The cutoff time is measured from the +time that the first failure for the domain (combined with the local part if +relevant) was detected, not from the time the message was received. +.index retry||algorithms +The available algorithms are: +.numberpars $. +\*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. +.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 +used to compute a new retry time that is later than the current time. In the +case of fixed interval retries, this simply means adding the interval to the +current time. For geometrically increasing intervals, retry intervals are +computed from the rule's parameters until one that is greater than the previous +interval is found. The main configuration variable +.index limit||retry interval +.index retry||interval, maximum +.index \retry@_interval@_max\ +\retry@_interval@_max\ limits the maximum interval between retries. + +A single remote domain may have a number of hosts associated with it, and each +host may have more than one IP address. Retry algorithms are selected on the +basis of the domain name, but are applied to each IP address independently. If, +for example, a host has two IP addresses and one is unusable, Exim will +generate retry times for it and will not try to use it until its next retry +time comes. Thus the good IP address is likely to be tried first most of the +time. + +.index hints database||use for retrying +Retry times are hints rather than promises. Exim does not make any attempt to +run deliveries exactly at the computed times. Instead, a queue runner process +starts delivery processes for delayed messages periodically, and these attempt +new deliveries only for those addresses that have passed their next retry time. +If a new message arrives for a deferred address, an immediate delivery attempt +occurs only if the address has passed its retry time. In the absence of new +messages, the minimum time between retries is the interval between queue runner +processes. There is not much point in setting retry times of five minutes if +your queue runners happen only once an hour, unless there are a significant +number of incoming messages (which might be the case on a system that is +sending everything to a smart host, for example). + +The data in the retry hints database can be inspected by using the +\*exim@_dumpdb*\ or \*exim@_fixdb*\ utility programs (see chapter ~~CHAPutils). The +latter utility can also be used to change the data. The \*exinext*\ utility +script can be used to find out what the next retry times are for the hosts +associated with a particular mail domain, and also for local deliveries that +have been deferred. + +.section Retry rule examples +Here are some example retry rules: +.display asis +alice@wonderland.fict.example quota_5d F,7d,3h +wonderland.fict.example quota_5d +wonderland.fict.example * F,1h,15m; G,2d,1h,2; +lookingglass.fict.example * F,24h,30m; +* refused_A F,2h,20m; +* * F,2h,15m; G,16h,1h,1.5; F,5d,8h +.endd +The first rule sets up special handling for mail to +\*alice@@wonderland.fict.example*\ when there is an over-quota error and the +mailbox has not been read for at least 5 days. Retries continue every three +hours for 7 days. The second rule handles over-quota errors for all other local +parts at \*wonderland.fict.example*\; the absence of a local part has the same +effect as supplying `$*$@@'. As no retry algorithms are supplied, messages that +fail are bounced immediately if the mailbox has not been read for at least 5 +days. + +The third rule handles all other errors at \*wonderland.fict.example*\; retries +happen every 15 minutes for an hour, then with geometrically increasing +intervals until two days have passed since a delivery first failed. After the +first hour there is a delay of one hour, then two hours, then four hours, and +so on (this is a rather extreme example). + +The fourth rule controls retries for the domain \*lookingglass.fict.example*\. +They happen every 30 minutes for 24 hours only. The remaining two rules handle +all other domains, with special action for connection refusal from hosts that +were not obtained from an MX record. + +The final rule in a retry configuration should always have asterisks in the +first two fields so as to provide a general catch-all for any addresses that do +not have their own special handling. This example tries every 15 minutes for 2 +hours, then with intervals starting at one hour and increasing by a factor of +1.5 up to 16 hours, then every 8 hours up to 5 days. + + +.section Timeout of retry data +.index timeout||of retry data +.index \retry@_data@_expire\ +.index hints database||data expiry +.index retry||timeout of data +Exim timestamps the data that it writes to its retry hints database. When it +consults the data during a delivery it ignores any that is older than the value +set in \retry@_data@_expire\ (default 7 days). If, for example, a host hasn't +been tried for 7 days, Exim will try to deliver to it immediately a message +arrives, and if that fails, it will calculate a retry time as if it were +failing for the first time. + +This improves the behaviour for messages routed to rarely-used hosts such as MX +backups. If such a host was down at one time, and happens to be down again when +Exim tries a month later, using the old retry data would imply that it had been +down all the time, which is not a justified assumption. + +If a host really is permanently dead, this behaviour causes a burst of retries +every now and again, but only if messages routed to it are rare. It there is a +message at least once every 7 days the retry data never expires. + + + +.section Long-term failures +.index delivery||failure, long-term +.index retry||after long-term failure +Special processing happens when an email address has been failing for so long +that the cutoff time for the last algorithm is reached. For example, using the +default retry rule: +.display asis +* * F,2h,15m; G,16h,1h,1.5; F,4d,6h +.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. + +When the cutoff time is reached for a local delivery, or for all the IP +addresses associated with a remote delivery, a subsequent delivery failure +causes Exim to give up on the address, and a bounce message is generated. +In order to cater for new messages that use the failing address, a next retry +time is still computed from the final algorithm, and is used as follows: + +For local deliveries, one delivery attempt is always made for any subsequent +messages. If this delivery fails, the address fails immediately. The +post-cutoff retry time is not used. + +If the delivery is remote, there are two possibilities, controlled by the +.index \delay@_after@_cutoff\ +\delay@_after@_cutoff\ option of the \%smtp%\ transport. The option is true by +default and in that case: +.numberpars " " +Until the post-cutoff retry time for one of the IP addresses is reached, +the failing email address is bounced immediately, without a delivery attempt +taking place. After that time, one new delivery attempt is made to those IP +addresses that are past their retry times, and if that still fails, the address +is bounced and new retry times are computed. +.endp + +In other words, when all the hosts for a given email address have been failing +for a long time, Exim bounces rather then defers until one of the hosts' retry +times is reached. Then it tries once, and bounces if that attempt fails. This +behaviour ensures that few resources are wasted in repeatedly trying to deliver +to a broken destination, but if the host does recover, Exim will eventually +notice. + +If \delay@_after@_cutoff\ is set false, Exim behaves differently. If all IP +addresses are past their final cutoff time, Exim tries to deliver to those IP +addresses that have not been tried since the message arrived. If there are +no suitable IP addresses, or if they all fail, the address is bounced. In other +words, it does not delay when a new message arrives, but tries the expired +addresses immediately, unless they have been tried since the message arrived. +If there is a continuous stream of messages for the failing domains, setting +\delay@_after@_cutoff\ false means that there will be many more attempts to +deliver to permanently failing IP addresses than when \delay@_after@_cutoff\ is +true. + +.section Ultimate address timeout +.index retry||ultimate address timeout +An additional rule is needed to cope with cases where a host is intermittently +available, or when a message has some attribute that prevents its delivery when +others to the same address get through. In this situation, because some +messages are successfully delivered, the `retry clock' for the address keeps +getting restarted, and so a message could remain on the queue for ever. To +prevent this, if a message has been on the queue for longer than the cutoff +time of any applicable retry rule for a given address, a delivery is attempted +for that address, even if it is not yet time, and if this delivery fails, the +address is timed out. A new retry time is not computed in this case, so that +other messages for the same address are considered immediately. + + + + + +. +. +. +. +. ============================================================================ +.chapter SMTP authentication +.set runningfoot "SMTP authentication" +.rset CHAPSMTPAUTH "~~chapter" +.index SMTP||authentication configuration +.index authentication +The `authenticators' section of Exim's run time configuration is concerned with +SMTP authentication. This facility is an extension to the SMTP protocol, +described in RFC 2554, which allows a client SMTP host to authenticate itself +to a server. This is a common way for a server to recognize clients that +are permitted to use it as a relay. SMTP authentication is not of relevance to +the transfer of mail between servers that have no managerial connection with +each other. + +.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 client's \\EHLO\\ command. +.nextp +The client issues an \\AUTH\\ command, naming a specific mechanism. The command +may, optionally, contain some authentication data. +.nextp +The server may issue one or more \*challenges*\, to which the client must send +appropriate responses. In simple authentication mechanisms, the challenges are +just prompts for user names and passwords. The server does not have to issue +any challenges -- in some mechanisms the relevant data may all be transmitted +with the \\AUTH\\ command. +.nextp +The server either accepts or denies authentication. +.nextp +If authentication succeeds, the client may optionally make use of the \\AUTH\\ +option on the \\MAIL\\ command to pass an authenticated sender in subsequent +mail transactions. Authentication lasts for the remainder of the SMTP +connection. +.nextp +If authentication fails, the client may give up, or it may try a different +authentication mechanism, or it may try transferring mail over the +unauthenticated connection. +.endp +If you are setting up a client, and want to know which authentication +mechanisms the server supports, you can use Telnet to connect to port 25 (the +SMTP port) on the server, and issue an \\EHLO\\ command. The response to this +includes the list of supported mechanisms. For example: +.display +@$ $cb{telnet server.example 25} +Trying 192.168.34.25... +Connected to server.example. +Escape character is '@^]'. +220 server.example ESMTP Exim 4.20 ... +$cb{ehlo client.example} +250-server.example Hello client.example [10.8.4.5] +250-SIZE 52428800 +250-PIPELINING +250-AUTH PLAIN +250 HELP +.endd +The second-last line of this example output shows that the server supports +authentication using the PLAIN mechanism. In Exim, the different authentication +mechanisms are configured by specifying \*authenticator*\ drivers. Like the +routers and transports, which authenticators are included in the binary is +controlled by build-time definitions. The following are currently available, +included by setting +.display asis +AUTH_CRAM_MD5=yes +AUTH_PLAINTEXT=yes +AUTH_SPA=yes +.endd +in \(Local/Makefile)\, respectively. The first of these supports the CRAM-MD5 +authentication mechanism (RFC 2195), and the second can be configured to +support the PLAIN authentication mechanism (RFC 2595) or the LOGIN mechanism, +which is not formally documented, but used by several MUAs. The third +authenticator supports Microsoft's \*Secure Password Authentication*\ +mechanism. + +The authenticators are configured using the same syntax as other drivers (see +section ~~SECTfordricon). If no authenticators are required, no authentication +section need be present in the configuration file. Each authenticator can in +principle have both server and client functions. When Exim is receiving SMTP +mail, it is acting as a server; when it is sending out messages over SMTP, it +is acting as a client. Authenticator configuration options are provided for use +in both these circumstances. + +To make it clear which options apply to which situation, the prefixes +\server@_\ and \client@_\ are used on option names that are specific to either +the server or the client function, respectively. Server and client functions +are disabled if none of their options are set. If an authenticator is to be +used for both server and client functions, a single definition, using both sets +of options, is required. For example: +.display asis +cram: + driver = cram_md5 + public_name = CRAM-MD5 + server_secret = ${if eq{$1}{ph10}{secret1}fail} + client_name = ph10 + client_secret = secret2 +.endd +The \server@_\ option is used when Exim is acting as a server, and the +\client@_\ options when it is acting as a client. + +Descriptions of the individual authenticators are given in subsequent chapters. +The remainder of this chapter covers the generic options for the +authenticators, followed by general discussion of the way authentication works +in Exim. + + +.section Generic options for authenticators +.index authentication||generic options + +.startconf +.index options||generic, for authenticators + +.conf driver string unset +This option must always be set. It specifies which of the available +authenticators is to be used. + +.conf public@_name string unset +This option specifies the name of the authentication mechanism that the driver +implements, and by which it is known to the outside world. These names should +contain only upper case letters, digits, underscores, and hyphens (RFC 2222), +but Exim in fact matches them caselessly. If \public@_name\ is not set, it +defaults to the driver's instance name. + +.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 +forced, and was not caused by a lookup defer, the incident is logged. +See section ~~SECTauthexiser below for further discussion. + +.conf server@_debug@_print string$**$ unset +If this option is set and authentication debugging is enabled (see the \-d-\ +command line option), the string is expanded and included in the debugging +output when the authenticator is run as a server. This can help with checking +out the values of variables. +If expansion of the string fails, the error message is written to the debugging +output, and Exim carries on processing. + +.conf server@_set@_id string$**$ unset +When an Exim server successfully authenticates a client, this string is +expanded using data from the authentication, and preserved for any incoming +messages in the variable \$authenticated@_id$\. It is also included in the log +lines for incoming messages. For example, a user/password authenticator +configuration might preserve the user name that was used to authenticate, and +refer to it subsequently during delivery of the message. +If expansion fails, the option is ignored. + +.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 +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. +How it is used is described in the following section. +.endconf + + + +.section The AUTH parameter on MAIL commands +.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 +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 +than \\EHLO\\), the use of \\AUTH=\\ is a syntax error. +.nextp +If the value of the \\AUTH=\\ parameter is `@<@>', it is ignored. +.nextp +If \acl@_smtp@_mailauth\ is defined, the ACL it specifies is run. While it is +running, the value of \$authenticated@_sender$\ is set to the value obtained +from the \\AUTH=\\ parameter. If the ACL does not yield `accept', the value of +\$authenticated@_sender$\ is deleted. The \acl@_smtp@_mailauth\ ACL may not +return `drop' or `discard'. If it defers, a temporary error code (451) is given +for the \\MAIL\\ command. +.nextp +If \acl@_smtp@_mailauth\ is not defined, the value of the \\AUTH=\\ parameter +is accepted and placed in \$authenticated@_sender$\ only if the client has +authenticated. +.nextp +If the \\AUTH=\\ value was accepted by either of the two previous rules, and +the client has authenticated, and the authenticator has a setting for the +\server@_mail@_auth@_condition\, the condition is checked at this point. The +valued that was saved from the authenticator is expanded. If the expansion +fails, or yields an empty string, `0', `no', or `false', the value of +\$authenticated__sender$\ is deleted. If the expansion yields any other value, +the value of \$authenticated@_sender$\ is retained and passed on with the +message. +.endp + +When \$authenticated@_sender$\ is set for a message, it is passed on to other +hosts to which Exim authenticates as a client. Do not confuse this value with +\$authenticated@_id$\, which is a string obtained from the authentication +process, and which is not usually a complete email address. + +Whenever an \\AUTH=\\ value is ignored, the incident is logged. The ACL for +\\MAIL\\, if defined, is run after \\AUTH=\\ is accepted or ignored. It can +therefore make use of \$authenticated@_sender$\. The converse is not true: the +value of \$sender@_address$\ is not yet set up when the \acl@_smtp@_mailauth\ +ACL is run. + + +.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 +conditions: +.numberpars $. +The client host must match \auth@_advertise@_hosts\ (default $*$). +.nextp +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 mechanisms are advertised. + +Some mail clients (for example, some versions of Netscape) require the user to +provide a name and password for authentication whenever \\AUTH\\ is advertised, +even though authentication may not in fact be needed (for example, Exim may be +set up to allow unconditional relaying from the client by an IP address check). +You can make such clients more friendly by not advertising \\AUTH\\ to them. +For example, if clients on the 10.9.8.0/24 network are permitted (by the ACL +that runs for \\RCPT\\) to relay without authentication, you should set +.display asis +auth_advertise_hosts = ! 10.9.8.0/24 +.endd +so that no authentication mechanisms are advertised to them. + +The \server@_advertise@_condition\ controls the advertisement of individual +authentication mechanisms. For example, it can be used to restrict the +advertisement of a patricular mechanism to encrypted connections, by a setting +such as: +.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 +yields `yes', which allows the advertisement to happen. + +When an Exim server receives an \\AUTH\\ command from a client, it rejects it +immediately if \\AUTH\\ was not advertised in response to an earlier \\EHLO\\ +command. This is the case if +.numberpars $. +The client host does not match \auth@_advertise@_hosts\; or +.nextp +No authenticators are configured with server options; or +.nextp +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. + +If \\AUTH\\ is not rejected by the ACL, Exim searches its configuration for a +server authentication mechanism that was advertised in response to \\EHLO\\ and +that matches the one named in the \\AUTH\\ command. If it finds one, it runs +the appropriate authentication protocol, and authentication either succeeds or +fails. If there is no matching advertised mechanism, the \\AUTH\\ command is +rejected with a 504 error. + +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. + + + +.section Testing server authentication +.index authentication||testing a server +.index \\AUTH\\||testing a server +.index base64 encoding||creating authentication test data +Exim's \-bh-\ option can be useful for testing server authentication +configurations. The data for the \\AUTH\\ command has to be sent using base64 +encoding. A quick way to produce such data for testing is the following Perl +script: +.display asis +use MIME::Base64; +printf ("%s", encode_base64(eval "\"$ARGV[0]\"")); +.endd +.index binary zero||in authentication data +This interprets its argument as a Perl string, and then encodes it. The +interpretation as a Perl string allows binary zeros, which are required for +some kinds of authentication, to be included in the data. For example, a +command line to run this script on such data might be +.display asis +encode '\0user\0password' +.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. + +\**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 +example, a command such as +.display asis +encode '\0user@domain.com\0pas$$word' +.endd +gives an incorrect answer because of the unescaped `@@' and `@$' characters. + +If you have the \mimencode\ command installed, another way to do produce +base64-encoded strings is to run the command +.display asis +echo -e -n `\0user\0password' | mimencode +.endd +The \-e-\ option of \echo\ enables the interpretation of backslash escapes in +the argument, and the \-n-\ option specifies no newline at the end of its +output. However, not all versions of \echo\ recognize these options, so you +should check your version before relying on this suggestion. + + +.section Authentication by an Exim client +.index authentication||on an Exim client +The \%smtp%\ transport has two options called \hosts@_require@_auth\ and +\hosts@_try@_auth\. When the \%smtp%\ transport connects to a server that +announces support for authentication, and the host matches an entry in either +of these options, Exim (as a client) tries to authenticate as follows: +.numberpars $. +For each authenticator that is configured as a client, it searches the +authentication mechanisms announced by the server for one whose name +matches the public name of the authenticator. +.nextp +When it finds one that matches, it runs the authenticator's client code. +The variables \$host$\ and \$host@_address$\ are available for any string +expansions that the client might do. They are set to the server's name and +IP address. If any expansion is forced to fail, the authentication attempt +is abandoned, +and Exim moves on to the next authenticator. +Otherwise an expansion failure causes delivery to be +deferred. +.nextp +If the result of the authentication attempt is a temporary error or a timeout, +Exim abandons trying to send the message to the host for the moment. It will +try again later. If there are any backup hosts available, they are tried in the +usual way. +.nextp +If the response to authentication is a permanent error (5xx code), Exim carries +on searching the list of authenticators and tries another one if possible. If +all authentication attempts give permanent errors, or if there are no attempts +because no mechanisms match +(or option expansions force failure), +what happens depends on whether the host matches \hosts@_require@_auth\ or +\hosts@_try@_auth\. In the first case, a temporary error is generated, and +delivery is deferred. The error can be detected in the retry rules, and thereby +turned into a permanent error if you wish. In the second case, Exim tries to +deliver the message unauthenticated. +.endp +.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 +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 +\qualify@_domain\ is treated as authenticated. However, if the +\authenticated@_sender\ option is set on the \%smtp%\ transport, it overrides +the authenticated sender that was received with the message. + + + + + + +. +. +. +. +. ============================================================================ +.chapter The plaintext authenticator +.rset CHAPplaintext "~~chapter" +.set runningfoot "plaintext authenticator" +.index \%plaintext%\ authenticator +.index authenticators||\%plaintext%\ +The \%plaintext%\ authenticator can be configured to support the PLAIN and +LOGIN authentication mechanisms, both of which transfer authentication data as +plain (unencrypted) text (though base64 encoded). The use of plain text is a +security risk. If you use one of these mechanisms without also making use of +SMTP encryption (see chapter ~~CHAPTLS) you should not use the same passwords +for SMTP connections as you do for login accounts. + +.section Using plaintext in a server +When running as a server, \%plaintext%\ performs the authentication test by +expanding a string. It has the following options: + +.startconf +.index options||\%plaintext%\ authenticator (server) + +.conf server@_prompts string$**$ unset +The contents of this option, after expansion, must be a colon-separated list of +prompt strings. If expansion fails, a temporary authentication rejection is +given. + +.conf server@_condition string$**$ unset +This option must be set in order to configure the driver as a server. Its use +is described below. + +.endconf + +.index \\AUTH\\||in \%plaintext%\ authenticator +.index binary zero||in \%plaintext%\ authenticator +.index numerical variables (\$1$\, \$2$\, etc)||in \%plaintext%\ authenticator +.index base64 encoding||in \%plaintext%\ authenticator +The data sent by the client with the \\AUTH\\ command, or in response to +subsequent prompts, is base64 encoded, and so may contain any byte values +when decoded. If any data is supplied with the command, it is treated as a +list of strings, separated by NULs (binary zeros), which are placed in the +expansion variables \$1$\, \$2$\, etc. If there are more strings in +\server@_prompts\ than the number of strings supplied with the \\AUTH\\ +command, the remaining prompts are used to obtain more data. Each response from +the client may be a list of NUL-separated strings. + +Once a sufficient number of data strings have been received, +\server@_condition\ is expanded. +If the expansion is forced to fail, authentication fails. Any other expansion +failure causes a temporary error code to be returned. +If the result of a successful expansion is an empty string, `0', `no', or +`false', authentication fails. If the result of the expansion is `1', `yes', or +`true', authentication succeeds and the generic \server@_set@_id\ option is +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. +There are good and bad examples at the end of the next section. + + +.section The PLAIN authentication mechanism +.index PLAIN authentication mechanism +.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 +separators). The data is sent either as part of the \\AUTH\\ command, or +subsequently in response to an empty prompt from the server. + +The second and third strings are a user name and a corresponding password. +Using a single fixed user name and password as an example, this could be +configured as follows: +.display asis +fixed_plain: + driver = plaintext + public_name = PLAIN + server_prompts = : + server_condition = \ + ${if and {{eq{$2}{username}}{eq{$3}{mysecret}}}{yes}{no}} + server_set_id = $2 +.endd +The \server@_prompts\ setting specifies a single, empty prompt (empty items at +the end of a string list are ignored). If all the data comes as part of the +\\AUTH\\ command, as is commonly the case, the prompt is not used. This +authenticator is advertised in the response to \\EHLO\\ as +.display asis +250-AUTH PLAIN +.endd +and a client host can authenticate itself by sending the command +.display asis +AUTH PLAIN AHVzZXJuYW1lAG15c2VjcmV0 +.endd +As this contains three strings (more than the number of prompts), no further +data is required from the client. Alternatively, the client may just send +.display asis +AUTH PLAIN +.endd +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 +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 +comparison (see \crypteq\ in chapter ~~CHAPexpand). Here is a example of this +approach, where the passwords are looked up in a DBM file. \**Warning**\: This +is an incorrect example: +.display asis +server_condition = \ + ${if eq{$3}{${lookup{$2}dbm{/etc/authpwd}}}{yes}{no}} +.endd +The expansion uses the user name (\$2$\) as the key to look up a password, +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 +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}} +.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 +first example is in fact safe, because \crypteq\ always fails if its second +argument is empty. However, the second way of writing the test makes the logic +clearer. + + +.section The LOGIN authentication mechanism +.index LOGIN authentication mechanism +.index authentication||LOGIN mechanism +The LOGIN authentication mechanism is not documented in any RFC, but is in use +in a number of programs. No data is sent with the \\AUTH\\ command. Instead, a +user name and password are supplied separately, in response to prompts. The +plaintext authenticator can be configured to support this as in this example: +.display asis +fixed_login: + driver = plaintext + public_name = LOGIN + server_prompts = User Name : Password + server_condition = \ + ${if and {{eq{$1}{username}}{eq{$2}{mysecret}}}{yes}{no}} + server_set_id = $1 +.endd +Because of the way plaintext operates, this authenticator accepts data supplied +with the \\AUTH\\ command (in contravention of the specification of LOGIN), but +if the client does not supply it (as is the case for LOGIN clients), the prompt +strings are used to obtain two data items. + +Some clients are very particular about the precise text of the prompts. For +example, Outlook Express is reported to recognize only `Username:' and +`Password:'. Here is an example of a LOGIN authenticator which uses those +strings, and which uses the \ldapauth\ expansion condition to check the user +name and password by binding to an LDAP server: +.display asis +login: + driver = plaintext + public_name = LOGIN + server_prompts = Username:: : Password:: + server_condition = ${if ldapauth \ +.newline + {user="cn=${quote_ldap_dn:$1},ou=people,o=example.org" \ + pass=${quote:$2} \ +.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 level, the password is an uninterpreted string. + + +.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, +Radius, \ldapauth\, and \*pwcheck*\. For details see section ~~SECTexpcond. + + + +.section Using plaintext in a client +The \%plaintext%\ authenticator has just one client option: + +.startconf +.index options||\%plaintext%\ authenticator (client) + +.conf client@_send string$**$ unset +The string is a colon-separated list of authentication data strings. Each +string is independently expanded before being sent to the server. The first +string is sent with the \\AUTH\\ command; any more strings are sent in response +to prompts from the server. + +\**Note**\: you cannot use expansion to create multiple strings, because +splitting takes priority and happens first. + +Because the PLAIN authentication mechanism requires NUL (binary zero) bytes in +the data, further processing is applied to each string before it is sent. If +there are any single circumflex characters in the string, they are converted to +NULs. Should an actual circumflex be required as data, it must be doubled in +the string. + +.endconf + +This is an example of a client configuration that implements the PLAIN +authentication mechanism with a fixed user name and password: +.display asis +fixed_plain: + driver = plaintext + public_name = PLAIN + client_send = ^username^mysecret +.endd +The lack of colons means that the entire text is sent with the \\AUTH\\ +command, with the circumflex characters converted to NULs. A similar example +that uses the LOGIN mechanism is: +.display asis +fixed_login: + driver = plaintext + public_name = LOGIN + client_send = : username : mysecret +.endd +The initial colon means that the first string is empty, so no data is sent with +the \\AUTH\\ command itself. The remaining strings are sent in response to +prompts. + + + + +. +. +. +. +. ============================================================================ +.chapter The cram@_md5 authenticator +.set runningfoot "cram@_md5 authenticator" +.index \%cram@_md5%\ authenticator +.index authenticators||\%cram@_md5%\ +.index CRAM-MD5 authentication mechanism +.index authentication||CRAM-MD5 mechanism +The CRAM-MD5 authentication mechanism is described in RFC 2195. The server +sends a challenge string to the client, and the response consists of a user +name and the CRAM-MD5 digest of the challenge string combined with a secret +string (password) which is known to both server and client. Thus, the secret +is not sent over the network as plain text, which makes this authenticator more +secure than \%plaintext%\. However, the downside is that the secret has to be +available in plain text at either end. + +.section Using cram@_md5 as a server +This authenticator has one server option, which must be set to configure the +authenticator as a server: + +.startconf +.index options||\%cram@_md5%\ authenticator (server) + +.conf server@_secret string$**$ unset +.index numerical variables (\$1$\, \$2$\, etc)||in \%cram@_md5%\ authenticator +When the server receives the client's response, the user name is placed in +the expansion variable \$1$\, and \server@_secret\ is expanded to obtain the +password for that user. The server then computes the CRAM-MD5 digest that the +client should have sent, and checks that it received the correct string. If the +expansion of \server@_secret\ is forced to fail, authentication fails. If the +expansion fails for some other reason, a temporary error code is returned to +the client. + +.endconf + +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. +.display asis +fixed_cram: + driver = cram_md5 + public_name = CRAM-MD5 + server_secret = ${if eq{$1}{ph10}{secret}fail} + server_set_id = $1 +.endd +If authentication succeeds, the setting of \server@_set@_id\ preserves the user +name in \$authenticated@_id$\. +A more tyical configuration might look up the secret string in a file, using +the user name as the key. For example: +.display asis +lookup_cram: + driver = cram_md5 + public_name = CRAM-MD5 + server_secret = ${lookup{$1}lsearch{/etc/authpwd}{$value}fail} + server_set_id = $1 +.endd +Note that this expansion explicitly forces failure if the lookup fails +because \$1$\ contains an unknown user name. + +.section Using cram@_md5 as a client +When used as a client, the \%cram@_md5%\ authenticator has two options: + +.startconf +.index options||\%cram@_md5%\ authenticator (client) + +.conf client@_name string$**$ "the primary host name" +This string is expanded, and the result used as the user name data when +computing the response to the server's challenge. + +.conf client@_secret string$**$ unset +This option must be set for the authenticator to work as a client. Its value is +expanded and the result used as the secret string when computing the response. + +.endconf + +Different user names and secrets can be used for different servers by referring +to \$host$\ or \$host@_address$\ in the options. + +Forced failure of either expansion string is treated as an indication that this +authenticator is not prepared to handle this case. Exim moves on to the next +configured client authenticator. Any other expansion failure causes Exim to +give up trying to send the message to the current server. + +A simple example configuration of a \%cram@_md5%\ authenticator, using fixed +strings, is: +.display asis +fixed_cram: + driver = cram_md5 + public_name = CRAM-MD5 + client_name = ph10 + client_secret = secret +.endd + + + + + +. +. +. +. +. ============================================================================ +.chapter The spa authenticator +.set runningfoot "spa authenticator" +.index \%spa%\ authenticator +.index authenticators||\%spa%\ +.index authentication||Microsoft Secure Password +.index authentication||NTLM +.index Microsoft Secure Password Authentication +.index NTLM authentication +The \%spa%\ authenticator provides client support for Microsoft's \*Secure +Password Authentication*\ mechanism, +which is also sometimes known as NTLM (NT LanMan). The code for client side of +this authenticator was contributed by Marc Prud'hommeaux, and much of it is +taken from the Samba project (\?http://www.samba.org?\). The code for the +server side was subsequently contributed by Tom Kistner. + +The mechanism works as follows: +.numberpars $. +After the \\AUTH\\ command has been accepted, the client sends an SPA +authentication request based on the user name and optional domain. +.nextp +The server sends back a challenge. +.nextp +The client builds a challenge response which makes use of the user's password +and sends it to the server, which then accepts or rejects it. +.endp +Encryption is used to protect the password in transit. + + +.section Using spa as a server +The \%spa%\ authenticator has just one server option: + +.startconf +.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 +authenticating user, whose name is at this point in \$1$\. For example: +.display asis +spa: + driver = 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 +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 +.index options||\%spa%\ authenticator (client) + +.conf client@_domain string$**$ unset +This option specifies an optional domain for the authentication. + +.conf client@_password string$**$ unset +This option specifies the user's password, and must be set. + +.conf client@_username string$**$ unset +This option specifies the user name, and must be set. + +.endconf + +Here is an example of a configuration of this authenticator for use with the +mail servers at \*msn.com*\: +.display asis +msn: + driver = spa + public_name = MSN + client_username = msn/msn_username + client_password = msn_plaintext_password + client_domain = DOMAIN_OR_UNSET +.endd + + + + + + +. +. +. +. +. ============================================================================ +.chapter Encrypted SMTP connections using TLS/SSL +.set runningfoot "TLS encryption" +.rset CHAPTLS "~~chapter" +.index encryption||on SMTP connection +.index SMTP||encryption +.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. + +RFC 2487 defines how SMTP connections can make use of encryption. Once a +connection is established, the client issues a \\STARTTLS\\ command. If the +server accepts this, the client and the server negotiate an encryption +mechanism. If the negotiation succeeds, the data that subsequently passes +between them is encrypted. + +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 +possible for an Exim server to deny or accept certain commands based on the +encryption state. + +\**Warning**\: certain types of firewall and certain anti-virus products can +disrupt TLS connections. You need to turn off SMTP scanning for these products +in order to get TLS to work. + + +.section OpenSSL vs GnuTLS +.index TLS||OpenSSL \*vs*\ GnuTLS +.rset SECTopenvsgnu "~~chapter.~~section" +The first TLS support in Exim was implemented using OpenSSL. Support for GnuTLS +followed later, when the first versions of GnuTLS were released. To build Exim +to use GnuTLS, you need to set +.display asis +USE_GNUTLS=yes +.endd +in Local/Makefile, in addition to +.display asis +SUPPORT_TLS=yes +.endd +You must also set \\TLS@_LIBS\\ and \\TLS@_INCLUDE\\ appropriately, so that the +include files and libraries for GnuTLS can be found. + +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 +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 +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 +time to compute. It is unreasonable to re-compute them for every TLS +session. Therefore, Exim keeps this data in a file in its spool +directory, called \(gnutls-params)\. The file is owned by the Exim user and is +readable only by its owner. Every Exim process that start up GnuTLS reads the +RSA and D-H parameters from this file. If the file does not exist, the first +Exim process that needs it computes the data and writes it to a temporary file +which is renamed once it is complete. It does not matter if several Exim +processes do this simultaneously (apart from wasting a few resources). Once a +file is in place, new Exim processes immediately start using it. + +For maximum security, the parameters that are stored in this file should be +recalculated periodically, the frequency depending on your paranoia level. +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 +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 +option). +.nem +.nextp +.em +The \tls@_require@_ciphers\ options operate differently, as described in the +following section. +.nem +.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 +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: +.numberpars $. +It can consist of a single cipher suite such as RC4-SHA. +.nextp +It can represent a list of cipher suites containing a certain algorithm, +or cipher suites of a certain type. For example SHA1 represents all +ciphers suites using the digest algorithm SHA1 and SSLv3 represents all +SSL v3 algorithms. +.nextp +Lists of cipher suites can be combined in a single cipher string using +the + character. This is used as a logical and operation. For example +SHA1+DES represents all cipher suites containing the SHA1 and the DES +algorithms. +.nextp +Each cipher string can be optionally preceded by the characters \"!"\, \"-"\ or +\"+"\. +.numberpars " " +If \"!"\ is used then the ciphers are permanently deleted from the list. The +ciphers deleted can never reappear in the list even if they are explicitly +stated. +.nextp +If \"-"\ is used then the ciphers are deleted from the list, but some or all +of the ciphers can be added again by later options. +.nextp +If \"+"\ is used then the ciphers are moved to the end of the list. This +option doesn't add any new ciphers it just moves matching existing ones. +.nextp +If none of these characters is present then the string is just interpreted as a +list of ciphers to be appended to the current preference list. If the list +includes any ciphers already present they will be ignored: that is, they will +not moved to the end of the list. +.endp +.endp + +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 +numerical, and the library does not have a function for turning names into +numbers. Consequently, the list of recognized names has to be built into +the application. + +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. + +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 +exclamation mark, all the default items are deleted. Thus, only those specified +can be used. If the first item in \tls@_require@_ciphers\ \*does*\ start with +an exclamation mark, the defaults are left on the list. + +Then, any item that starts with an exclamation mark causes the relevent +algorithms to be removed from the list, and any item that does not start +with an exclamation mark causes the relevant algorithms to be added to the +list. Thus, +.display asis +tls_require_ciphers = !RSA_ARCFOUR_SHA +.endd +allows all the defaults except those that use ARCFOUR, whereas +.display asis +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. +.nem + + +.section Configuring an Exim server to use TLS +.index TLS||configuring an Exim server +When Exim has been built with TLS support, it advertises the availability of +the \\STARTTLS\\ command to client hosts that match \tls@_advertise@_hosts\, +but not to any others. The default value of this option is unset, which means +that \\STARTTLS\\ is not advertised at all. This default is chosen because you +need to set some other options in order to make TLS avaliable, and also it is +sensible for systems that want to use TLS only as a client. + +If a client issues a \\STARTTLS\\ command and there is some configuration +problem in the server, the command is rejected with a 454 error. If the client +persists in trying to issue SMTP commands, all except \\QUIT\\ are rejected +with the error +.display asis +554 Security failure +.endd +If a \\STARTTLS\\ command is issued within an existing TLS session, it is +rejected with a 554 error code. + +To enable TLS operations on a server, you must set \tls@_advertise@_hosts\ to +match some hosts. You can, of course, set it to $*$ to match all hosts. +However, this is not all you need to do. TLS sessions to a server won't work +without some further configuration at the server end. + +It is rumoured that all existing clients that support TLS/SSL use RSA +encryption. To make this work you need to set, in the server, +.display asis +tls_certificate = /some/file/name +tls_privatekey = /some/file/name +.endd +The first file contains the server's X509 certificate, and the second contains +the private key that goes with it. These files need to be readable by the Exim +user, and must always be given as full path names. They can be the same file if +both the certificate and the key are contained within it. If \tls@_privatekey\ +is not set, this is assumed to be the case. The certificate file may also +contain intermediate certificates that need to be sent to the client to enable +it to authenticate the server's certificate. + +If you do not understand about certificates and keys, please try to find a +source of this background information, which is not Exim-specific. (There are a +few comments below in section ~~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 +of the same name in an \%smtp%\ transport. + +With just these options, Exim will work as a server with clients such as +Netscape. It does not require the client to have a certificate (but see below +for how to insist on this). There is one other option that may be needed in +other situations. If +.display asis +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 +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 +ignored if GnuTLS is being used. + +The strings supplied for these three options are expanded every time a client +host connects. It is therefore possible to use different certificates and keys +for different hosts, if you so wish, by making use of the client's IP address +in \$sender@_host@_address$\ to control the expansion. If a string expansion is +forced to fail, Exim behaves as if the option is not set. + +.index cipher||logging +.index log||TLS cipher +The variable \$tls@_cipher$\ is set to the cipher suite that was negotiated for +an incoming TLS connection. It is included in the ::Received:: header of an +incoming message (by default -- you can, of course, change this), and it is +also included in the log line that records a message's arrival, keyed by `X=', +unless the \tls@_cipher\ log selector is turned off. +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 +suite and vary their actions accordingly. The cipher suite names are those used +by OpenSSL. These may differ from the names used elsewhere. For example, +OpenSSL uses the name DES-CBC3-SHA for the cipher suite which in other contexts +is known as TLS@_RSA@_WITH@_3DES@_EDE@_CBC@_SHA. Check the OpenSSL +documentation for more details. + + +.section Requesting and verifying client certificates +.index certificate||verification of client +.index TLS||client certificate verification +If you want an Exim server to request a certificate when negotiating a TLS +session with a client, you must set either \tls@_verify@_hosts\ or +\tls@_try@_verify@_hosts\. You can, of course, set either of them to $*$ to +apply to all TLS connections. For any host that matches one of these options, +Exim requests a certificate as part of the setup of the TLS session. The +contents of the certificate are verified by comparing it with a list of +expected 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 +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 +.display asis +openssl x509 -hash -noout -in /cert/file +.endd +where \(/cert/file)\ contains a single certificate. + +The difference between \tls@_verify@_hosts\ and \tls@_try@_verify@_hosts\ is +what happens if the client does not supply a certificate, or if the certificate +does not match any of the certificates in the collection named by +\tls@_verify@_certificates\. If the client matches \tls@_verify@_hosts\, the +attempt to set up a TLS session is aborted, and the incoming connection is +dropped. If the client matches \tls@_try@_verify@_hosts\, the (encrypted) SMTP +session continues. ACLs that run for subsequent SMTP commands can detect the +fact that no certificate was verified, and vary their actions accordingly. For +example, you can insist on a certificate before accepting a message for +relaying, but not when the message is destined for local delivery. + +When a client supplies a certificate (whether it verifies or not), the value of +the Distinguished Name of the certificate is made available in the variable +\$tls@_peerdn$\ during subsequent processing of the message. +.index log||distinguished name +Because it is often a long text string, it is not included in the log line or +::Received:: header by default. You can arrange for it to be logged, keyed by +`DN=', by setting the \tls@_peerdn\ log selector, and you can use +\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 +.index certificate||revocation list +Certificate issuing authorities issue Certificate Revocation Lists (CRLs) when +certificates are revoked. If you have such a list, you can pass it to an Exim +server using the global option called \tls@_crl\ and to an Exim client using an +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 +.index log||TLS cipher +.index log||distinguished name +.index TLS||configuring an Exim client +The \tls@_cipher\ and \tls@_peerdn\ log selectors apply to outgoing SMTP +deliveries as well as to incoming, the latter one causing logging of the +server certificate's DN. The remaining client configuration for TLS is all +within the \%smtp%\ transport. + +It is not necessary to set any options to have TLS work in the \%smtp%\ +transport. If Exim is built with TLS support, and TLS is advertised by a +server, the \%smtp%\ transport always tries to start a TLS session. However, +this can be prevented by setting \hosts@_avoid@_tls\ (an option of the +transport) to a list of server hosts for which TLS should not be used. + +If you do not want Exim to attempt to send messages unencrypted when an attempt +to set up an encrypted connection fails in any way, you can set +\hosts@_require@_tls\ to a list of hosts for which encryption is mandatory. For +those hosts, delivery is always deferred if an encrypted connection cannot be +set up. If there are any other hosts for the address, they are tried in the +usual way. + +When the server host is not in \hosts@_require@_tls\, Exim may try to deliver +the message unencrypted. It always does this if the response to \\STARTTLS\\ is +a 5\*xx*\ code. For a temporary error code, or for a failure to negotiate a TLS +session after a success response code, what happens is controlled by the +\tls@_tempfail@_tryclear\ option of the \%smtp%\ transport. If it is false, +delivery to this host is deferred, and other hosts (if available) are tried. If +it is true, Exim attempts to deliver unencrypted after a 4\*xx*\ response to +\\STARTTLS\\, and if \\STARTTLS\\ is accepted, but the subsequent TLS +negotiation fails, Exim closes the current connection (because it is in an +unknown state), opens a new one to the same host, and then tries the delivery +unencrypted. + + +The \tls@_certificate\ and \tls@_privatekey\ options of the \%smtp%\ transport +provide the client with a certificate, which is passed to the server if it +requests it. If the server is Exim, it will request a certificate only if +\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 +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 +list of permitted cipher suites. If either of these checks fails, delivery to +the current host is abandoned, and the \%smtp%\ transport tries to deliver to +alternative hosts, if any. + +All the TLS options in the \%smtp%\ transport are expanded before use, with +\$host$\ and \$host@_address$\ containing the name and address of the server to +which the client is connected. Forced failure of an expansion causes Exim to +behave as if the relevant option were unset. + + +.section Multiple messages on the same encrypted TCP/IP connection +.rset SECTmulmessam "~~chapter.~~section" +.index multiple SMTP deliveries with TLS +.index TLS||multiple message deliveries +Exim sends multiple messages down the same TCP/IP connection by starting up +an entirely new delivery process for each message, passing the socket from +one process to the next. This implementation does not fit well with the use +of TLS, because there is quite a lot of state information associated with a TLS +connection, not just a socket identification. Passing all the state information +to a new process is not feasible. Consequently, Exim shuts down an existing TLS +session before passing the socket to a new process. The new process may then +try to start a new TLS session, and if successful, may try to re-authenticate +if \\AUTH\\ is in use, before sending the next message. + +The RFC is not clear as to whether or not an SMTP session continues in clear +after TLS has been shut down, or whether TLS may be restarted again later, as +just described. However, if the server is Exim, this shutdown and +reinitialization works. It is not known which (if any) other servers operate +successfully if the client closes a TLS session and continues with unencrypted +SMTP, but there are certainly some that do not work. For such servers, Exim +should not pass the socket to another process, because the failure of the +subsequent attempt to use it would cause Exim to record a temporary host error, +and delay other deliveries to that host. + +To test for this case, Exim sends an \\EHLO\\ command to the server after +closing down the TLS session. If this fails in any way, the connection is +closed instead of being passed to a new delivery process, but no retry +information is recorded. + +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. + + + +.section Certificates and all that +.rset SECTcerandall "~~chapter.~~section" +.index certificate||references to discussion +In order to understand fully how TLS works, you need to know about +certificates, certificate signing, and certificate authorities. This is not the +place to give a tutorial, especially as I do not know very much about it +myself. Some helpful introduction can be found in the FAQ for the SSL addition +to Apache, currently at +.display rm +\?http://www.modssl.org/docs/2.7/ssl@_faq.html@#ToC24?\ +.endd +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. +Some sample programs taken from the book are available from +.display rm +\?http://www.rtfm.com/openssl-examples/?\ +.endd + +.section Certificate chains +The file named by \tls@_certificate\ may contain more than one +certificate. This is useful in the case where the certificate that is being +sent is validated by an intermediate certificate which the other end does +not have. Multiple certificates must be in the correct order in the file. +First the host's certificate itself, then the first intermediate +certificate to validate the issuer of the host certificate, then the next +intermediate certificate to validate the issuer of the first intermediate +certificate, and so on, until finally (optionally) the root certificate. +The root certificate must already be trusted by the recipient for +validation to succeed, of course, but if it's not preinstalled, sending the +root certificate along with the rest makes it available for the user to +install if the receiving end is a client MUA that can interact with a user. + +.section Self-signed certificates +.index certificate||self-signed +You can create a self-signed certificate using the \*req*\ command provided +with OpenSSL, like this: +.display asis +openssl req -x509 -newkey rsa:1024 -keyout file1 -out file2 \ + -days 9999 -nodes +.endd +\(file1)\ and \(file2)\ can be the same file; the key and the certificate are +delimited and so can be identified independently. The \-days-\ option +specifies a period for which the certificate is valid. The \-nodes-\ option is +important: if you do not set it, the key is encrypted with a passphrase +that you are prompted for, and any use that is made of the key causes more +prompting for the passphrase. This is not helpful if you are going to use +this certificate and key in an MTA, where prompting is not possible. + +A self-signed certificate made in this way is sufficient for testing, and +may be adequate for all your requirements if you are mainly interested in +encrypting transfers, and not in secure identification. + +However, many clients require that the certificate presented by the server be a +user (also called `leaf' or `site') certificate, and not a self-signed +certificate. In this situation, the self-signed certificate described above +must be installed on the client host as a trusted root \*certification +authority*\ (CA), and the certificate used by Exim must be a user certificate +signed with that self-signed certificate. + +For information on creating self-signed CA certificates and using them to sign +user certificates, see the \*General implementation overview*\ chapter of the +Open-source PKI book, available online at \?http://ospkibook.sourceforge.net/?\. + + + +. +. +. +. +. ============================================================================ +.chapter Access control lists +.set runningfoot "ACL" +.rset CHAPACL "~~chapter" +.index ~~ACL||description +.index control of incoming mail +.index message||controlling incoming +.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 +one very small ACL: +.display asis +begin acl + +small_acl: + accept hosts = one.host.only +.endd +You can have as many lists as you like in the ACL section, and the order in +which they appear does not matter. The lists are self-terminating. + +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. + +.section Testing ACLs +The \-bh-\ command line option provides a way of testing your ACL configuration +locally by running a fake SMTP session with which you interact. The host +\*relay-test.mail-abuse.org*\ provides a service for checking your relaying +configuration (see section ~~SECTcheralcon for more details). + + +.section Specifying when ACLs are used +.index ~~ACL||options for specifying +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 \\ETRN\\||ACL for +.index \\EXPN\\||ACL for +.index \\HELO\\||ACL for +.index \\EHLO\\||ACL for +.index \\MAIL\\||ACL for +.index \\RCPT\\||ACL for +.index \\STARTTLS\\, ACL for +.index \\VRFY\\||ACL for +.display +.tabs 20 +.if !~~sys.fancy +.tabs 24 +.fi +\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@_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 +\acl@_smtp@_rcpt\ $t $rm{ACL for \\RCPT\\} +\acl@_smtp@_starttls\ $t $rm{ACL for \\STARTTLS\\} +\acl@_smtp@_vrfy\ $t $rm{ACL for \\VRFY\\} +.endd +For example, if you set +.display asis +acl_smtp_rcpt = small_acl +.endd +the little ACL defined above is used whenever Exim receives a \\RCPT\\ command +in an SMTP dialogue. The majority of policy tests on incoming messages can be +done when \\RCPT\\ commands arrive. A rejection of \\RCPT\\ should cause the +sending MTA to give up on the recipient address contained in the \\RCPT\\ +command, whereas rejection at other times may cause the client MTA to keep on +trying to deliver the message. It is therefore recommended that you do as much +testing as possible at \\RCPT\\ time. + +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). + +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 +kind of rejection is treated as permanent, because there is no way of sending a +temporary error for these kinds of message. Many of the ACL conditions (for +example, host tests, and tests on the state of the SMTP connection such as +encryption and authentication) are not relevant and are forbidden in this ACL. + + +.section ACL return codes +.index ~~ACL||return codes +The 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 +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. + +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 +remaining recipients. + +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 +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'. + +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. + +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. + +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 \$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. + + + +.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 +\$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 +other words, it does not permit authentication methods that use cleartext +passwords on unencrypted connections. +.display asis +acl_check_auth: + accept encrypted = * + accept condition = ${if eq{${uc:$smtp_command_argument}}\ + {CRAM-MD5}{yes}{no}} + 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 +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: +.display asis +deny dnslists = list1.example + dnslists = list2.example +.endd + +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: +.numberpars $. +\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 +\endpass\, the ACL returns `deny'. Consider this statement, used to check a +\\RCPT\\ command: +.display asis +accept domains = +local_domains + endpass + verify = recipient +.endd +If the recipient domain does not match the \domains\ condition, control passes +to the next statement. If it does match, the recipient is verified, and the +command is accepted if verification succeeds. However, if verification fails, +the ACL yields `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, +\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 +\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, +.display asis +deny dnslists = blackholes.mail-abuse.org +.endd +rejects commands from hosts that are on a DNS black list. +.nextp +\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 \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 +message's recipients are discarded. Recipients that are discarded before +\\DATA\\ do not appear in the log line when the \log@_recipients\ log selector +is set. +.nextp +\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}} +.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 +\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, +.display asis +require verify = sender +.endd +passes control to subsequent statements only if the message's sender can be +verified. Otherwise, it rejects the command. +.nextp +.em +\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\. + +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 +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 +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 + +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 +want this logged, you must set it up explicitly. For example: +.display asis +warn !verify = sender + log_message = sender verify failed: $acl_verify_message +.endd +.endp + +At the end of each ACL there is an implicit unconditional \deny\. + +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. + + +.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: +.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 +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 +preserved with the message and are subsequently made available at delivery +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 +be set. If you want to set a variable without taking any action, you can use a +\warn\ verb without any other modifiers. + + +.section Condition and modifier processing +.index ~~ACL||conditions, processing +.index ~~ACL||modifiers, processing +An exclamation mark preceding a condition negates its result. For example, +.display asis +deny domains = *.dom.example + !verify = recipient +.endd +causes the ACL to return `deny' if the recipient domain ends in +\*dom.example*\, but 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 +condition is true. Consider these two statements: +.display asis +accept senders = ${lookup{$host_name}lsearch\ + {/some/file}{$value}fail} +accept senders = ${lookup{$host_name}lsearch\ + {/some/file}{$value}{}} +.endd +Each attempts to look up a list of acceptable senders. If the lookup succeeds, +the returned list is searched, but if the lookup fails the behaviour is +different in the two cases. The \fail\ in the first statement causes the +condition to be ignored, leaving no further conditions. The \accept\ verb +therefore succeeds. The second statement, however, generates an empty list when +the lookup fails. No sender can match an empty list, so the condition fails, +and therefore the \accept\ also fails. + +ACL modifiers appear mixed in with conditions in ACL statements. Some of them +specify actions that are taken as the conditions for a statement are checked; +others specify text for messages that are used when access is denied or a +warning is generated. + +The 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: +.display asis +require message = Can't verify sender + verify = sender + message = Can't verify recipient + 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 +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 +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 +which time Exim has set up the message. + + +.section ACL modifiers +.rset SECTACLmodi "~~chapter.~~section" +.index ~~ACL||modifiers, list of +The ACL modifiers are as follows: + +.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. +.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. +.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: +.numberpars $. +It can be at the end of an \accept\ statement: +.display asis +accept ...some conditions... + control = queue_only +.endd +In this case, the control is applied when this statement yields `accept'. +.nextp +It can be in the middle of an \accept\ statement: +.display asis +accept ...some conditions... + control = queue_only + ...some more conditions... +.endd +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. +.nextp +It can be used with \warn\ to apply the control, leaving the +decision about accepting or denying to a subsequent verb. For +example: +.display asis +warn ...some conditions... + 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. +.nem +.endp + +.item "delay = <<time>>" +.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 + +Like \control\, \delay\ can be used with \accept\ or +\deny\, for example: +.display asis +deny ...some conditions... + delay = 30s +.endd +The delay happens if all the conditions are true, before the statement returns +`deny'. Compare this with: +.display asis +deny delay = 30s + ...some conditions... +.endd +which waits for 30s before processing the conditions. The \delay\ modifier can +also be used with \warn\ and together with \control\: +.display +warn ...some conditions... + delay = 2m + control = freeze +accept ... +.endd + +.item endpass +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>>" +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: +.display asis +require log_message = wrong cipher suite $tls_cipher + encrypted = DES-CBC3-SHA +.endd +\log@_message\ adds to any underlying error message that may exist because of +the condition failure. For example, while verifying a recipient address, a +:::fail:: redirection might have already set up a message. Although the message +is usually defined before the conditions to which it applies, the expansion +does not happen until Exim decides that access is to be denied. This means that +any variables that are set by the condition are available for inclusion in the +message. For example, the \$dnslist@_<<xxx>>$\ variables are set after a DNS +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, +the \message\ text is used for logging rejections. However, if any text for +logging contains newlines, only the first line is logged. In the absence of +both \log@_message\ and \message\, a default built-in message is used for +logging rejections. + +.item "logwrite = <<text>>" +.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 +accept <<some special conditions>> + control = freeze + logwrite = froze message because ... +.endd +By default, the message is written to the main log. However, it may begin +with a colon, followed by a comma-separated list of log names, and then +another colon, to specify exactly which logs are to be written. For +example: +.display asis +logwrite = :main,reject: text for main and reject logs +logwrite = :panic: text for panic log only +.endd + +.item "message = <<text>>" +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 +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. + +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. +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%\ +routers to be passed back as part of the SMTP response, you should either not +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 +~~SECTaclvariables). + +.enditems + + + + +.section ACL conditions +.rset SECTaclconditions "~~chapter.~~section" +.index ~~ACL||conditions, list of +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. +The conditions are as follows: + +.startitems + +.item "acl = <<name of acl or ACL string or file name >>" +.index ~~ACL||nested +.index ~~ACL||indirect +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. + +ACLs may be nested up to 20 deep; the limit exists purely to catch runaway +loops. This condition allows you to use different ACLs in different +circumstances. For example, different ACLs can be used to handle \\RCPT\\ +commands for different local users or different local domains. + +.item "authenticated = <<string list>>" +.index authentication||ACL checking +.index ~~ACL||testing for authentication +If the SMTP connection is not authenticated, the condition is false. Otherwise, +the name of the authenticator is tested against the list. To test for +authentication by any authenticator, you can set +.display asis +authenticated = * +.endd + +.item "condition = <<string>>" +.index customizing||ACL condition +.index ~~ACL||customized test +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'. + +.item "dnslists = <<list of domain names and other data>>" +.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 +here. See sections ~~SECTmorednslists--~~SECTmorednslistslast for details. + +.item "domains = <<domain list>>" +.index domain||ACL checking +.index ~~ACL||testing a recipient domain +This condition is relevant only after a \\RCPT\\ command. It checks that the +domain of the recipient address is in the domain list. If percent-hack +processing is enabled, it is done before this test is done. If the check +succeeds with a lookup, the result of the lookup is placed in \$domain@_data$\ +until the next \domains\ test. + +.item "encrypted = <<string list>>" +.index encryption||checking in an ACL +.index ~~ACL||testing for encryption +If the SMTP connection is not encrypted, the condition is false. Otherwise, the +name of the cipher suite in use is tested against the list. To test for +encryption without testing for any specific cipher suite(s), set +.display asis +encrypted = * +.endd + +.item "hosts = << host list>>" +.index host||ACL checking +.index ~~ACL||testing the client host +This condition tests that the calling host matches the host list. If you have +name lookups or wildcarded host names and IP addresses in the same host list, +you should normally put the IP addresses first. For example, you could have: +.display asis +accept hosts = 10.9.8.7 : dbm;/etc/friendly/hosts +.endd +The reason for this lies in the left-to-right way that Exim processes lists. +It can test IP addresses without doing any DNS lookups, but when it reaches an +item that requires a host name, it fails if it cannot find a host name to +compare with the pattern. If the above list is given in the opposite order, the +\accept\ statement fails for a host whose name cannot be found, even if its +IP address is 10.9.8.7. + +If you really do want to do the name check first, and still recognize the IP +address even if the name lookup fails, you can rewrite the ACL like this: +.display asis +accept hosts = dbm;/etc/friendly/hosts +accept hosts = 10.9.8.7 +.endd +The default action on failing to find the host name is to assume that the host +is not in the list, so the first \accept\ statement fails. The second statement +can then check the IP address. + +If a \hosts\ condition is satisfied by means of a lookup, the result +of the lookup is made available in the \$host@_data$\ variable. This +allows you, for example, to set up a statement like this: +.display asis +deny hosts = net-lsearch;/some/file + message = $host_data +.endd +which gives a custom error message for each denied host. + +.item "local@_parts = <<local part list>>" +.index local part||ACL checking +.index ~~ACL||testing a local part +This condition is relevant only after a \\RCPT\\ command. It checks that the +local part of the recipient address is in the list. If percent-hack processing +is enabled, it is done before this test. If the check succeeds with a lookup, +the result of the lookup is placed in \$local@_part@_data$\ until the next +\local@_parts\ test. + +.item "recipients = <<address list>>" +.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. + +.item "sender@_domains = <<domain list>>" +.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 +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 sender||ACL checking +.index ~~ACL||testing a sender +This condition tests the sender of the message against the given list. To test +for a bounce message, which has an empty sender, set +.display asis +senders = : +.endd + +.item "verify = certificate" +.index TLS||client certificate verification +.index certificate||verification of client +.index ~~ACL||certificate verification +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 ~~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: +.display asis +deny senders = : + message = A valid sender header is required for bounces + !verify = header_sender +.endd + +.item "verify = header@_syntax" +.index ~~ACL||verifying header syntax +.index header lines||verifying syntax +.index verifying||header syntax +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\ +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::). +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 +appropriate. + +Note that this condition is a syntax check only. However, a common spamming +ploy is to send syntactically invalid headers such as +.display asis +To: @ +.endd +and this condition can be used to reject such messages. + +.item "verify = helo" +.index ~~ACL||verifying HELO/EHLO +.index \\HELO\\||verifying +.index \\EHLO\\||verifying +.index verifying||\\EHLO\\ +.index verifying||\\HELO\\ +This condition is true if a \\HELO\\ or \\EHLO\\ command has been received from +the client host, and its contents have been verified. Verification of these +commands does not happen by default. See the description of the +\helo@_verify@_hosts\ and \helo@_try@_verify@_hosts\ options for details of how +to request it. + +.item "verify = recipient/<<options>>" +.index ~~ACL||verifying recipient +.index recipient||verifying +.index verifying||recipient +This condition is relevant only after a \\RCPT\\ command. It verifies the +current recipient. Details of address verification are given later, starting at +section ~~SECTaddressverification. After a recipient has been verified, the +value of \$address@_data$\ is the last value that was set while routing the +address. This applies even if the verification fails. When an address that is +being verified is redirected to a single address, verification continues with +the new address, and in that case, the subsequent value of \$address@_data$\ is +the value for the child address. + + +.item "verify = reverse@_host@_lookup" +.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 +address of the client host. (This may have happened already if the host name +was needed for checking a host list, or if the host matched \host@_lookup\.) +Verification ensures that the host name obtained from a reverse DNS lookup, or +one of its aliases, does, when it is itself looked up in the DNS, yield the +original IP address. + +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 ~~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). +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>>" +This is a variation of the previous option, in which a modified address is +verified as a sender. + +.enditems + + + +.section Using DNS lists +.rset SECTmorednslists "~~chapter.~~section" +.index DNS list||in ACL +.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 +.display asis +deny dnslists = blackholes.mail-abuse.org : \ + dialups.mail-abuse.org +.endd +the following domains are looked up: +.display asis +43.62.168.192.blackholes.mail-abuse.org +43.62.168.192.dialups.mail-abuse.org +.endd +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: +.index \"+include@_unknown"\ +.index \"+exclude@_unknown"\ +.index \"+defer@_unknown"\ +.display ++include@_unknown $rm{behave as if the item is on the list} ++exclude@_unknown $rm{behave as if the item is not on the list (default)} ++defer@_unknown $rm{give a temporary error} +.endd +Each of these applies to any subsequent items on the list. For example: +.display asis +deny dnslists = +defer_unknown : foo.bar.example +.endd + +Testing the list of domains stops as soon as a match is found. If you want to +warn for one list and block for another, you can use two different statements: +.display asis +deny dnslists = blackholes.mail-abuse.org +warn message = X-Warn: sending host is on dialups list + dnslists = dialups.mail-abuse.org +.endd + +DNS list lookups are cached by Exim for the duration of the SMTP session, +so a lookup based on the IP address is done at most once for any incoming +connection. Exim does not share information between multiple incoming +connections (but your local name server cache should be active). + + +.section DNS lists keyed on domain names +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, +.display asis +deny message = Sender's domain is listed at $dnslist_domain + dnslists = dsn.rfc-ignorant.org/$sender_address_domain +.endd +This particular example is useful only in ACLs that are obeyed after the +\\RCPT\\ or \\DATA\\ commands, when a sender address is available. If (for +example) the message's sender is \*user@@tld.example*\ the name that is looked +up by this example is +.display asis +tld.example.dsn.rfc-ignorant.org +.endd +You can mix entries with and without additional data in the same \dnslists\ +condition. + +.section Data returned by DNS lists +DNS lists are constructed using address records in the DNS. The original RBL +just used the address 127.0.0.1 on the right hand side of each record, but the +RBL+ list and some other lists use a number of values with different meanings. +The values used on the RBL+ list are: +.display rm +.tabs 12 +127.1.0.1 $t RBL +127.1.0.2 $t DUL +127.1.0.3 $t DUL and RBL +127.1.0.4 $t RSS +127.1.0.5 $t RSS and RBL +127.1.0.6 $t RSS and DUL +127.1.0.7 $t RSS and DUL and RBL +.endd +Some DNS lists may return more than one address record. + +.section Variables set from DNS lists +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 +associated TXT record. If more than one address record is returned by the DNS +lookup, all the IP addresses are included in \$dnslist@_value$\, separated by +commas and spaces. + +You can use these variables in \message\ or \log@_message\ modifiers -- +although these appear before the condition in the ACL, they are not expanded +until after it has failed. For example: +.display asis +deny hosts = !+local_networks + message = $sender_host_address is listed \ + at $dnslist_domain + dnslists = rbl-plus.mail-abuse.example +.endd + + +.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, +.display asis +deny dnslists = rblplus.mail-abuse.org=127.0.0.2 +.endd +rejects only those hosts that yield 127.0.0.2. Without this additional data, +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: +.display asis +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 +tested. For example: +.display asis +dnslists = a.b.c&0.0.0.3 +.endd +matches if the address is \*x.x.x.*\3, \*x.x.x.*\7, \*x.x.x.*\11, etc. If you +want to test whether one bit or another bit is present (as opposed to both +being present), you must use multiple values. For example: +.display asis +dnslists = a.b.c&0.0.0.1,0.0.0.2 +.endd +matches if the final component of the address is an odd number or two times +an odd number. + + +.section Negated DNS matching conditions +You can supply a negative list of IP addresses as part of a \dnslists\ +condition. Whereas +.display asis +deny dnslists = a.b.c=127.0.0.2,127.0.0.3 +.endd +means `deny if the host is in the black list at the domain \*a.b.c*\ and the IP +address yielded by the list is either 127.0.0.2 or 127.0.0.3', +.display asis +deny dnslists = a.b.c!=127.0.0.2,127.0.0.3 +.endd +means `deny if the host is in the black list at the domain \*a.b.c*\ and the IP +address yielded by the list is not 127.0.0.2 and not 127.0.0.3'. In other +words, the result of the test is inverted if an exclamation mark appears before +the `=' (or the `&') sign. + +\**Note**\: this kind of negation is not the same as negation in a domain, +host, or address list (which is why the syntax is different). + +If you are using just one list, the negation syntax does not gain you much. The +previous example is precisely equivalent to +.display asis +deny dnslists = a.b.c + !dnslists = a.b.c=127.0.0.2,127.0.0.3 +.endd +However, if you are using multiple lists, the negation syntax is clearer. +Consider this example: +.display asis +deny dnslists = sbl.spamhaus.org : \ + list.dsbl.org : \ + dnsbl.njabl.org!=127.0.0.3 : \ + relays.ordb.org +.endd +Using only positive lists, this would have to be: +.display asis +deny dnslists = sbl.spamhaus.org : \ + list.dsbl.org +deny dnslists = dnsbl.njabl.org + !dnslists = dnsbl.njabl.org=127.0.0.3 +deny dnslists = relays.ordb.org +.endd +which is less clear, and harder to maintain. + + + +.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 +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 +1.3.0.c.a.0.0.2.0.0.8.0.a.0.0.0.0.0.a.0.f.6.3.8. + f.f.f.f.e.f.f.3.blackholes.mail-abuse.org +.endd +(split over two lines here to fit on the page). Unfortunately, some of the DNS +lists contain wildcard records, intended for IPv4, that interact badly with +IPv6. For example, the DNS entry +.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. + +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}} + dnslists = some.list.example +.endd + + +.section Address verification +.rset SECTaddressverification "~~chapter.~~section" +.index verifying||address, options for +.index policy control||address verification +Several of the \verify\ conditions described in section ~~SECTaclconditions +cause addresses to be verified. These conditions can be followed by options +that modify the verification process. The options are separated from the +keyword and from each other by slashes, and some of them contain parameters. +For example: +.display asis +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 +normally returns `defer'. However, if you include \defer@_ok\ in the options, +the condition is forced to be true instead. + +.section Callout verification +.rset SECTcallver "~~chapter.~~section" +.index verifying||address, by callout +.index callout||verification +.index SMTP||callout verification +For non-local addresses, routing verifies the domain, but is unable to do any +checking of the local part. There are situations where some means of verifying +the local part is desirable. One way this can be done is to make an SMTP +\*callback*\ to the sending host (for a sender address) or a \*callforward*\ to +a subsequent host (for a recipient address), to see if the host accepts the +address. We use the term \*callout*\ to cover both cases. This facility should +be used with care, because it can add a lot of resource usage to the cost of +verifying an address. However, Exim does cache the results of callouts, which +helps to reduce the cost. Details of caching are in 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 +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 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 +\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. + +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>> +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'. + +.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 + +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, +Exim tries the next host, if any. If there is a problem with all the remote +hosts, the ACL yields `defer', unless the \defer@_ok\ parameter of the +\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 +The \callout\ option can be followed by an equals sign and a number of optional +parameters, separated by commas. For example: +.display asis +verify = recipient/callout=10s,defer_ok +.endd +The old syntax, which had \callout@_defer@_ok\ and \check@_postmaster\ as +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: +.display asis +verify = sender/callout=5s +.endd +The default is 30 seconds. The timeout is used for each response from the +remote host. +.nextp +.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 +.index callout||cache, suppressing +.index caching||callout, suppressing +\no@_cache\: The callout cache is neither read nor updated. +.nextp +.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 +.index callout||`random' check +\random\: 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 +.display asis +$primary_host_name-$tod_epoch-testing +.endd +The idea here is to try to determine whether the remote host accepts all local +parts without checking. If it does, there is no point in doing callouts for +specific local parts. If the `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 +.index callout||sender for recipient check +.em +\use@_postmaster\: This option 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: +.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. +.nem +.endp + + +.section Callout caching +.rset SECTcallvercache "~~chapter.~~section" +.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 +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 +address, and the other records information that applies to the entire domain +(for example, that it accepts the local part \*postmaster*\). + +When an original callout fails, a detailed SMTP error message is given about +the failure. However, for subsequent failures use the cache data, this message +is not available. + +The expiry times for negative and positive address cache records are +independent, and can be set by the global options \callout@_negative@_expire\ +(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 +.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 +separate expiry times for domain cache records: +\callout@_domain@_negative@_expire\ (default 3h) and +\callout__domain__positive@_expire\ (default 7d). + +Domain records expire when the negative expiry time is reached if callouts +cannot be made for the domain, or if the postmaster check failed. +Otherwise, they expire when the positive expiry time is reached. This +ensures that, for example, a host that stops accepting `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. + + +.section Sender address verification reporting +.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 +SMTP command (\\RCPT\\ or \\DATA\\). For example, if sender callout is in use, +you might see: +.display asis +MAIL FROM:<xyz@abc.example> +250 OK +RCPT TO:<pqr@def.example> +550-Verification failed for <xyz@abc.example> +550-Called: 192.168.34.43 +550-Sent: RCPT TO:<xyz@abc.example> +550-Response: 550 Unknown local part xyz in <xyz@abc.example> +550 Sender verification failed +.endd +If more than one \\RCPT\\ command fails in the same way, the details are given +only for the first of them. However, some administrators do not want to send +out this much information. You can suppress the details by adding +`/no@_details' to the ACL statement that requests sender verification. For +example: +.display asis +verify = sender/no_details +.endd + + +.section Redirection while verifying +.index verifying||redirection while +.index address redirection||while verifying +A dilemma arises when a local address is redirected by aliasing or forwarding +during verification: should the generated addresses themselves be verified, +or should the successful expansion of the original address be enough to verify +it? Exim takes the following pragmatic approach: +.numberpars $. +When an incoming address is redirected to just one child address, verification +continues with the child address, and if that fails to verify, the original +verification also fails. +.nextp +When an incoming address is redirected to more than one child address, +verification does not continue. A success result is returned. +.endp +This seems the most reasonable behaviour for the common use of aliasing as a +way of redirecting different local parts to the same mailbox. It means, for +example, that a pair of alias entries of the form +.display asis +A.Wol: aw123 +aw123: :fail: Gone away, no forwarding address +.endd +work as expected, with both local parts causing verification failure. When a +redirection generates more than one address, the behaviour is more like a +mailing list, where the existence of the alias itself is sufficient for +verification to succeed. + + +.section Using an ACL to control relaying +.rset SECTrelaycontrol "~~chapter.~~section" +.index ~~ACL||relay control +.index relaying||control by ACL +.index policy control||relay control +An MTA is said to \*relay*\ a message if it receives it from some host and +delivers it directly to another host as a result of a remote address contained +within it. Redirecting a local address via an alias or forward file and then +passing the message on to another host is not relaying, +.index `percent hack' +but a redirection as a result of the `percent hack' is. + +Two kinds of relaying exist, which are termed `incoming' and `outgoing'. A host +which is acting as a gateway or an MX backup is concerned with incoming +relaying from arbitrary hosts to a specific set of domains. On the other hand, +a host which is acting as a smart host for a number of clients is concerned +with outgoing relaying from those clients to the Internet at large. Often the +same host is fulfilling both functions, as illustrated in the diagram below, +but in principle these two kinds of relaying are entirely independent. What is +not wanted is the transmission of mail from arbitrary remote hosts through your +system to arbitrary domains. +.if ~~sys.fancy +.figure "Controlled relaying" rm +.indent 0 +.call aspic +centre ~~sys.linelength; +magnify 0.8; +boundingbox 30; +textdepth 16; + boxwidth 120; + boxdepth 44; +A: box "Arbitrary" "remote hosts"; +C: ibox; +D: box "Arbitrary" "domains"; + iline down 50 from bottom of C; +H: box width 180 "Local host"; + iline down 50; +E: ibox; +SH: box "Specific" "hosts"; +SD: box join right to E "Specific" "domains"; + arcarrow clockwise from top of SH to bottom of D plus (-10,-4) + via right of H plus (-20,0); + arcarrow clockwise from bottom of A to top of SD plus (10,4) + via left of H plus (20,0); + + ibox join left to right of H "$it{Outgoing}"; + goto H; + ibox join right to left of H "$it{Incoming}"; + +L: line dashed from right of A to top of H plus (-15,0); + arc dashed to top of H plus (15,0); + arrow dashed to left of D plus (-2,0); + + arrow dashed back up 72 right 32 from middle of L plus (8,0); + text at end plus (0, 4) "$it{Not wanted}"; +.endcall +.endfigure +.elif !~~html +.display asis + -------------- ----------- + | Arbitrary | |Arbitrary| + |remote hosts| | domains | + -------------- ----------- + I v ^ O + n v ^ u + c ---v----------------^--- t + o | v Local ^ | g + m | v host ^ | o + i ---v----------------^--- i + n v ^ n + g v ^ g + Specific Specific + domains hosts +.endd +.else +[(IMG SRC="relaying.gif" alt="Controlled relaying")][(br)] +.fi + +You can implement relay control by means of suitable statements in the ACL that +runs for each \\RCPT\\ command. For convenience, it is often easiest to use +Exim's named list facility to define the domains and hosts involved. For +example, suppose you want to do the following: +.numberpars $. +Deliver a number of domains to mailboxes on the local host (or process them +locally in some other way). Let's say these are \*my.dom1.example*\ and +\*my.dom2.example*\. +.nextp +Relay mail for a number of other domains for which you are the secondary MX. +These might be \*friend1.example*\ and \*friend2.example*\. +.nextp +Relay mail from the hosts on your local LAN, to whatever domains are involved. +Suppose your LAN is 192.168.45.0/24. +.endp +In the main part of the configuration, you put the following definitions: +.display asis +domainlist local_domains = my.dom1.example : my.dom2.example +domainlist relay_domains = friend1.example : friend2.example +hostlist relay_hosts = 192.168.45.0/24 +.endd +Now you can use these definitions in the ACL that is run for every \\RCPT\\ +command: +.display asis +acl_check_rcpt: + accept domains = +local_domains : +relay_domains + accept hosts = +relay_hosts +.endd +The first statement accepts any \\RCPT\\ command that contains an address in +the local or relay domains. For any other domain, control passes to the second +statement, which accepts the command only if it comes from one of the relay +hosts. In practice, you will probably want to make your ACL more sophisticated +than this, for example, by including sender and recipient verification. The +default configuration includes a more comprehensive example, which is described +in chapter ~~CHAPdefconfil. + + +.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 +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 +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 +.display asis +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)\. + +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). + + + +.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 + +The function prototype for \*local@_scan()*\ is: +.display asis +extern int local_scan(int fd, uschar **return_text); +.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. + +.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"\ + +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 behaves as \\LOCAL@_SCAN@_ACCEPT\\, except that the accepted message is +queued without immediate delivery, and is frozen. +.nextp +\"LOCAL@_SCAN@_ACCEPT@_QUEUE"\ + +This behaves as \\LOCAL@_SCAN@_ACCEPT\\, except that the accepted message is +queued without immediate delivery. +.nextp +\"LOCAL@_SCAN@_REJECT"\ + +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 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"\ + +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"\ + +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 + +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. + + +.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 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"; + +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: + +.startitems + +.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 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: + +.startitems + +.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 +if ((debug_selector & D_local_scan) != 0) + debug_printf("xxx", ...); +.endd + +.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. + +.item "uschar *interface@_address" +The IP address of the interface that received the message, as a string. This +is NULL for locally submitted messages. + +.item "int interface@_port" +The port on which this message was received. + +.item "uschar *message@_id" +This variable contains the message id for the incoming message as a +zero-terminated string. + + +.item "uschar *received@_protocol" +The name of the protocol by which the message was received. + +.item "int recipients@_count" +The number of accepted recipients. + +.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. + +.item "uschar *sender@_address" +The envelope sender address. For bounce messages this is the empty string. + +.item "uschar *sender@_host@_address" +The IP address of the sending host, as a string. This is NULL for +locally-submitted messages. + +.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. + +.item "int sender@_host@_port" +The port on the sending host. + +.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. + +.item "int store@_pool" +The contents of this variable control which pool of memory is used for new +requests. See section ~~SECTmemhanloc for details. + +.enditems + + +.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 + +.item "struct header@_line *next" +A pointer to the next header line, or NULL for the last line. + +.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'. + +.item "int slen" +The number of characters in the header line, including the terminating and any +internal newlines. + +.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. + +.enditems + + + +.section Structure of recipient items +The \recipient@_item\ structure contains these members: + +.startitems + +.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: + +.startitems + +.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\. + +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. + +The function returns the pid of the new process, or -1 if things go wrong. + + +.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 + +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 + +The was some other error in wait(); \errno\ is still set. +.endp + + +.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. + +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. + +.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 + +.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. + +.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 +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 +.display asis +lss_match_host(sender_host_name, sender_host_address, ...) +.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. + +.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. + + +.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 + +.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. + +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 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. + + +.item "int smtp@_fflush(void)" +This function is used in conjunction with \*smtp@_printf()*\, as described +below. + +.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 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. + +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. + +.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. + +.enditems + + + +.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. + +If you want to allocate memory that remains available for subsequent messages +in the same SMTP connection, you should set +.display asis +store_pool = POOL_PERM +.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\. + + + + + +. +. +. +. +. ============================================================================ +.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}. + +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. + +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. + +\**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. + +.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. + +.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. + +.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. + +\**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. + + +.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. + +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 +.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. + +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\. + +.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. + +Header lines that are added by a system filter are visible to users' filter +files and to all routers and transports. +.nem + +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. + + +.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 +.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 + +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 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. + +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, + +.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. + +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: +.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. +.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. +.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\. +.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. + + + + +. +. +. +. ============================================================================ +.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 +send_to_smart_host: + driver = manualroute + route_list = !+local_domains smart.host.name + transport = remote_smtp +.endd +You can use the smart host's IP address instead of the name if you wish. + + +.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. + +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. + +.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. + + +.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. + +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 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. + +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. + +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 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 + +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. + +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 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. + +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 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. + +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. + + +.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. + +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 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. + +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. + +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 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 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. + + + + + +. +. +. +. +. ============================================================================ +.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\\ +.index \\HELO\\ +.index \\SIZE\\ option on \\MAIL\\ command +Outgoing SMTP and LMTP over TCP/IP is implemented by the \%smtp%\ transport. +The \protocol\ option selects which protocol is to be used, but the actual +processing is the same in both cases. + +If, in response to its \\EHLO\\ command, Exim is told that the \\SIZE\\ +parameter is supported, it adds \\SIZE\\=<<n>> to each subsequent \\MAIL\\ +command. The value of <<n>> is the message size plus the value of the +\size@_addition\ option (default 1024) to allow for additions to the message +such as per-transport header lines, or changes made in a +.index transport||filter +.index filter||transport filter +transport filter. If \size@_addition\ is set negative, the use of \\SIZE\\ is +suppressed. + +If the remote server advertises support for \\PIPELINING\\, Exim uses the +pipelining extension to SMTP (RFC 2197) to reduce the number of TCP/IP packets +required for the transaction. + +If the remote server advertises support for the \\STARTTLS\\ command, and Exim +was built to support TLS encryption, it tries to start a TLS session unless the +server matches \hosts@_avoid@_tls\. See chapter ~~CHAPTLS for more details. + +If the remote server advertises support for the \\AUTH\\ command, Exim scans +the authenticators configuration for any suitable client settings, as described +in chapter ~~CHAPSMTPAUTH. + +.index carriage return +.index linefeed +Responses from the remote host are supposed to be terminated by CR followed by +LF. However, there are known to be hosts that do not send CR characters, so in +order to be able to interwork with such hosts, Exim treats LF on its own as a +line terminator. + +If a message contains a number of different addresses, all those with the same +characteristics (for example, the same envelope sender) that resolve to the +same set of hosts, in the same order, are sent in a single SMTP transaction, +even if they are for different domains, unless there are more than the setting +of the \max@_rcpts\ option in the \%smtp%\ transport allows, in which case they +are split into groups containing no more than \max@_rcpts\ addresses each. If +\remote@_max@_parallel\ is greater than one, such groups may be sent in +parallel sessions. The order of hosts with identical MX values is not +significant when checking whether addresses can be batched in this way. + +When the \%smtp%\ transport suffers a temporary failure that is not +message-related, Exim updates its transport-specific database, which contains +records indexed by host name that remember which messages are waiting for each +particular host. It also updates the retry database with new retry times. +.index hints database||retry keys +Exim's retry hints are based on host name plus IP address, so if one address of +a multi-homed host is broken, it will soon be skipped most of the time. +See the next section for more detail about error handling. + +.index SMTP||passed connection +.index SMTP||batching over TCP/IP +When a message is successfully delivered over a TCP/IP SMTP connection, Exim +looks in the hints database for the transport to see if there are any queued +messages waiting for the host to which it is connected. If it finds one, it +creates a new Exim process using the \-MC-\ option (which can only be used by a +process running as root or the Exim user) and passes the TCP/IP socket to it so +that it can deliver another message using the same socket. The new process does +only those deliveries that are routed to the connected host, and may in turn +pass the socket on to a third process, and so on. + +The \connection@_max@_messages\ option of the \%smtp%\ transport can be used to +limit the number of messages sent down a single TCP/IP connection. +.index asterisk||after IP address +The second and subsequent messages delivered down an existing connection are +identified in the main log by the addition of an asterisk after the closing +square bracket of the IP address. + + + +.section Errors in outgoing SMTP +.rset SECToutSMTPerr "~~chapter.~~section" +.index error||in outgoing SMTP +.index SMTP||errors in outgoing +.index host||error +Three different kinds of error are recognized for outgoing SMTP: host errors, +message errors, and recipient errors. +.numberpars +A host error is not associated with a particular message or with a +particular recipient of a message. The host errors are: +.numberpars $. +Connection refused or timed out, +.nextp +Any error response code on connection, +.nextp +Any error response code to \\EHLO\\ or \\HELO\\, +.nextp +Loss of connection at any time, except after `.', +.nextp +I/O errors at any time, +.nextp +Timeouts during the session, other than in response to \\MAIL\\, \\RCPT\\ or +the `.' at the end of the data. +.endp +For a host error, a permanent error response on connection, or in response to +\\EHLO\\, causes all addresses routed to the host to be failed. Any other host +error causes all addresses to be deferred, and retry data to be created for the +host. It is not tried again, for any message, until its retry time arrives. If +the current set of addresses are not all delivered in this run (to some +alternative host), the message is added to the list of those waiting for this +host, so if it is still undelivered when a subsequent successful delivery is +made to the host, it will be sent down the same SMTP connection. +.nextp +.index message||error +A message error is associated with a particular message when sent to a +particular host, but not with a particular recipient of the message. The +message errors are: +.numberpars $. +Any error response code to \\MAIL\\, \\DATA\\, or the `.' that terminates +the data, +.nextp +Timeout after \\MAIL\\, +.nextp +Timeout +or loss of connection after the `.' that terminates the data. A timeout after +the \\DATA\\ command itself is treated as a host error, as is loss of +connection at any other time. +.endp +For a message error, a permanent error response (5$it{xx}) causes all addresses +to be failed, and a delivery error report to be returned to the sender. A +temporary error response (4$it{xx}), or one of the timeouts, causes all +addresses to be deferred. Retry data is not created for the host, but instead, +a retry record for the combination of host plus message id is created. The +message is not added to the list of those waiting for this host. This ensures +that the failing message will not be sent to this host again until the retry +time arrives. However, other messages that are routed to the host are not +affected, so if it is some property of the message that is causing the error, +it will not stop the delivery of other mail. + +If the remote host specified support for the \\SIZE\\ parameter in its response +to \\EHLO\\, Exim adds SIZE=$it{nnn} to the \\MAIL\\ command, so an +over-large message will cause a message error because the error arrives as a +response to \\MAIL\\. +.nextp +.index recipient||error +A recipient error is associated with a particular recipient of a message. The +recipient errors are: +.numberpars $. +Any error response to \\RCPT\\, +.nextp +Timeout after \\RCPT\\. +.endp +For a recipient error, a permanent error response (5$it{xx}) causes the +recipient address to be failed, and a bounce message to be returned to the +sender. A temporary error response (4$it{xx}) or a timeout causes the failing +address to be deferred, and routing retry data to be created for it. This is +used to delay processing of the address in subsequent queue runs, until its +routing retry time arrives. This applies to all messages, but because it +operates only in queue runs, one attempt will be made to deliver a new message +to the failing address before the delay starts to operate. This ensures that, +if the failure is really related to the message rather than the recipient +(`message too big for this recipient' is a possible example), other messages +have a chance of getting delivered. If a delivery to the address does succeed, +the retry information gets cleared, so all stuck messages get tried again, and +the retry clock is reset. + +The message is not added to the list of those waiting for this host. Use of the +host for other messages is unaffected, and except in the case of a timeout, +other recipients are processed independently, and may be successfully delivered +in the current SMTP session. After a timeout it is of course impossible to +proceed with the session, so all addresses get deferred. However, those other +than the one that failed do not suffer any subsequent retry delays. Therefore, +if one recipient is causing trouble, the others have a chance of getting +through when a subsequent delivery attempt occurs before the failing +recipient's retry time. +.endp + +In all cases, if there are other hosts (or IP addresses) available for the +current set of addresses (for example, from multiple MX records), they are +tried in this run for any undelivered addresses, subject of course to their +own retry data. In other words, recipient error retry data does not take effect +until the next delivery attempt. + +Some hosts have been observed to give temporary error responses to every +\\MAIL\\ command at certain times (`insufficient space' has been seen). It +would be nice if such circumstances could be recognized, and defer data for the +host itself created, but this is not possible within the current Exim design. +What actually happens is that retry data for every (host, message) combination +is created. + +The reason that timeouts after \\MAIL\\ and \\RCPT\\ are treated specially is +that these can sometimes arise as a result of the remote host's verification +procedures. Exim makes this assumption, and treats them as if a temporary error +response had been received. A timeout after `.' is treated specially because it +is known that some broken implementations fail to recognize the end of the +message if the last character of the last line is a binary zero. Thus, it is +helpful to treat this case as a message error. + +Timeouts at other times are treated as host errors, assuming a problem with the +host, or the connection to it. If a timeout after \\MAIL\\, \\RCPT\\, +or `.' is really a connection problem, the assumption is that at the next try +the timeout is likely to occur at some other point in the dialogue, causing it +then to be treated as a host error. + +There is experimental evidence that some MTAs drop the connection after the +terminating `.' if they do not like the contents of the message for some +reason, in contravention of the RFC, which indicates that a 5$it{xx} response +should be given. That is why Exim treats this case as a message rather than a +host error, in order not to delay other messages to the same host. + + + + +.section Variable Envelope Return Paths (VERP) +.index VERP +.index Variable Envelope Return Paths +.index envelope sender +Variable Envelope Return Paths -- see +\?ftp://koobera.math.uic.edu/www/proto/verp.txt?\ -- can be supported in Exim +by using the \return@_path\ generic transport option to rewrite the return path +at transport time. For example, the following could be used on an \%smtp%\ +transport: +.display asis +return_path = \ + ${if match {$return_path}{^(.+?)-request@your.dom.example\$}\ + {$1-request=$local_part%$domain@your.dom.example}fail} +.endd +This has the effect of rewriting the return path (envelope sender) on all +outgoing SMTP messages, if the local part of the original return path ends in +`-request', and the domain is \*your.dom.example*\. The rewriting inserts the +local part and domain of the recipient into the return path. Suppose, for +example, that a message whose return path has been set to +\*somelist-request@@your.dom.example*\ is sent to +\*subscriber@@other.dom.example*\. In the transport, the return path is +rewritten as +.display asis +somelist-request=subscriber%other.dom.example@your.dom.example +.endd +For this to work, you must arrange for outgoing messages that have `-request' +in their return paths to have just a single recipient. This can be done by +setting +.display asis +max_rcpt = 1 +.endd +in the \%smtp%\ transport. Otherwise a single copy of a message might be +addressed to several different recipients in the same domain, in which case +\$local@_part$\ is not available (because it is not unique). Of course, if you +do start sending out messages with this kind of return path, you must also +configure Exim to accept the bounce messages that come back to those paths. +Typically this would be done by setting an \local@_part@_suffix\ option for a +suitable router. + +The overhead incurred in using VERP depends very much on the size of the +message, the number of recipient addresses that resolve to the same remote +host, and the speed of the connection over which the message is being sent. If +a lot of addresses resolve to the same host and the connection is slow, sending +a separate copy of the message for each address may take substantially longer +than sending a single copy with many recipients (for which VERP cannot be +used). + + +.section Incoming SMTP messages over TCP/IP +.index SMTP||incoming over TCP/IP +.index incoming SMTP over TCP/IP +.index inetd +.index daemon +Incoming SMTP messages can be accepted in one of two ways: by running a +listening daemon, or by using \*inetd*\. In the latter case, the entry in +\(/etc/inetd.conf)\ should be like this: +.display asis +smtp stream tcp nowait exim /opt/exim/bin/exim in.exim -bs +.endd +Exim distinguishes between this case and the case of a locally running user +agent using the \-bs-\ option by checking whether or not the standard input is +a socket. When it is, either the port must be privileged (less than 1024), or +the caller must be root or the Exim user. If any other user passes a socket +with an unprivileged port number, Exim prints a message on the standard error +stream and exits with an error code. + +By default, Exim does not make a log entry when a remote host connects or +disconnects (either via the daemon or \*inetd*\), unless the disconnection is +unexpected. It can be made to write such log entries by setting the +\smtp@_connection\ log selector. + +.index carriage return +.index linefeed +Commands from the remote host are supposed to be terminated by CR followed by +LF. However, there are known to be hosts that do not send CR characters. In +order to be able to interwork with such hosts, Exim treats LF on its own as a +line terminator. +Furthermore, because common code is used for receiving messages from all +sources, a CR on its own is also interpreted as a line terminator. However, the +sequence `CR, dot, CR' does not terminate incoming SMTP data. + +.index \\EHLO\\||invalid data +.index \\HELO\\||invalid data +One area that sometimes gives rise to problems concerns the \\EHLO\\ or +\\HELO\\ commands. Some clients send syntactically invalid versions of these +commands, which Exim rejects by default. (This is nothing to do with verifying +the data that is sent, so \helo@_verify@_hosts\ is not relevant.) You can tell +Exim not to apply a syntax check by setting \helo@_accept@_junk@_hosts\ to +match the broken hosts that send invalid commands. + +.index \\SIZE\\ option on \\MAIL\\ command +.index \\MAIL\\||\\SIZE\\ option +The amount of disk space available is checked whenever \\SIZE\\ is received on +a \\MAIL\\ command, independently of whether \message@_size@_limit\ or +\check@_spool@_space\ is configured, unless \smtp__check__spool__space\ is set +false. A temporary error is given if there is not enough space. If +\check@_spool@_space\ is set, the check is for that amount of space plus the +value given with \\SIZE\\, that is, it checks that the addition of the incoming +message will not reduce the space below the threshold. + +When a message is successfully received, Exim includes the local message id in +its response to the final `.' that terminates the data. If the remote host logs +this text it can help with tracing what has happened to a message. + +The Exim daemon can limit the number of simultaneous incoming connections it is +prepared to handle (see the \smtp@_accept@_max\ option). It can also limit the +number of simultaneous incoming connections from a single remote host (see the +\smtp@_accept@_max@_per@_host\ option). Additional connection attempts are +rejected using the SMTP temporary error code 421. + +The Exim daemon does not rely on the \\SIGCHLD\\ signal to detect when a +subprocess has finished, as this can get lost at busy times. Instead, it looks +for completed subprocesses every time it wakes up. Provided there are other +things happening (new incoming calls, starts of queue runs), completed +processes will be noticed and tidied away. On very quiet systems you may +sometimes see a `defunct' Exim process hanging about. This is not a problem; it +will be noticed when the daemon next wakes up. + +When running as a daemon, Exim can reserve some SMTP slots for specific hosts, +and can also be set up to reject SMTP calls from non-reserved hosts at times of +high system load -- for details see the \smtp@_accept@_reserve\, +\smtp@_load@_reserve\, and \smtp@_reserve@_hosts\ options. The load check +applies in both the daemon and \*inetd*\ cases. + +Exim normally starts a delivery process for each message received, though this +can be varied by means of the \-odq-\ command line option and the +\queue@_only\, \queue@_only@_file\, and \queue@_only@_load\ options. The number +of simultaneously running delivery processes started in this way from SMTP +input can be limited by the \smtp__accept__queue\ and +\smtp__accept__queue__per__connection\ options. When either limit is reached, +subsequently received messages are just put on the input queue without starting +a delivery process. + +The controls that involve counts of incoming SMTP calls (\smtp@_accept@_max\, +\smtp@_accept@_queue\, \smtp__accept__reserve\) are not available when Exim is +started up from the \*inetd*\ daemon, because in that case each connection is +handled by an entirely independent Exim process. Control by load average is, +however, available with \*inetd*\. + +Exim can be configured to verify addresses in incoming SMTP commands as they +are received. See chapter ~~CHAPACL for details. It can also be configured to +rewrite addresses at this time -- before any syntax checking is done. See +section ~~SECTrewriteS. + +Exim can also be configured to limit the rate at which a client host submits +\\MAIL\\ and \\RCPT\\ commands in a single SMTP session. See the +\smtp@_ratelimit@_hosts\ option. + + +.section Unrecognized SMTP commands +.index SMTP||unrecognized commands +If Exim receives more than \smtp@_max@_unknown@_commands\ unrecognized SMTP +commands during a single SMTP connection, it drops the connection after sending +the error response to the last command. The default value for +\smtp@_max@_unknown@_commands\ is 3. This is a defence against some kinds of +abuse that subvert web servers into making connections to SMTP ports; in these +circumstances, a number of non-SMTP lines are sent first. + +.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 +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 +broken clients that loop sending bad commands (yes, it has been seen). + + +.section Use of non-mail SMTP commands +.index SMTP||non-mail commands +The `non-mail' SMTP commands are those other than \\MAIL\\, \\RCPT\\, and +\\DATA\\. Exim counts such commands, and drops the connection if there are too +many of them in a single SMTP session. This action catches some +denial-of-service attempts and things like repeated failing \\AUTH\\s, or a mad +client looping sending \\EHLO\\. The global option \smtp@_accept@_max@_nonmail\ +defines what `too many' means. Its default value is 10. + +When a new message is expected, one occurrence of \\RSET\\ is not counted. This +allows a client to send one \\RSET\\ between messages (this is not necessary, +but some clients do it). Exim also allows one uncounted occurence of \\HELO\\ +or \\EHLO\\, and one occurrence of \\STARTTLS\\ between messages. After +starting up a TLS session, another \\EHLO\\ is expected, and so it too is not +counted. + +The first occurrence of \\AUTH\\ in a connection, or immediately following +\\STARTTLS\\ is also not counted. Otherwise, all commands other than \\MAIL\\, +\\RCPT\\, \\DATA\\, and \\QUIT\\ are counted. + +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 +the limit apply to all hosts. This option means that you can exclude any +specific badly-behaved hosts that you have to live with. + + + +.section The \\VRFY\\ and \\EXPN\\ commands +When Exim receives a \\VRFY\\ or \\EXPN\\ command on a TCP/IP connection, it +runs the ACL specified by \acl@_smtp@_vrfy\ or \acl@_smtp@_expn\ (as +appropriate) in order to decide whether the command should be accepted or not. +If no ACL is defined, the command is rejected. + +.index \\VRFY\\||processing +When \\VRFY\\ is accepted, it runs exactly the same code as when Exim is +called with the \-bv-\ option. +.index \\EXPN\\||processing +When \\EXPN\\ is accepted, a single-level expansion of the address is done. +\\EXPN\\ is treated as an `address test' (similar to the \-bt-\ option) rather +than a verification (the \-bv-\ option). If an unqualified local part is given +as the argument to \\EXPN\\, it is qualified with \qualify@_domain\. Rejections +of \\VRFY\\ and \\EXPN\\ commands are logged on the main and reject logs, and +\\VRFY\\ verification failures are logged on the main log for consistency with +\\RCPT\\ failures. + + +.section The \\ETRN\\ command +.rset SECTETRN "~~chapter.~~section" +.index \\ETRN\\||processing +RFC 1985 describes an SMTP command called \\ETRN\\ that is designed to +overcome the security problems of the \\TURN\\ command (which has fallen into +disuse). When Exim receives an \\ETRN\\ command on a TCP/IP connection, it runs +the ACL specified by \acl@_smtp@_etrn\ in order to decide whether the command +should be accepted or not. If no ACL is defined, the command is rejected. + +The \\ETRN\\ command is concerned with `releasing' messages that are awaiting +delivery to certain hosts. As Exim does not organize its message queue by host, +the only form of \\ETRN\\ that is supported by default is the one where the +text starts with the `@#' prefix, in which case the remainder of the text is +specific to the SMTP server. A valid \\ETRN\\ command causes a run of Exim with +the \-R-\ option to happen, with the remainder of the \\ETRN\\ text as its +argument. For example, +.display asis +ETRN #brigadoon +.endd +runs the command +.display asis +exim -R brigadoon +.endd +which causes a delivery attempt on all messages with undelivered addresses +containing the text `brigadoon'. When \smtp@_etrn@_serialize\ is set (the +default), Exim prevents the simultaneous execution of more than one queue run +for the same argument string as a result of an \\ETRN\\ command. This stops +a misbehaving client from starting more than one queue runner at once. + +.index hints database||\\ETRN\\ serialization +Exim implements the serialization by means of a hints database in which a +record is written whenever a process is started by \\ETRN\\, and deleted when +the process completes. However, Exim does not keep the SMTP session waiting for +the \\ETRN\\ process to complete. Once \\ETRN\\ is accepted, the client is sent +a `success' return code. Obviously there is scope for hints records to get left +lying around if there is a system or program crash. To guard against this, Exim +ignores any records that are more than six hours old. + +.index \smtp@_etrn@_command\ +For more control over what \\ETRN\\ does, the \smtp@_etrn@_command\ option can +used. This specifies a command that is run whenever \\ETRN\\ is received, +whatever the form of its argument. For +example: +.display asis +smtp_etrn_command = /etc/etrn_command $domain $sender_host_address +.endd +The string is split up into arguments which are independently expanded. The +expansion variable \$domain$\ is set to the argument of the \\ETRN\\ command, +and no syntax checking is done on the contents of this argument. Exim does not +wait for the command to complete, so its status code is not checked. Exim runs +under its own uid and gid when receiving incoming SMTP, so it is not possible +for it to change them before running the command. + + +.section Incoming local SMTP +.index SMTP||local incoming +Some user agents use SMTP to pass messages to their local MTA using the +standard input and output, as opposed to passing the envelope on the command +line and writing the message to the standard input. This is supported by the +\-bs-\ option. This form of SMTP is handled in the same way as incoming +messages over TCP/IP (including the use of ACLs), except that the envelope +sender given in a \\MAIL\\ command is ignored unless the caller is trusted. In +an ACL you can detect this form of SMTP input by testing for an empty host +identification. It is common to have this as the first line in the ACL that +runs for \\RCPT\\ commands: +.display asis +accept hosts = : +.endd +This accepts SMTP messages from local processes without doing any other tests. + + +.section Outgoing batched SMTP +.rset SECTbatchSMTP "~~chapter.~~section" +.index SMTP||batched outgoing +.index batched SMTP output +Both the \%appendfile%\ and \%pipe%\ transports can be used for handling batched +SMTP. Each has an option called \use@_bsmtp\ which causes messages to be output +in BSMTP format. No SMTP responses are possible for this form of delivery. All +it is doing is using SMTP commands as a way of transmitting the envelope along +with the message. + +The message is written to the file or pipe preceded by the SMTP commands +\\MAIL\\ and \\RCPT\\, and followed by a line containing a single dot. Lines in +the message that start with a dot have an extra dot added. The SMTP command +\\HELO\\ is not normally used. If it is required, the \message@_prefix\ option +can be used to specify it. + +Because \%appendfile%\ and \%pipe%\ are both local transports, they accept only +one recipient address at a time by default. However, you can arrange for them +to handle several addresses at once by setting the \batch@_max\ option. When +this is done for BSMTP, messages may contain multiple \\RCPT\\ commands. See +chapter ~~CHAPbatching for more details. + +When one or more addresses are routed to a BSMTP transport by a router that +sets up a host list, the name of the first host on the list is available to the +transport in the variable \$host$\. Here is an example of such a transport and +router: +.display asis +begin routers +route_append: + driver = manualroute + transport = smtp_appendfile + route_list = domain.example batch.host.example + +begin transports +smtp_appendfile: + driver = appendfile + directory = /var/bsmtp/$host + batch_max = 1000 + use_bsmtp + user = exim +.endd +This causes messages addressed to \*domain.example*\ to be written in BSMTP +format to \(/var/bsmtp/batch.host.example)\, with only a single copy of each +message (unless there are more than 1000 recipients). + + +.section Incoming batched SMTP +.rset SECTincomingbatchedSMTP "~~chapter.~~section" +.index SMTP||batched incoming +.index batched SMTP input +The \-bS-\ command line option causes Exim to accept one or more messages by +reading SMTP on the standard input, but to generate no responses. If the caller +is trusted, the senders in the \\MAIL\\ commands are believed; otherwise the +sender is always the caller of Exim. Unqualified senders and receivers are not +rejected (there seems little point) but instead just get qualified. \\HELO\\ +and \\EHLO\\ act as \\RSET\\; \\VRFY\\, \\EXPN\\, \\ETRN\\ and \\HELP\\, act +as \\NOOP\\; \\QUIT\\ quits. + +No policy checking is done for BSMTP input. That is, no ACL is run at anytime. +In this respect it is like non-SMTP local input. + +If an error is detected while reading a message, including a missing `.' at +the end, Exim gives up immediately. It writes details of the error to the +standard output in a stylized way that the calling program should be able to +make some use of automatically, for example: +.display asis +554 Unexpected end of file +Transaction started in line 10 +Error detected in line 14 +.endd +It writes a more verbose version, for human consumption, to the standard error +file, for example: +.display asis +An error was detected while processing a file of BSMTP input. +The error message was: + + 501 '>' missing at end of address + +The SMTP transaction started in line 10. +The error was detected in line 12. +The SMTP command at fault was: + + rcpt to:<malformed@in.com.plete + +1 previous message was successfully processed. +The rest of the batch was abandoned. +.endd +The return code from Exim is zero only if there were no errors. It is 1 if some +messages were accepted before an error was detected, and 2 if no messages were +accepted. + + + + +. +. +. +. +. ============================================================================ +.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. + +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 +.display asis +control = submission/domain=some.other.domain +.endd +.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 +.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 +.endp + + + +.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: +.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 +.em +or submission-mode +.nem +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 +.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 + +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 +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. + + +.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 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 +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 +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 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 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 Log files +.set runningfoot "log files" +.rset CHAPlog "~~chapter" +.index log||types of +.index log||general description +Exim writes three different logs, referred to as the main log, the reject log, +and the panic log: +.numberpars $. +.index main log +The main log records the arrival of each message and each delivery in a single +line in each case. The format is as compact as possible, in an attempt to keep +down the size of log files. Two-character flag sequences make it easy to pick +out these lines. A number of other events are recorded in the main log. Some of +them are optional, in which case the \log@_selector\ option controls whether +they are included or not. A Perl script called \*eximstats*\, which does simple +analysis of main log files, is provided in the Exim distribution (see section +~~SECTmailstat). +.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 +The first line of each rejection is a copy of the line that is also written to +the main log. Then, if the message's header has been read at the time the log +is written, its contents are written to this log. Only the original header +lines are available; header lines added by ACLs are not logged. You can use the +reject log to check that your policy controls are working correctly; on a busy +host this may be easier than scanning the main log for rejection messages. You +can suppress the writing of the reject log by setting \write@_rejectlog\ false. +.nem +.nextp +.index panic log +.index system log +When certain serious errors occur, Exim writes entries to its panic log. If the +error is sufficiently disastrous, Exim bombs out afterwards. Panic log entries +are usually written to the main log as well, but can get lost amid the mass of +other entries. The panic log should be empty under normal circumstances. It is +therefore a good idea to check it (or to have a \*cron*\ script check it) +regularly, in order to become aware of any problems. When Exim cannot open its +panic log, it tries as a last resort to write to the system log (syslog). This +is opened with LOG@_PID+LOG@_CONS and the facility code of LOG@_MAIL. The +message itself is written at priority LOG@_CRIT. +.endp +Every log line starts with a timestamp, in the format shown in this example: +.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 +ways of changing this: +.numberpars $. +You can set the \timezone\ option to a different time zone; in particular, if +you set +.display asis +timezone = UTC +.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 +example: +.display asis +2003-04-25 11:17:07 +0100 Start queue run: pid=12762 +.endd +.endp + + + +.section Where the logs are written +.rset SECTwhelogwri "~~chapter.~~section" +.index log||destination +.index log||to file +.index log||to syslog +.index syslog +The logs may be written to local files, or to syslog, or both. However, it +should be noted that many syslog implementations use UDP as a transport, and +are therefore unreliable in the sense that messages are not guaranteed to +arrive at the loghost, nor is the ordering of messages necessarily maintained. +It has also been reported that on large log files (tens of megabytes) you may +need to tweak syslog to prevent it syncing the file with each write -- on Linux +this has been seen to make syslog take 90% plus of CPU time. + +The destination for Exim's logs is configured by setting \\LOG@_FILE@_PATH\\ in +\(Local/Makefile)\ or by setting \log@_file@_path\ in the run time +configuration. This latter string is expanded, so it can contain, for example, +references to the host name: +.display asis +log_file_path = /var/log/$primary_hostname/exim_%slog +.endd +It is generally advisable, however, to set the string in \(Local/Makefile)\ +rather than at run time, because then the setting is available right from the +start of Exim's execution. Otherwise, if there's something it wants to log +before it has read the configuration file (for example, an error in the +configuration file) it will not use the path you want, and may not be able to +log at all. + +The value of \\LOG@_FILE@_PATH\\ or \log@_file@_path\ is a colon-separated +list, currently limited to at most two items. This is one option where the +facility for changing a list separator may not be used. The list must always be +colon-separated. If an item in the list is `syslog' then syslog is used; +otherwise the item must either be an absolute path, containing \"%s"\ at the +point where `main', `reject', or `panic' is to be inserted, or be empty, +implying the use of a default path. + +When Exim encounters an empty item in the list, it searches the list defined by +\\LOG@_FILE@_PATH\\, and uses the first item it finds that is neither empty nor +`syslog'. This means that an empty item in \log@_file@_path\ can be used to +mean `use the path specified at build time'. It no such item exists, log files +are written in the \(log)\ subdirectory of the spool directory. This is +equivalent to the setting: +.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 +logs are written. + +A log file path may also contain \"%D"\ if datestamped log file names are in +use -- see section ~~SECTdatlogfil below. + +Here are some examples of possible settings: +.display +.tabs 42 +LOG@_FILE@_PATH=syslog $t $rm{syslog only} +LOG@_FILE@_PATH=:syslog $t $rm{syslog and default path} +LOG@_FILE@_PATH=syslog : /usr/log/exim@_%s $t $rm{syslog and specified path} +LOG@_FILE@_PATH=/usr/log/exim@_%s $t $rm{specified path only} +.endd +If there are more than two paths in the list, the first is used and a panic +error is logged. + + +.section Logging to local files that are periodically `cycled' +.index log||cycling local files +.index cycling logs +.index \*exicyclog*\ +.index log||local files, writing to +Some operating systems provide centralized and standardised methods for cycling +log files. For those that do not, a utility script called \*exicyclog*\ is +provided (see section ~~SECTcyclogfil). This renames and compresses the main +and reject logs each time it is called. The maximum number of old logs to keep +can be set. It is suggested this script is run as a daily \*cron*\ job. + +An Exim delivery process opens the main log when it first needs to write to it, +and it keeps the file open in case subsequent entries are required -- for +example, if a number of different deliveries are being done for the same +message. However, remote SMTP deliveries can take a long time, and this means +that the file may be kept open long after it is renamed if \*exicyclog*\ or +something similar is being used to rename log files on a regular basis. To +ensure that a switch of log files is noticed as soon as possible, Exim calls +\*stat()*\ on the main log's name before reusing an open file, and if the file +does not exist, or its inode has changed, the old file is closed and Exim +tries to open the main log from scratch. Thus, an old log file may remain open +for quite some time, but no Exim processes should write to it once it has been +renamed. + + +.section Datestamped log files +.rset SECTdatlogfil "~~chapter.~~section" +.index log||datestamped files +Instead of cycling the main and reject log files by renaming them +periodically, some sites like to use files whose names contain a datestamp, +for example, \(mainlog-20031225)\. The datestamp is in the form \(yyyymmdd)\. +Exim has support for this way of working. It is enabled by setting the +\log@_file@_path\ option to a path that includes \"%D"\ at the point where the +datestamp is required. For example: +.display asis +log_file_path = /var/spool/exim/log/%slog-%D +log_file_path = /var/log/exim-%s-%D.log +log_file_path = /var/spool/exim/log/%D-%slog +.endd +As before, \"%s"\ is replaced by `main' or `reject'; the following are examples +of names generated by the above examples: +.display asis +/var/spool/exim/log/mainlog-20021225 +/var/log/exim-reject-20021225.log +/var/spool/exim/log/20021225-mainlog +.endd +When this form of log file is specified, Exim automatically switches to new +files at midnight. It does not make any attempt to compress old logs; you +will need to write your own script if you require this. You should not +run \*exicyclog*\ with this form of logging. + +The location of the panic log is also determined by \log@_file@_path\, but it +is not datestamped, because rotation of the panic log does not make sense. +When generating the name of the panic log, \"%D"\ is removed from the string. +In addition, if it immediately follows a slash, a following non-alphanumeric +character is removed; otherwise a preceding non-alphanumeric character is +removed. Thus, the three examples above would give these panic log names: +.display asis +/var/spool/exim/log/paniclog +/var/log/exim-panic.log +/var/spool/exim/log/paniclog +.endd + + +.section Logging to syslog +.index log||syslog, writing to +The use of syslog does not change what Exim logs or the format of its messages, +except in one respect. If \syslog@_timestamp\ is set false, the timestamps on +Exim's log lines are omitted when these lines are sent to syslog. Apart from +that, the same strings are written to syslog as to log files. The syslog +`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 +\(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. +The three log streams are mapped onto syslog priorities as follows: +.numberpars " " +\*mainlog*\ is mapped to \\LOG@_INFO\\ +.nextp +\*rejectlog*\ is mapped to \\LOG@_NOTICE\\ +.nextp +\*paniclog*\ is mapped to \\LOG@_ALERT\\ +.endp +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 +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 +870 data characters. (This allows for a total syslog line length of 1024, when +additions such as timestamps are added.) If you are running a syslog +replacement that can handle lines longer than the 1024 characters allowed by +RFC 3164, you should set +.display asis +SYSLOG_LONG_LINES=yes +.endd +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 +entry starts with a string of the form `[<<n>>/<<m>>]' or `[<<n>>@\<<m>>]' +where <<n>> is the component number and <<m>> is the total number of components +in the entry. The / delimiter is used when the line was split because it was +too long; if it was split because of an internal newline, the @\ delimiter is +used. For example, supposing the length limit to be 70 instead of 1000, the +following would be the result of a typical rejection message to \*mainlog*\ +(LOG@_INFO), each line in addition being preceded by the time, host name, and +pid as added by syslog: +.display +.indent 0 +$smc{[1/3] 2002-09-16 16:09:43 16RdAL-0006pc-00 rejected from [127.0.0.1] (ph10): +[2/3] syntax error in 'From' header when scanning for sender: missing or ma +[3/3] lformed local part in "<>" (envelope sender is <ph10@@cam.example>)} +.endd +The same error might cause the following lines to be written to `rejectlog' +(LOG@_NOTICE): +.display flow +.indent 0 +$smc{[1/14] 2002-09-16 16:09:43 16RdAL-0006pc-00 rejected from [127.0.0.1] (ph10): +[2/14] syntax error in 'From' header when scanning for sender: missing or ma +[3@\14] lformed local part in "@<@>" (envelope sender is <ph10@@cam.example>) +[4@\14] Recipients: ph10@@some.domain.cam.example +[5@\14] P Received: from [127.0.0.1] (ident=ph10) +[6@\14] by xxxxx.cam.example with smtp (Exim 4.00) +[7@\14] id 16RdAL-0006pc-00 +[8@\14] for ph10@@cam.example; Mon, 16 Sep 2002 16:09:43 +0100 +[9@\14] F From: @<@> +[10@\14] Subject: this is a test header +[11@\14] X-something: this is another header +[12@\14] I Message-Id: <E16RdAL-0006pc-00@@xxxxx.cam.example> +[13@\14] B Bcc: +[14/14] Date: Mon, 16 Sep 2002 16:09:43 +0100} +.endd +Log lines that are neither too long nor contain newlines are written to syslog +without modification. + +If only syslog is being used, the Exim monitor is unable to provide a log tail +display, unless syslog is routing \*mainlog*\ to a file on the local host and +the environment variable \\EXIMON@_LOG@_FILE@_PATH\\ is set to tell the monitor +where it is. + + +.section Log line flags +One line is written to the main log for each message received, and for each +successful, unsuccessful, and delayed delivery. These lines can readily be +picked out by the distinctive two-character flags that immediately follow the +timestamp. The flags are: +.display +.tabs 6 +<= $t $rm{message arrival} +=> $t $rm{normal message delivery} +-> $t $rm{additional address in same delivery} +*> $t $rm{delivery suppressed by \-N-\} +** $t $rm{delivery failed; address bounced} +== $t $rm{delivery deferred; temporary problem} +.endd + + +.section Logging message reception +.index log||reception line +The format of the single-line entry in the main log that is written for every +message received is shown in the basic example below, which is split over +several lines in order to fit it on the page: +.display +.indent 0 +2002-10-31 08:57:53 16ZCW1-0005MB-00 <= kryten@@dwarf.fict.example + H=mailer.fict.example [192.168.123.123] U=exim + P=smtp S=5678 id=<<incoming message id>> +.endd +The address immediately following `<=' is the envelope sender address. A bounce +message is shown with the sender address `<>', and if it is locally generated, +this is followed by an item of the form +.display +R=<<message id>> +.endd +which is a reference to the message that caused the bounce to be sent. + +.index \\HELO\\ +.index \\EHLO\\ +For messages from other hosts, the H and U fields identify the remote host and +record the RFC 1413 identity of the user that sent the message, if one was +received. The number given in square brackets is the IP address of the sending +host. If there is a single, unparenthesized host name in the H field, as +above, it has been verified to correspond to the IP address (see the +\host@_lookup\ option). If the name is in parentheses, it was the name quoted +by the remote host in the SMTP \\HELO\\ or \\EHLO\\ command, and has not been +verified. If verification yields a different name to that given for \\HELO\\ or +\\EHLO\\, the verified name appears first, followed by the \\HELO\\ or \\EHLO\\ +name in parentheses. + +Misconfigured hosts (and mail forgers) sometimes put an IP address, with or +without brackets, in the \\HELO\\ or \\EHLO\\ command, leading to entries in +the log containing text like these examples: +.display +H=(10.21.32.43) [192.168.8.34] +H=([10.21.32.43]) [192.168.8.34] +.endd +This can be confusing. Only the final address in square brackets can be relied +on. + +For locally generated messages (that is, messages not received over TCP/IP), +the H field is omitted, and the U field contains the login name of the caller +of Exim. + +.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. + +The id field records the existing message id, if present. +.index size||of message +The size of the received message is given by the S field. When the message is +delivered, headers may get removed or added, so that the size of delivered +copies of the message may not correspond with this value (and indeed may be +different to each other). + +The \log@_selector\ option can be used to request the logging of additional +data when a message is received. See section ~~SECTlogselector below. + + +.section Logging deliveries +.index log||delivery line +The format of the single-line entry in the main log that is written for every +delivery is shown in one of the examples below, for local and remote deliveries, +respectively. Each example has been split into two lines in order to fit +it on the page: +.display +.indent 0 +2002-10-31 08:59:13 16ZCW1-0005MB-00 => marv <marv@@hitch.fict.example> + R=localuser T=local@_delivery +2002-10-31 09:00:10 16ZCW1-0005MB-00 => monk@@holistic.fict.example + R=dnslookup T=remote@_smtp H=holistic.fict.example [192.168.234.234] +.endd +For ordinary local deliveries, the original address is given in angle brackets +after the final delivery address, which might be a pipe or a file. If +intermediate address(es) exist between the original and the final address, the +last of these is given in parentheses after the final address. The R and T +fields record the router and transport that were used to process the address. + +If a shadow transport was run after a successful local delivery, the log line +for the successful delivery has an item added on the end, of the form +.display +ST=<<shadow transport name>> +.endd +If the shadow transport did not succeed, the error message is put in +parentheses afterwards. + +When more than one address is included in a single delivery (for example, two +SMTP \\RCPT\\ commands in one transaction) the second and subsequent +addresses are flagged with `$tt{@-@>}' instead of `$tt{@=@>}'. When two or more +messages are delivered down a single SMTP connection, an asterisk follows the +IP address in the log lines for the second and subsequent messages. + +The generation of a reply message by a filter file gets logged as a `delivery' +to the addressee, preceded by `>'. + +The \log@_selector\ option can be used to request the logging of additional +data when a message is delivered. See section ~~SECTlogselector below. + + +.section Discarded deliveries +.index discarded messages +.index message||discarded +.index delivery||discarded, logging +When a message is discarded as a result of the command `seen finish' being +obeyed in a filter file which generates no deliveries, a log entry of the form +.display +2002-12-10 00:50:49 16auJc-0001UB-00 => discarded + <low.club@@bridge.example> R=userforward +.endd +is written, to record why no deliveries are logged. When a message is discarded +because it is aliased to `:blackhole:' the log line is like this: +.display asis +1999-03-02 09:44:33 10HmaX-0005vi-00 => :blackhole: + <hole@nowhere.example> R=blackhole_router +.endd + + +.section Deferred deliveries +When a delivery is deferred, a line of the following form is logged: +.display +.indent 0 +2002-12-19 16:20:23 16aiQz-0002Q5-00 == marvin@@endrest.example + R=dnslookup T=smtp defer (146): Connection refused +.endd +In the case of remote deliveries, the error is the one that was given for the +last IP address that was tried. Details of individual SMTP failures are also +written to the log, so the above line would be preceded by something like +.display +.indent 0 +2002-12-19 16:20:23 16aiQz-0002Q5-00 Failed to connect to + mail1.endrest.example [192.168.239.239]: Connection refused +.endd +When a deferred address is skipped because its retry time has not been reached, +a message is written to the log, but this can be suppressed by setting an +appropriate value in \log@_selector\. + + +.section Delivery failures +.index delivery||failure, logging +If a delivery fails because an address cannot be routed, a line of the +following form is logged: +.display asis +.indent 0 +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 +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>... + 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 +disabling \\PIPELINING\\. +.nem + +The log lines for all forms of delivery failure are flagged with \"**"\. + + +.section Fake deliveries +.index delivery||fake, logging +If a delivery does not actually take place because the \-N-\ option has been +used to suppress it, a normal delivery line is written to the log, except that +`=>' is replaced by `$*$>'. + + +.section Completion +A line of the form +.display +2002-10-31 09:00:11 16ZCW1-0005MB-00 Completed +.endd +is written to the main log when a message is about to be removed from the spool +at the end of its processing. + + + +.section Summary of Fields in Log Lines +.index log||summary of fields +A summary of the field identifiers that are used in log lines is shown in +the following table: +.display flow +.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 +.nem +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 +.nem +R $t $rm{on \"<="\ lines: reference for local bounce} + $t $rm{on \"=>"\ lines: router name} +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} +U $t $rm{local user or RFC 1413 identity} +X $t $rm{TLS cipher suite} +.endd + + +.section Other log entries +Various other types of log entry are written from time to time. Most should be +self-explanatory. Among the more common are: +.numberpars $. +.index retry||time not reached +\*retry time not reached*\##An address previously suffered a temporary error +during routing or local delivery, and the time to retry has not yet arrived. +This message is not written to an individual message log file unless it happens +during the first delivery attempt. +.nextp +\*retry time not reached for any host*\##An address previously suffered +temporary errors during remote delivery, and the retry time has not yet arrived +for any of the hosts to which it is routed. +.nextp +.index spool directory||file locked +\*spool file locked*\##An attempt to deliver a message cannot proceed because +some other Exim process is already working on the message. This can be quite +common if queue running processes are started at frequent intervals. The +\*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 +message: +.numberpars " " +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 +failed. The delivery was discarded. +.nextp +A delivery set up by a router configured with +.display asis +errors_to = <> +.endd +failed. The delivery was discarded. +.endp +.nem +.endp + + + +.section Reducing or increasing what is logged +.rset SECTlogselector "~~chapter.~~section" +.index log||selectors +By setting the \log@_selector\ global option, you can disable some of Exim's +default logging, or you can request additional logging. The value of +\log@_selector\ is made up of names preceded by plus or minus characters. For +example: +.display asis +log_selector = +arguments -retry_defer +.endd +The list of optional log items is in the following table, with the default +selection marked by asterisks: +.display flow +.tabs 32 + address@_rewrite $t $rm{address rewriting} + 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 + 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 +.nem + 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 + 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} + + all $t $rm{all of the above} +.endd +More details on each of these items follows: +.numberpars $. +.index log||rewriting +.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 +cannot access the log). +.nem +.nextp +.index log||full parentage +\all@_parents\: Normally only the original and final addresses are logged on +delivery lines; with this selector, intermediate parents are given in +parentheses between them. +.nextp +.index log||Exim arguments +.index Exim arguments, logging +\arguments\: This causes Exim to write the arguments with which it was called +to the main log, +preceded by the current working directory. +This is a debugging feature, added to make it easier to find out how certain +MUAs call \(/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 +characters are shown as escape sequences. +This facility cannot log unrecognized arguments, because the arguments are +checked before the configuration file is read. The only way to log such cases +is to interpose a script such as \(util/logargs.sh)\ between the caller and +Exim. +.nextp +.index log||connection rejections +\connection@_reject\: A log entry is written whenever an incoming SMTP +connection is rejected, for whatever reason. +.nextp +.index log||delayed delivery +.index delayed delivery, logging +\delay@_delivery\: A log entry is written whenever a delivery process is not +started for an incoming message because the load is too high or too many +messages were received on one connection. Logging does not occur if no delivery +process is started because \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 +\delivery@_size\: For each delivery, the size of message delivered is added to +the `=>' line, tagged with S=. +.nextp +.index log||dnslist defer +.index DNS list||logging defer +.index black list (DNS) +\dnslist@_defer\: A log entry is written if an attempt to look up a host in a +DNS black list suffers a temporary error. +.nextp +.index log||ETRN commands +.index \\ETRN\\||logging +\etrn\: Every legal ETRN command that is received is logged, before the ACL is +run to determine whether or not it is actually accepted. An invalid ETRN +command, or one received within a message transaction is not logged by this +selector (see \smtp@_syntax@_error\ and \smtp@_protocol@_error\). +.nextp +.index log||host lookup failure +\host@_lookup@_failed\: When a lookup of a host's IP addresses fails to find +any addresses, or when a lookup of an IP address fails to find a host name, a +log line is written. This logging does not apply to direct DNS lookups when +routing email addresses, but it does apply to `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 +.index TCP/IP||logging incoming remote port +\incoming@_port\: The remote port number from which a message was received is +added to log entries and ::Received:: header lines, following the IP address in +square brackets, and separated from it by a colon. This is implemented by +changing the value that is put in the \$sender@_fullhost$\ and +\$sender@_rcvhost$\ variables. Recording the remote port number has become more +important with the widening use of NAT (see RFC 2505). +.nextp +.index log||dropped connection +\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 +\outgoing@_port\: The remote port number is added to delivery log lines (those +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. +.nem +.nextp +.index log||recipients +\received@_recipients\: The recipients of a message are listed in the main log +as soon as the message is received. The list appears at the end of the log line +that is written when a message is received, preceded by the word `for'. The +addresses are listed after they have been qualified, but before any rewriting +has taken place. +Recipients that were discarded by an ACL for \\MAIL\\ or \\RCPT\\ do not appear +in the list. +.nextp +.index log||sender reception +\received@_sender\: The unrewritten original sender of a message is added to +the end of the log line that records the message's arrival, after the word +`from' (before the recipients if \received@_recipients\ is also set). +.nextp +.index log||header lines for rejection +\rejected@_header\: If a message's header has been received at the time a +rejection is written to the reject log, the complete header is added to the +log. Header logging can be turned off individually for messages that are +rejected by the \*local@_scan()*\ function (see section ~~SECTapiforloc). +.nextp +.index log||retry defer +\retry@_defer\: A log line is written if a delivery is deferred because a retry +time has not yet been reached. However, this `retry time not reached' message +is always omitted from individual message logs after the first delivery +attempt. +.nextp +.index log||return path +.em +\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=. +.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 +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 +is too big. +.nextp +.index log||frozen messages, skipped +.index frozen messages||logging skipping +\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. +.nextp +.index log||smtp confirmation +.index SMTP||logging confirmation +\smtp@_confirmation\: The response to the final `.' in the SMTP dialogue for +outgoing messages is added to delivery log lines in the form `C="<<text>>"'. A +number of MTAs (including Exim) return an identifying string in this response. +.nextp +.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. + +For TCP/IP connections to an Exim daemon, the current number of connections is +included in the log message for each new connection, but note that the count is +reset if the daemon is restarted. +Also, because connections are closed (and the closure is logged) in +subprocesses, the count may not include connections that have been closed but +whose termination the daemon has not yet noticed. Thus, while it is possible to +match up the opening and closing of connections in the log, the value of the +logged counts may not be entirely accurate. +.nextp +.index log||SMTP transaction, incomplete +.index SMTP||logging incomplete transactions +\smtp@_incomplete@_transaction\: When a mail transaction is aborted by +\\RSET\\, \\QUIT\\, loss of connection, or otherwise, the incident is logged, +and the message sender plus any accepted recipients are included in the log +line. This can provide evidence of dictionary attacks. +.nextp +.index log||SMTP protocol error +.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 +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 SMTP||unknown command, logging +.index log||unknown SMTP command +.index log||SMTP syntax error +\smtp@_syntax@_error\: A log line is written for every SMTP syntax error +encountered. An unrecognized command is treated as a syntax error. For an +external connection, the host identity is given; for an internal connection +using \-bs-\ the sender identification (normally the calling user) is given. +.nextp +.index log||subject +.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 +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 +\tls@_cipher\: When a message is sent or received over an encrypted connection, +the cipher suite used is added to the log line, preceded by X=. +.nextp +.index log||TLS peer DN +.index TLS||logging peer DN +\tls@_peerdn\: When a message is sent or received over an encrypted connection, +and a certificate is supplied by the remote host, the peer DN is added to the +log line, preceded by DN=. +.endp + +.section Message log +.index message||log file for +.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 +they are kept in the \(msglog)\ sub-directory of the spool directory. Each +message log contains copies of the log lines that apply to the message. This +makes it easier to inspect the status of an individual message without having +to search the main log. A message log is deleted when processing of the message +is complete, +.index \preserve@_message@_logs\ +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 +\message@_logs\ option false. + + + +. +. +. +. ============================================================================ +.chapter Exim utilities +.set runningfoot "utilities" +.rset CHAPutils ~~chapter +.index utilities +A number of utility scripts and programs are supplied with Exim and are +described in this chapter. There is also the Exim Monitor, which is covered in +the next chapter. The utilities described here are: + +. This duplication seems to be the only way to arrange that the cross- +. references are omitted in the Texinfo version. They look horribly ugly. + +.if ~~texinfo +.display rm +.tabs 22 +\*exiwhat*\ $t $rm{list what Exim processes are doing} +.newline +\*exiqgrep*\ $t $rm{grep the queue} +.newline +\*exiqsumm*\ $t $rm{summarize the queue} +\*exigrep*\ $t $rm{search the main log} +\*exipick*\ $t $rm{select messages on various criteria} +\*exicyclog*\ $t $rm{cycle (rotate) log files} +\*eximstats*\ $t $rm{extract statistics from the log} +\*exim@_checkaccess*\ $t $rm{check address acceptance from given IP} +\*exim@_dbmbuild*\ $t $rm{build a DBM file} +\*exinext*\ $t $rm{extract retry information} +\*exim@_dumpdb*\ $t $rm{dump a hints database} +\*exim@_tidydb*\ $t $rm{clean up a hints database} +\*exim@_fixdb*\ $t $rm{patch a hints database} +\*exim@_lock*\ $t $rm{lock a mailbox file} +.endd +. +.else +. +.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} +~~SECTdbmbuild \*exim@_dbmbuild*\ $t $rm{build a DBM file} +~~SECTfinindret \*exinext*\ $t $rm{extract retry information} +~~SECThindatmai \*exim@_dumpdb*\ $t $rm{dump a hints database} +~~SECThindatmai \*exim@_tidydb*\ $t $rm{clean up a hints database} +~~SECThindatmai \*exim@_fixdb*\ $t $rm{patch a hints database} +~~SECTmailboxmaint \*exim@_lock*\ $t $rm{lock a mailbox file} +.endd +.fi + +.section Finding out what Exim processes are doing (exiwhat) +.rset SECTfinoutwha "~~chapter.~~section" +.index \*exiwhat*\ +.index process, querying +.index \\SIGUSR1\\ +On operating systems that can restart a system call after receiving a signal +(most modern OS), an Exim process responds to the \\SIGUSR1\\ signal by writing +a line describing what it is doing to the file \(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 +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 +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 +doesn't seem to be working for you, check the following compile-time options: +.display +EXIWHAT@_PS@_CMD $rm{the command for running \*ps*\} +EXIWHAT@_PS@_ARG $rm{the argument for \*ps*\} +EXIWHAT@_EGREP@_ARG $rm{the argument for \*egrep*\ to select from \*ps*\ output} +EXIWHAT@_KILL@_ARG $rm{the argument for the \*kill*\ command} +.endd +An example of typical output from \*exiwhat*\ is +.display +.indent 0 + 164 daemon: -q1h, listening on port 25 +10483 running queue: waiting for 0tAycK-0002ij-00 (10492) +10492 delivering 0tAycK-0002ij-00 to mail.ref.example [10.19.42.42] + (editor@@ref.example) +10592 handling incoming call from [192.168.243.242] +10628 accepting a local non-SMTP message +.endd +The first number in the output line is the process number. The third line has +been split here, in order to fit it on the page. + + +.section Selective queue listing (exiqgrep) +.rset SECTgreptheque "~~chapter.~~section" +.index \*exiqgrep*\ +.index queue||grepping +This utility is a Perl script contributed by Matt Hubbard. It runs +.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 +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 +.display asis +exiqgrep -f '^<>$' +.endd + +.option r <<regex>> +Match a recipient address. The field that is tested is not enclosed in angle +brackets. + +.option s <<regex>> +Match against the size field. + +.option y <<seconds>> +Match messages that are younger than the given time. + +.option o <<seconds>> +Match messages that are older than the given time. + +.option z +Match only frozen messages. + +.option x +Match only non-frozen messages. + +.endoptions + +The following options control the format of the output: + +.startoptions + +.option c +Display only the count of matching messages. + +.option l +Long format -- display the full message information as output by Exim. This is +the default. + +.option i +Display message ids only. + +.option b +Brief format -- one line per message. + +.option R +Display messages in reverse order. + +.endoptions + +There is one more option, \-h-\, which outputs a list of options. + + +.section Summarising the queue (exiqsumm) +.rset SECTsumtheque "~~chapter.~~section" +.index \*exiqsumm*\ +.index queue||summary +The \*exiqsumm*\ utility is a Perl script which reads the output of \*exim +-bp*\ and produces a summary of the messages on the queue. Thus, you use it by +running a command such as +.display asis +exim -bp | exiqsumm +.endd +The output consists of one line for each domain that has messages waiting for +it, as in the following example: +.display asis + 3 2322 74m 66m msn.com.example +.endd +Each line lists the number of +pending deliveries for a domain, their total volume, and the length of time +that the oldest and the newest messages have been waiting. Note that the number +of pending deliveries is greater than the number of messages when messages +have more than one recipient. + +A summary line is output at the end. By default the output is sorted on the +domain name, but \*exiqsumm*\ has the options \-a-\ and \-c-\, which cause the +output to be sorted by oldest message and by count of messages, respectively. + +The output of \*exim -bp*\ contains the original addresses in the message, so +this also applies to the output from \*exiqsumm*\. No domains from addresses +generated by aliasing or forwarding are included (unless the \one@_time\ option +of the \%redirect%\ router has been used to convert them into `top level' +addresses). + + + +.section Extracting specific information from the log (exigrep) +.rset SECTextspeinf "~~chapter.~~section" +.index \*exigrep*\ +.index log||extracts, grepping for +The \*exigrep*\ utility is a Perl script that searches one or more main log +files for entries that match a given pattern. When it finds a match, it +extracts all the log entries for the relevant message, not just those that +match the pattern. Thus, \*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 +they spent more than <<n>> seconds on the queue. + +The \-l-\ flag means `literal', that is, treat all characters in the +pattern as standing for themselves. Otherwise the pattern must be a Perl +regular expression. The pattern match is case-insensitive. If no file names are +given on the command line, the standard input is read. + +If the location of a \*zcat*\ command is known from the definition of +\\ZCAT@_COMMAND\\ in \(Local/Makefile)\, \*exigrep*\ automatically passes any +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*\ +John Jetmore's \*exipick*\ utility is included in the Exim distribution. It +lists messages from the queue according to a variety of criteria. For details, +run: +.display asis +exipick --help +.endd +.nem + + +.section Cycling log files (exicyclog) +.rset SECTcyclogfil "~~chapter.~~section" +.index log||cycling local files +.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 +\(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. + +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, +using a compression command which is configured by the \\COMPRESS@_COMMAND\\ +setting in \(Local/Makefile)\. It is usual to run \*exicyclog*\ daily from a +root \crontab\ entry of the form +.display +1 0 * * * su exim -c /usr/exim/bin/exicyclog +.endd +assuming you have used the name `exim' for the Exim user. You can run +\*exicyclog*\ as root if you wish, but there is no need. + + +.section Mail statistics (eximstats) +.rset SECTmailstat "~~chapter.~~section" +.index statistics +.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 +LogReport Foundation (\?http://www.logreport.org?\). + +The \*eximstats*\ script has been hacked about quite a bit over time. The +latest version is the result of some extensive revision by Steve Campbell. A +lot of information is given by default, but there are options for suppressing +various parts of it. Following any options, the arguments to the script are a +list of files, which should be main log files. For example: +.display asis +eximstats -nr /var/spool/exim/log/mainlog.01 +.endd +By default, \*eximstats*\ extracts information about the number and volume of +messages received from or delivered to various hosts. The information is sorted +both by message count and by volume, and the top fifty hosts in each category +are listed on the standard output. Similar information, based on email +addresses or domains instead of hosts can be requested by means of various +options. For messages delivered and received locally, similar statistics are +also produced per user. + +The output also includes total counts and statistics about delivery errors, and +histograms showing the number of messages received and deliveries made in each +hour of the day. A delivery with more than one address in its envelope (for +example, an SMTP transaction with more than one \\RCPT\\ command) is counted +as a single delivery by \*eximstats*\. + +Though normally more deliveries than receipts are reported (as messages may +have multiple recipients), it is possible for \*eximstats*\ to report more +messages received than delivered, even though the queue is empty at the start +and end of the period in question. If an incoming message contains no valid +recipients, no deliveries are recorded for it. A bounce message is handled as +an entirely separate message. + +\*eximstats*\ always outputs a grand total summary giving the volume and number +of messages received and deliveries made, and the number of hosts involved in +each case. It also outputs the number of messages that were delayed (that is, +not completely delivered at the first attempt), and the number that had at +least one address that failed. + +The remainder of the output is in sections that can be independently disabled +or modified by various options. It consists of a summary of deliveries by +transport, histograms of messages received and delivered per time interval +(default per hour), information about the time messages spent on the queue, +a list of relayed messages, lists of the top fifty sending hosts, local +senders, destination hosts, and destination local users by count and by volume, +and a list of delivery errors that occurred. + +The relay information lists messages that were actually relayed, that is, they +came from a remote host and were directly delivered to some other remote host, +without being processed (for example, for aliasing or forwarding) locally. + +The options for \*eximstats*\ are as follows: + +.startoptions +.index \*eximstats*\||options +.option bydomain +The `league tables' are computed on the basis of the superior domains of the +sending hosts instead of the sending and receiving hosts. This option may be +combined with \-byhost-\ and/or \-byemail-\. + +.option byedomain +This is a synonym for \-byemaildomain-\. + +.option byemail +The `league tables' are computed on the basis of complete email addresses, +instead of sending and receiving hosts. This option may be combined with +\-byhost-\ and/or \-bydomain-\. + +.option byemaildomain +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 byhost +The `league tables' are computed on the basis of sending and receiving hosts. +This is the default option. It may be combined with \-bydomain-\ and/or +\-byemail-\. + +.option cache +Cache results of \*timegm()*\ lookups. This results in a significant speedup +when processing hundreds of thousands of messages, at a cost of increasing the +memory utilisation. + +.option chartdir <<dir>> +When \-charts-\ is specified, create the charts in the directory <<dir>>. + +.option chartrel <<dir>> +When \-charts-\ is specified, this option specifies the relative directory for +the \"img src="\ tags from where to include the charts. + +.option charts +Create graphical charts to be displayed in HTML output. This requires the +\"GD"\, \"GDTextUtil"\, and \"GDGraph"\ Perl modules, which can be obtained +from \?http://www.cpan.org/modules/01modules.index.html?\. + +To install these, download and unpack them, then use the normal Perl +installation procedure: +.display asis +perl Makefile.PL +make +make test +make install +.endd + +.option d +This is a debug flag. It causes \*eximstats*\ to output the \*eval()*\'d parser +to the standard output, which makes it easier to trap errors in the eval +section. Remember to add one to the line numbers to allow for the title. + + +.option help +Show help information about \*eximstats*\' options. + +.option h <<n>> +This option controls the histograms of messages received and deliveries per +time interval. By default the time interval is one hour. If \-h0-\ is given, +the histograms are suppressed; otherwise the value of <<n>> gives the number of +divisions per hour. Valid values are 0, 1, 2, 3, 5, 10, 15, 20, 30 or 60, so +\-h2-\ sets an interval of 30 minutes, and the default is equivalent to \-h1-\. + +.option html +Output the results in HTML instead of plain text. + +.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 +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 +eximstats mainlog.sun > report.sun.txt +eximstats mainlog.mon > report.mon.txt +eximstats mainlog.tue > report.tue.txt +eximstats mainlog.wed > report.wed.txt +eximstats mainlog.thu > report.thu.txt +eximstats mainlog.fri > report.fri.txt +eximstats mainlog.sat > report.sat.txt +eximstats -merge -html report.*.txt > weekly_report.html +.endd +You can merge text or html reports and output the results as text or html. You +can use all the normal \*eximstats*\ output options, but only data included in +the original reports can be shown. When merging reports, some loss of accuracy +may occur in the `league tables', towards the ends of the lists. The order of +items in the `league tables' may vary when the data volumes round to the same +value. + +.option ne +Suppress the display of information about failed deliveries (errors). + +.option nr +Suppress information about messages relayed through this host. + +.option nr /pattern/ +Suppress information about relayed messages that match the pattern, which is +matched against a string of the following form (split over two lines here in +order to fit it on the page): +.display asis +H=<host> [<ip address>] A=<sender address> => + H=<host> A=<recipient address> +.endd +for example +.display asis +H=in.host [1.2.3.4] A=from@some.where.example => + H=out.host A=to@else.where.example +.endd +The sending host name appears in parentheses if it has not been verified as +matching the IP address. The mail addresses are taken from the envelope, not +the headers. This option allows you to screen out hosts whom you are happy to +have using your host as a relay. + +.option nt +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 +transport from your normal statistics (on the grounds that it is of no +interest). + + +.option "pattern" "#<<description>>#/<<pattern>>/" +Count lines matching specified patterns and show them in +the results. For example: +.display asis +-pattern 'Refused connections' '/refused connection/' +.endd +This option can be specified multiple times. + +.option q0 +Suppress information about times messages spend on the queue. + +.option q <<n1>>... +This option sets an alternative list of time intervals for the queueing +information. The values are separated by commas and are in seconds, but can +involve arithmetic multipliers, so for example you can set 3$*$60 to specify 3 +minutes. A setting such as +.display asis +-q60,5*60,10*60 +.endd +causes \*eximstats*\ to give counts of messages that stayed on the queue for less +than one minute, less than five minutes, less than ten minutes, and over ten +minutes. + +.option t <<n>> +Sets the `top' count to <<n>>. This controls the listings of the `top <<n>>' +hosts and users by count and volume. The default is 50, and setting 0 +suppresses the output altogether. + +.option tnl +Omit local information from the `top' listings. + +.option t@_remote@_users +Include remote users in the `top' listings. + +.endoptions + + +.section Checking access policy (exim@_checkaccess) +.rset SECTcheckaccess "~~chapter.~~section" +.index \*exim@_checkaccess*\ +.index policy control||checking access +.index checking access +The \-bh-\ command line argument allows you to run a fake SMTP session with +debugging output, in order to check what Exim is doing when it is applying +policy controls to incoming SMTP mail. However, not everybody is sufficiently +familiar with the SMTP protocol to be able to make full use of \-bh-\, and +sometimes you just want to answer the question \*Does this address have +access?*\ without bothering with any further details. + +The \*exim@_checkaccess*\ utility is a `packaged' version of \-bh-\. It takes +two arguments, an IP address and an email address: +.display asis +exim_checkaccess 10.9.8.7 A.User@a.domain.example +.endd +The utility runs a call to Exim with the \-bh-\ option, to test whether the +given email address would be accepted in a \\RCPT\\ command in a TCP/IP +connection from the host with the given IP address. The output of the utility +is either the word `accepted', or the SMTP error response, for example: +.display asis +Rejected: + 550 Relay not permitted +.endd +When running this test, the utility uses \"<>"\ as the envelope sender address +for the \\MAIL\\ command, but you can change this by providing additional +options. These are passed directly to the Exim command. For example, to specify +that the test is to be run with the sender address \*himself@@there.example*\ +you can use: +.display asis +exim_checkaccess 10.9.8.7 A.User@a.domain.example \ + -f himself@there.example +.endd +Note that these additional Exim command line items must be given after the two +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-\, +but this is not yet available in a `packaged' form. + + +.section Making DBM files (exim@_dbmbuild) +.rset SECTdbmbuild "~~chapter.~~section" +.index DBM||building dbm files +.index building DBM files +.index \*exim@_dbmbuild*\ +.index lower casing +.index binary zero||in lookup key +The \*exim@_dbmbuild*\ program reads an input file containing keys and data in +the format used by the \%lsearch%\ lookup (see section ~~SECTsinglekeylookups). +It writes a DBM file using the lower-cased alias names as keys and the +remainder of the information as data. The lower-casing can be prevented by +calling the program with the \-nolc-\ option. + +A terminating zero is included as part of the key string. This is expected by +the \%dbm%\ lookup type. However, if the option \-nozero-\ is given, +\*exim@_dbmbuild*\ creates files without terminating zeroes in either the key +strings or the data strings. The \%dbmnz%\ lookup type can be used with such +files. + +The program requires two arguments: the name of the input file (which can be a +single hyphen to indicate the standard input), and the name of the output file. +It creates the output under a temporary name, and then renames it if all went +well. +.index \\USE@_DB\\ +If the native DB interface is in use (\\USE@_DB\\ is set in a compile-time +configuration file -- this is common in free versions of Unix) the two file +names must be different, because in this mode the Berkeley DB functions create +a single output file using exactly the name given. For example, +.display asis +exim_dbmbuild /etc/aliases /etc/aliases.db +.endd +reads the system alias file and creates a DBM version of it in +\(/etc/aliases.db)\. + +In systems that use the \*ndbm*\ routines (mostly proprietary versions of Unix), +two files are used, with the suffixes \(.dir)\ and \(.pag)\. In this +environment, the suffixes are added to the second argument of +\*exim@_dbmbuild*\, so it can be the same as the first. This is also the case +when the Berkeley functions are used in compatibility mode (though this is not +recommended), because in that case it adds a \(.db)\ suffix to the file name. + +If a duplicate key is encountered, the program outputs a warning, and when it +finishes, its return code is 1 rather than zero, unless the \-noduperr-\ option +is used. By default, only the first of a set of duplicates is used -- this +makes it compatible with \%lsearch%\ lookups. There is an option \-lastdup-\ +which causes it to use the data for the last duplicate instead. There is also +an option \-nowarn-\, which stops it listing duplicate keys to \stderr\. For +other errors, where it doesn't actually make a new file, the return code is 2. + + + +.section Finding individual retry times (exinext) +.rset SECTfinindret "~~chapter.~~section" +.index retry||times +.index \*exinext*\ +A utility called \*exinext*\ (mostly a Perl script) provides the ability to fish +specific information out of the retry database. Given a mail domain (or a +complete address), it looks up the hosts for that domain, and outputs any retry +information for the hosts or for the domain. At present, the retry information +is obtained by running \*exim@_dumpdb*\ (see below) and post-processing the +output. For example: +.display asis +$ exinext piglet@milne.fict.example +kanga.milne.fict.example:192.168.8.1 error 146: Connection refused + first failed: 21-Feb-1996 14:57:34 + last tried: 21-Feb-1996 14:57:34 + next try at: 21-Feb-1996 15:02:34 +roo.milne.fict.example:192.168.8.3 error 146: Connection refused + first failed: 20-Jan-1996 13:12:08 + last tried: 21-Feb-1996 11:42:03 + next try at: 21-Feb-1996 19:42:03 + past final cutoff time +.endd +You can also give \*exinext*\ a local part, without a domain, and it +will give any retry information for that local part in your default domain. +A message id can be used to obtain retry information pertaining to a specific +message. This exists only when an attempt to deliver a message to a remote host +suffers a message-specific error (see section ~~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 + + + +.section Hints database maintenance (exim@_dumpdb, exim@_fixdb, exim@_tidydb) +.rset SECThindatmai "~~chapter.~~section" +.index hints database||maintenance +.index maintaining Exim's hints database +Three utility programs are provided for maintaining the DBM files that Exim +uses to contain its delivery hint information. Each program requires two +arguments. The first specifies the name of Exim's spool directory, and the +second is the name of the database it is to operate on. These are as +follows: +.numberpars $. +\*retry*\: the database of retry information +.nextp +\*wait-*\<<transport name>>: databases of information about messages waiting +for remote hosts +.nextp +.em +\*callout*\: the callout cache +.nem +.nextp +\*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 +\%smtp%\ transport) +.endp +.nem +.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 +spool and database names. For example, to dump the retry database: +.display asis +exim_dumpdb /var/spool/exim retry +.endd +Two lines of output are produced for each entry: +.display + T:mail.ref.example:192.168.242.242 146 77 Connection refused +31-Oct-1995 12:00:12 02-Nov-1995 12:21:39 02-Nov-1995 20:21:39 * +.endd +The first item on the first line is the key of the record. It starts with one +of the letters R, or T, depending on whether it refers to a routing or +transport retry. For a local delivery, the next part is the local address; for +a remote delivery it is the name of the remote host, followed by its failing IP +address (unless \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. + +The three times on the second line are the time of first failure, the time of +the last delivery attempt, and the computed time for the next attempt. The line +ends with an asterisk if the cutoff time for the last retry rule has been +exceeded. + +Each output line from \*exim@_dumpdb*\ for the \*wait-*\$it{xxx} databases +consists of a host name followed by a list of ids for messages that are or were +waiting to be delivered to that host. If there are a very large number for any +one host, continuation records, with a sequence number added to the host name, +may be seen. The data in these records is often out of date, because a message +may be routed to several alternative hosts, and Exim makes no effort to keep +cross-references. + +.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 +that are more than 30 days old. The cutoff date can be altered by means of the +\-t-\ option, which must be followed by a time. For example, to remove all +records older than a week from the retry database: +.display asis +exim_tidydb -t 7d /var/spool/exim retry +.endd +Both the \*wait-*\$it{xxx} and \*retry*\ databases contain items that involve +message ids. In the former these appear as data in records keyed by host -- +they were messages that were waiting for that host -- and in the latter they +are the keys for retry information for messages that have suffered certain +types of error. When \*exim@_tidydb*\ is run, a check is made to ensure that +message ids in database records are those of messages that are still on the +queue. Message ids for messages that no longer exist are removed from +\*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. + +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. + +.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 +getting round problems in a live system. It has no options, and its interface +is somewhat crude. On entry, it prompts for input with a right angle-bracket. A +key of a database record can then be entered, and the data for that record is +displayed. + +If `d' is typed at the next prompt, the entire record is deleted. For all +except the \*retry*\ database, that is the only operation that can be carried +out. For the \*retry*\ database, each field is output preceded by a number, and +data for individual fields can be changed by typing the field number followed +by new data, for example: +.display asis +> 4 951102:1000 +.endd +resets the time of the next delivery attempt. Time values are given as a +sequence of digit pairs for year, month, day, hour, and minute. Colons can be +used as optional separators. + + + +.section Mailbox maintenance (exim@_lock) +.rset SECTmailboxmaint "~~chapter.~~section" +.index mailbox||maintenance +.index \*exim@_lock*\ +.index locking mailboxes +The \*exim@_lock*\ utility locks a mailbox file using the same algorithm as +Exim. For a discussion of locking issues, see section ~~SECTopappend. +\*Exim@_lock*\ can be used to prevent any modification of a mailbox by Exim or +a user agent while investigating a problem. The utility requires the name of +the file as its first argument. If the locking is successful, the second +argument is run as a command (using C's \*system()*\ function); if there is no +second argument, the value of the SHELL environment variable is used; if this +is unset or empty, \(/bin/sh)\ is run. When the command finishes, the mailbox +is unlocked and the utility ends. The following options are available: + +.startoptions + +.option fcntl +Use \*fcntl()*\ locking on the open mailbox. + +.option flock +Use \*flock()*\ locking on the open mailbox, provided the operating system +supports it. + +.option interval +This must be followed by a number, which is a number of seconds; it sets the +interval to sleep between retries (default 3). + +.option lockfile +Create a lock file before opening the mailbox. + +.option mbx +Lock the mailbox using MBX rules. + +.option q +Suppress verification output. + +.option retries +This must be followed by a number; it sets the number of times to try to get +the lock (default 10). + +.option restore@_time +This option causes \exim@_lock\ to restore the modified and read times to the +locked file before exiting. This allows you to access a locked mailbox (for +example, to take a backup copy) without disturbing the times that the user +subsequently sees. + +.option timeout +This must be followed by a number, which is a number of seconds; it sets a +timeout to be used with a blocking \*fcntl()*\ lock. If it is not set (the +default), a non-blocking call is used. + +.option v +Generate verbose output. + +.endoptions + +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-\ +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-\. +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 +the device number and inode number of the mailbox file. When the locking is +released, if an exclusive lock can be obtained for the mailbox, the file in +\(/tmp)\ is deleted. + +The default output contains verification of the locking that takes place. The +\-v-\ option causes some additional information to be given. The \-q-\ option +suppresses all output except error messages. + +A command such as +.display asis +exim_lock /var/spool/mail/spqr +.endd +runs an interactive shell while the file is locked, whereas +.display +exim@_lock -q /var/spool/mail/spqr @<@<End +<<some commands>> +End +.endd +runs a specific non-interactive sequence of commands while the file is locked, +suppressing all verification output. A single command can be run by a command +such as +.display asis +exim_lock -q /var/spool/mail/spqr \ + "cp /var/spool/mail/spqr /some/where" +.endd +Note that if a command is supplied, it must be entirely contained within the +second argument -- hence the quotes. + + + +. +. +. +. +. ============================================================================ +.chapter The Exim monitor +.set runningfoot "monitor" +.rset CHAPeximon ~~chapter +.index monitor +.index Exim monitor +.index X-windows +.index \*eximon*\ +.index Local/eximon.conf +.index \(exim@_monitor/EDITME)\ +The Exim monitor is an application which displays in an X window information +about the state of Exim's queue and what Exim is doing. An admin user can +perform certain operations on messages from this GUI interface; however all +such facilities are also available from the command line, and indeed, the +monitor itself makes use of the command line to perform any actions requested. + + +.section Running the monitor +The monitor is started by running the script called \*eximon*\. This is a shell +script that sets up a number of environment variables, and then runs the +binary called \(eximon.bin)\. The default appearance of the monitor window can +be changed by editing the \(Local/eximon.conf)\ file created by editing +\(exim@_monitor/EDITME)\. Comments in that file describe what the various +parameters are for. + +The parameters that get built into the \*eximon*\ script can be overridden for a +particular invocation by setting up environment variables of the same names, +preceded by `$tt{EXIMON@_}'. For example, a shell command such as +.display asis +EXIMON_LOG_DEPTH=400 eximon +.endd +(in a Bourne-compatible shell) runs \*eximon*\ with an overriding setting of the +\\LOG@_DEPTH\\ parameter. If \\EXIMON@_LOG@_FILE@_PATH\\ is set in the +environment, it overrides the Exim log file configuration. This makes it +possible to have \*eximon*\ tailing log data that is written to syslog, provided +that MAIL.INFO syslog messages are routed to a file on the local host. + +X resources can be used to change the appearance of the window in the normal +way. For example, a resource setting of the form +.display asis +Eximon*background: gray94 +.endd +changes the colour of the background to light grey rather than white. The +stripcharts are drawn with both the data lines and the reference lines in +black. This means that the reference lines are not visible when on top of the +data. However, their colour can be changed by setting a resource called +`highlight' (an odd name, but that's what the Athena stripchart widget uses). +For example, if your X server is running Unix, you could set up lighter +reference lines in the stripcharts by obeying +.display asis +xrdb -merge <<End +Eximon*highlight: gray +End +.endd + +.index admin user +In order to see the contents of messages on the queue, and to operate on them, +\*eximon*\ must either be run as root or by an admin user. + +The monitor's window is divided into three parts. The first contains one or +more stripcharts and two action buttons, the second contains a `tail' of the +main log file, and the third is a display of the queue of messages awaiting +delivery, with two more action buttons. The following sections describe these +different parts of the display. + + + +.section The stripcharts +.index stripchart +The first stripchart is always a count of messages on the queue. Its name can +be configured by setting \\QUEUE@_STRIPCHART@_NAME\\ in the +\(Local/eximon.conf)\ file. The remaining stripcharts are defined in the +configuration script by regular expression matches on log file entries, making +it possible to display, for example, counts of messages delivered to certain +hosts or using certain transports. The supplied defaults display counts of +received and delivered messages, and of local and SMTP deliveries. The default +period between stripchart updates is one minute; this can be adjusted by a +parameter in the \(Local/eximon.conf)\ file. + +The stripchart displays rescale themselves automatically as the value they are +displaying changes. There are always 10 horizontal lines in each chart; the +title string indicates the value of each division when it is greater than one. +For example, `x2' means that each division represents a value of 2. + +It is also possible to have a stripchart which shows the percentage fullness of +a particular disk partition, which is useful when local deliveries are confined +to a single partition. +.index \statvfs\ function +This relies on the availability of the \*statvfs()*\ function or equivalent in +the operating system. Most, but not all versions of Unix that support Exim have +this. For this particular stripchart, the top of the chart always represents +100%, and the scale is given as `x10%'. This chart is configured by setting +\\SIZE@_STRIPCHART\\ and (optionally) \\SIZE@_STRIPCHART@_NAME\\ in the +\(Local/eximon.conf)\ file. + + + +.section Main action buttons +.index size||of monitor window +.index monitor window size +.index window size +Below the stripcharts there is an action button for quitting the monitor. Next +to this is another button marked `Size'. They are placed here so that shrinking +the window to its default minimum size leaves just the queue count stripchart +and these two buttons visible. Pressing the `Size' button causes the window to +expand to its maximum size, unless it is already at the maximum, in which case +it is reduced to its minimum. + +When expanding to the maximum, if the window cannot be fully seen where it +currently is, it is moved back to where it was the last time it was at full +size. When it is expanding from its minimum size, the old position is +remembered, and next time it is reduced to the minimum it is moved back there. + +The idea is that you can keep a reduced window just showing one or two +stripcharts at a convenient place on your screen, easily expand it to show +the full window when required, and just as easily put it back to what it was. +The idea is copied from what the \*twm*\ window manager does for its +\*f.fullzoom*\ action. The minimum size of the window can be changed by setting +the \\MIN@_HEIGHT\\ and \\MIN@_WIDTH\\ values in \(Local/eximon.conf)\. + +Normally, the monitor starts up with the window at its full size, but it can be +built so that it starts up with the window at its smallest size, by setting +\\START@_SMALL\\=yes in \(Local/eximon.conf)\. + + +.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. +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 +syslog, unless the syslog lines are routed to a local file whose name is passed +to \*eximon*\ via the \\EXIMON@_LOG@_FILE@_PATH\\ environment variable. + +The log sub-window has a scroll bar at its lefthand side which can be used to +move back to look at earlier text, and the up and down arrow keys also have a +scrolling effect. The amount of log that is kept depends on the setting of +\\LOG@_BUFFER\\ in \(Local/eximon.conf)\, which specifies the amount of memory +to use. When this is full, the earlier 50% of data is discarded -- this is much +more efficient than throwing it away line by line. The sub-window also has a +horizontal scroll bar for accessing the ends of long log lines. This is the +only means of horizontal scrolling; the right and left arrow keys are not +available. Text can be cut from this part of the window using the mouse in the +normal way. The size of this subwindow is controlled by parameters in the +configuration file \(Local/eximon.conf)\. + +Searches of the text in the log window can be carried out by means of the ^R +and ^S keystrokes, which default to a reverse and a forward search, +respectively. The search covers only the text that is displayed in the window. +It cannot go further back up the log. + +The point from which the search starts is indicated by a caret marker. This is +normally at the end of the text in the window, but can be positioned explicitly +by pointing and clicking with the left mouse button, and is moved automatically +by a successful search. If new text arrives in the window when it is scrolled +back, the caret remains where it is, but if the window is not scrolled back, +the caret is moved to the end of the new text. + +Pressing ^R or ^S pops up a window into which the search text can be typed. +There are buttons for selecting forward or reverse searching, for carrying out +the search, and for cancelling. If the `Search' button is pressed, the search +happens and the window remains so that further searches can be done. If the +`Return' key is pressed, a single search is done and the window is closed. If +^C is typed the search is cancelled. + +The searching facility is implemented using the facilities of the Athena text +widget. By default this pops up a window containing both `search' and `replace' +options. In order to suppress the unwanted `replace' portion for eximon, a +modified version of the \TextPop\ widget is distributed with Exim. However, the +linkers in BSDI and HP-UX seem unable to handle an externally provided version +of \TextPop\ when the remaining parts of the text widget come from the standard +libraries. The compile-time option \\EXIMON@_TEXTPOP\\ can be unset to cut out +the modified \TextPop\, making it possible to build Eximon on these systems, at +the expense of having unwanted items in the search popup window. + + +.section The queue display +.index queue||display in monitor +The bottom section of the monitor window contains a list of all messages that +are on the queue, which includes those currently being received or delivered, +as well as those awaiting delivery. The size of this subwindow is controlled by +parameters in the configuration file \(Local/eximon.conf)\, and the frequency +at which it is updated is controlled by another parameter in the same file -- +the default is 5 minutes, since queue scans can be quite expensive. However, +there is an `Update' action button just above the display which can be used to +force an update of the queue display at any time. + +When a host is down for some time, a lot of pending mail can build up for it, +and this can make it hard to deal with other messages on the queue. To help +with this situation there is a button next to `Update' called `Hide'. If +pressed, a dialogue box called `Hide addresses ending with' is put up. If you +type anything in here and press `Return', the text is added to a chain of such +texts, and if every undelivered address in a message matches at least one +of the texts, the message is not displayed. + +If there is an address that does not match any of the texts, all the addresses +are displayed as normal. The matching happens on the ends of addresses so, for +example, \*cam.ac.uk*\ specifies all addresses in Cambridge, while +\*xxx@@foo.com.example*\ specifies just one specific address. When any hiding +has been set up, a button called `Unhide' is displayed. If pressed, it cancels +all hiding. Also, to ensure that hidden messages do not get forgotten, a hide +request is automatically cancelled after one hour. + +While the dialogue box is displayed, you can't press any buttons or do anything +else to the monitor window. For this reason, if you want to cut text from the +queue display to use in the dialogue box, you have to do the cutting before +pressing the `Hide' button. + +The queue display contains, for each unhidden queued message, the length of +time it has been on the queue, the size of the message, the message id, the +message sender, and the first undelivered recipient, all on one line. If it is +a bounce message, the sender is shown as `<>'. If there is more than one +recipient to which the message has not yet been delivered, subsequent ones are +listed on additional lines, up to a maximum configured number, following which +an ellipsis is displayed. Recipients that have already received the message are +not shown. +.index frozen messages||display +If a message is frozen, an asterisk is displayed at the left-hand side. + +The queue display has a vertical scroll bar, and can also be scrolled by means +of the arrow keys. Text can be cut from it using the mouse in the normal way. +The text searching facilities, as described above for the log window, are also +available, but the caret is always moved to the end of the text when the queue +display is updated. + + +.section The queue menu +.index queue||menu in monitor +If the \shift\ key is held down and the left button is clicked when the mouse +pointer is over the text for any message, an action menu pops up, and the first +line of the queue display for the message is highlighted. This does not affect +any selected text. + +If you want to use some other event for popping up the menu, you can set the +\\MENU@_EVENT\\ parameter in \(Local/eximon.conf)\ to change the default, or +set \\EXIMON@_MENU@_EVENT\\ in the environment before starting the monitor. The +value set in this parameter is a standard X event description. For example, to +run eximon using \ctrl\ rather than \shift\ you could use +.display asis +EXIMON_MENU_EVENT='Ctrl<Btn1Down>' eximon +.endd +The title of the menu is the message id, and it contains entries which act as +follows: +.numberpars $. +\*message log*\: The contents of the message log for the message are displayed in +a new text window. +.nextp +\*headers*\: Information from the spool file that contains the envelope +information and headers is displayed in a new text window. See chapter +~~CHAPspool for a description of the format of spool files. +.nextp +\*body*\: The contents of the spool file containing the body of the message are +displayed in a new text window. There is a default limit of 20,000 bytes to the +amount of data displayed. This can be changed by setting the \\BODY@_MAX\\ +option at compile time, or the \\EXIMON@_BODY@_MAX\\ option at run time. +.nextp +\*deliver message*\: A call to Exim is made using the \-M-\ option to request +delivery of the message. This causes an automatic thaw if the message is +frozen. The \-v-\ option is also set, and the output from Exim is displayed in +a new text window. The delivery is run in a separate process, to avoid holding +up the monitor while the delivery proceeds. +.nextp +\*freeze message*\: A call to Exim is made using the \-Mf-\ option to request +that the message be frozen. +.nextp +.index thawing messages +.index unfreezing messages +.index frozen messages||thawing +\*thaw message*\: A call to Exim is made using the \-Mt-\ option to request that +the message be thawed. +.nextp +.index delivery||forcing failure +\*give up on msg*\: A call to Exim is made using the \-Mg-\ option to request +that Exim gives up trying to deliver the message. A bounce message is generated +for any remaining undelivered addresses. +.nextp +\*remove message*\: A call to Exim is made using the \-Mrm-\ option to request +that the message be deleted from the system without generating a bounce +message. +.nextp +\*add recipient*\: A dialog box is displayed into which a recipient address can +be typed. If the address is not qualified and the \\QUALIFY@_DOMAIN\\ parameter +is set in \(Local/eximon.conf)\, the address is qualified with that domain. +Otherwise it must be entered as a fully qualified address. Pressing \\RETURN\\ +causes a call to Exim to be made using the \-Mar-\ option to request that an +additional recipient be added to the message, unless the entry box is empty, in +which case no action is taken. +.nextp +\*mark delivered*\: A dialog box is displayed into which a recipient address can +be typed. If the address is not qualified and the \\QUALIFY@_DOMAIN\\ parameter +is set in \(Local/eximon.conf)\, the address is qualified with that domain. +Otherwise it must be entered as a fully qualified address. Pressing \\RETURN\\ +causes a call to Exim to be made using the \-Mmd-\ option to mark the given +recipient address as already delivered, unless the entry box is empty, in which +case no action is taken. +.nextp +\*mark all delivered*\: A call to Exim is made using the \-Mmad-\ option to mark +all recipient addresses as already delivered. +.nextp +\*edit sender*\: A dialog box is displayed initialized with the current sender's +address. Pressing \\RETURN\\ causes a call to Exim to be made using the \-Mes-\ +option to replace the sender address, unless the entry box is empty, in which +case no action is taken. If you want to set an empty sender (as in bounce +messages), you must specify it as `<>'. Otherwise, if the address is not +qualified and the \\QUALIFY@_DOMAIN\\ parameter is set in +\(Local/eximon.conf)\, the address is qualified with that domain. +.endp +When a delivery is forced, a window showing the \-v-\ output is displayed. In +other cases when a call to Exim is made, if there is any output from Exim (in +particular, if the command fails) a window containing the command and the +output is displayed. Otherwise, the results of the action are normally apparent +from the log and queue displays. However, if you set \\ACTION@_OUTPUT\\=yes in +\(Local/eximon.conf)\, a window showing the Exim command is always opened, even +if no output is generated. + +The queue display is automatically updated for actions such as freezing and +thawing, unless \\ACTION@_QUEUE@_UPDATE\\=no has been set in +\(Local/eximon.conf)\. In this case the `Update' button has to be used to force +an update of the display after one of these actions. + +In any text window that is displayed as result of a menu action, the normal +cut-and-paste facility is available, and searching can be carried out using ^R +and ^S, as described above for the log tail window. + + + + + + +. +. +. +. +. ============================================================================ +.chapter Security considerations +.set runningfoot "security" +.rset CHAPsecurity ~~chapter +.index security +This chapter discusses a number of issues concerned with security, some of +which are also covered in other parts of this manual. + +For reasons that this author does not understand, some people have promoted +Exim as a `particularly secure' mailer. Perhaps it is because of the existence +of this chapter in the documentation. However, the intent of the chapter is +simply to describe the way Exim works in relation to certain security concerns, +not to make any specific claims about the effectiveness of its security as +compared with other MTAs. + +What follows is a description of the way Exim is supposed to be. Best efforts +have been made to try to ensure that the code agrees with the theory, but an +absence of bugs can never be guaranteed. Any that are reported will get fixed +as soon as possible. + +.section Building a more `hardened' Exim +.index security||build-time features +There are a number of build-time options that can be set in \(Local/Makefile)\ +to create Exim binaries that are `harder' to attack, in particular by a rogue +Exim administrator who does not have the root password, or by someone who has +penetrated the Exim (but not the root) account. These options are as follows: +.numberpars $. +\\ALT@_CONFIG@_PREFIX\\ can be set to a string that is required to match the +start of any file names used with the \-C-\ option. When it is set, these file +names are also not allowed to 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\. + +If the permitted configuration files are confined to a directory to +which only root has access, this guards against someone who has broken +into the Exim account from running a privileged Exim with an arbitrary +configuration file, and using it to break into other accounts. +.nextp +If \\ALT@_CONFIG@_ROOT@_ONLY\\ is defined, root privilege is retained for \-C-\ +and \-D-\ only if the caller of Exim is root. Without it, the Exim user may +also use \-C-\ and \-D-\ and retain privilege. Setting this option 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. +\\ALT@_CONFIG@_ROOT@_ONLY\\ is not set by default. +.nextp +If \\DISABLE@_D@_OPTION\\ is defined, the use of the \-D-\ command line option +is disabled. +.nextp +\\FIXED@_NEVER@_USERS\\ can be set to a colon-separated list of users that are +never to be used for any deliveries. This is like the \never@_users\ runtime +option, but it cannot be overridden; the runtime option adds additional users +to the list. The default setting is `root'; this prevents a non-root user who +is permitted to modify the runtime file from using Exim as a way to get root. +.endp + + +.section Root privilege +.index setuid +.index root privilege +The Exim binary is normally setuid to root, which means that it gains root +privilege (runs as root) when it starts execution. In some special cases (for +example, when the daemon is not in use and there are no local deliveries), it +may be possible to run Exim setuid to some user other than root. This is +discussed in the next section. However, in most installations, root privilege +is required for two things: +.numberpars $. +To set up a socket connected to the standard SMTP port (25) when initialising +the listening daemon. If Exim is run from \*inetd*\, this privileged action is +not required. +.nextp +To be able to change uid and gid in order to read users' \(.forward)\ files and +perform local deliveries as the receiving user or as specified in the +configuration. +.endp +It is not necessary to be root to do any of the other things Exim does, such as +receiving messages and delivering them externally over SMTP, and it is +obviously more secure if Exim does not run as root except when necessary. +For this reason, a user and group for Exim to use must be defined in +\(Local/Makefile)\. These are known as `the Exim user' and `the Exim group'. +Their values can be changed by the run time configuration, though this is not +recommended. Often a user called \*exim*\ is used, but some sites use \*mail*\ +or another user name altogether. + +Exim uses \*setuid()*\ whenever it gives up root privilege. This is a permanent +abdication; the process cannot regain root afterwards. Prior to release 4.00, +\*seteuid()*\ was used in some circumstances, but this is no longer the case. + +After a new Exim process has interpreted its command line options, it changes +uid and gid in the following cases: +.numberpars $. +.index \-C-\ option +.index \-D-\ option +If the \-C-\ option is used to specify an alternate configuration file, or if +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 +\\DISABLE@_D@_OPTION\\ is set, the \-D-\ option may not be used at all. +.nextp +.index \-be-\ option +.index \-bf-\ option +.index \-bF-\ option +If the expansion test option (\-be-\) or one of the filter testing options +(\-bf-\ or \-bF-\) are used, the uid and gid are changed to those of the +calling process. +.nextp +If the process is not a daemon process or a queue runner process or a delivery +process or a process for testing address routing (started with \-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 +.index \-bv-\ option +.index \-bh-\ option +(the \-bv-\ option) and testing incoming message policy controls (the \-bh-\ +option). +.nextp +For a daemon, queue runner, delivery, or address testing process, the uid +remains as root at this stage, but the gid is changed to the Exim group. +.endp +The processes that initially retain root privilege behave as follows: +.numberpars $. +A daemon process changes the gid to the Exim group and the uid to the Exim user +after setting up one or more listening sockets. The \*initgroups()*\ function +is called, so that if the Exim user is in any additional groups, they will be +used during message reception. +.nextp +A queue runner process retains root privilege throughout its execution. Its job +is to fork a controlled sequence of delivery processes. +.nextp +A delivery process retains root privilege throughout most of its execution, +but any actual deliveries (that is, the transports themselves) are run in +subprocesses which always change to a non-root uid and gid. For local +deliveries this is typically the uid and gid of the owner of the mailbox; for +remote deliveries, the Exim uid and gid are used. Once all the delivery +subprocesses have been run, a delivery process changes to the Exim uid and gid +while doing post-delivery tidying up such as updating the retry database and +generating bounce and warning messages. + +While the recipient addresses in a message are being routed, the delivery +process runs as root. However, if a user's filter file has to be processed, +this is done in a subprocess that runs under the individual user's uid and +gid. A system filter is run as root unless \system@_filter@_user\ is set. +.nextp +A process that is testing addresses (the \-bt-\ option) runs as root so that +the routing is done in the same environment as a message delivery. +.endp + + +.section Running Exim without privilege +.index privilege, running without +.index unprivileged running +.index root privilege||running without +Some installations like to run Exim in an unprivileged state for more of its +operation, for added security. Support for this mode of operation is provided +by the global option \deliver@_drop@_privilege\. When this is set, the uid and +gid are changed to the Exim user and group at the start of a delivery process +(and also queue runner and address testing processes). This means that address +routing is no longer run as root, and the deliveries themselves cannot change +to any other uid. + +Leaving the binary setuid to root, but setting \deliver@_drop@_privilege\ means +that the daemon can still be started in the usual way, and it can respond +correctly to SIGHUP because the re-invocation regains root privilege. + +An alternative approach is to make Exim setuid to the Exim user and also setgid +to the Exim group. +If you do this, the daemon must be started from a root process. (Calling +Exim from a root process makes it behave in the way it does when it is setuid +root.) However, the daemon cannot restart itself after a SIGHUP signal because +it cannot regain privilege. + +It is still useful to set \deliver@_drop@_privilege\ in this case, because it +stops Exim from trying to re-invoke itself to do a delivery after a message has +been received. Such a re-invocation is a waste of resources because it has no +effect. + +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: + +In this style of operation, Exim is running with the real uid and gid set to +those of the calling process, and the effective uid/gid set to Exim's values. +Ideally, any association with the calling process' uid/gid should be dropped, +that is, the real uid/gid should be reset to the effective values so as to +discard any privileges that the caller may have. While some operating systems +have a function that permits this action for a non-root effective uid, quite a +number of them do not. Because of this lack of standardization, Exim does not +address this problem at this time. + +For this reason, the recommended approach for `mostly unprivileged' running is +to keep the Exim binary setuid to root, and to set \deliver@_drop@_privilege\. +This also has the advantage of allowing a daemon to be used in the most +straightforward way. + +If you configure Exim not to run delivery processes as root, there are a +number of restrictions on what you can do: +.numberpars $. +You can deliver only as the Exim user/group. You should explicitly use the +\user\ and \group\ options to override routers or local transports that +normally deliver as the recipient. This makes sure that configurations that +work in this mode function the same way in normal mode. Any implicit or +explicit specification of another user causes an error. +.nextp +Use of \(.forward)\ files is severely restricted, such that it is usually +not worthwhile to include them in the configuration. +.nextp +Users who wish to use \(.forward)\ would have to make their home directory and +the file itself accessible to the Exim user. Pipe and append-to-file entries, +and their equivalents in Exim filters, cannot be used. While they could be +enabled in the Exim user's name, that would be insecure and not very useful. +.nextp +Unless the local user mailboxes are all owned by the Exim user (possible in +some POP3 or IMAP-only environments): +.numberpars $*$ +They must be owned by the Exim group and be writable by that group. This +implies you must set \mode\ in the appendfile configuration, as well as the +mode of the mailbox files themselves. +.nextp +You must set \no@_check@_owner\, since most or all of the files will not be +owned by the Exim user. +.nextp +You must set \file@_must@_exist\, because Exim cannot set the owner correctly +on a newly created mailbox when unprivileged. This also implies that new +mailboxes need to be created manually. +.endp +.endp +These restrictions severely restrict what can be done in local deliveries. +However, there are no restrictions on remote deliveries. If you are running a +gateway host that does no local deliveries, setting \deliver@_drop@_privilege\ +gives more security at essentially no cost. + + +.section Delivering to local files +Full details of the checks applied by \%appendfile%\ before it writes to a file +are given in chapter ~~CHAPappendfile. + + +.section IPv4 source routing +.index source routing||in IP packets +.index IP source routing +Many operating systems suppress IP source-routed packets in the kernel, but +some cannot be made to do this, so Exim does its own check. It logs incoming +IPv4 source-routed TCP calls, and then drops them. Things are all different in +IPv6. No special checking is currently done. + + +.section The VRFY, EXPN, and ETRN commands in SMTP +Support for these SMTP commands is disabled by default. If required, they can +be enabled by defining suitable ACLs. + + + +.section Privileged users +.index trusted user +.index admin user +.index privileged user +.index user||trusted +.index user||admin +Exim recognises two sets of users with special privileges. Trusted users are +able to submit new messages to Exim locally, but supply their own sender +addresses and information about a sending host. For other users submitting +local messages, Exim sets up the sender address from the uid, and doesn't +permit a remote host to be specified. + +.index \-f-\ option +However, an untrusted user is permitted to use the \-f-\ command line option in +the special form \-f @<@>-\ to indicate that a delivery failure for the message +should not cause an error report. This affects the message's envelope, but it +does not affect the ::Sender:: header. Untrusted users may also be permitted to +use specific forms of address with the \-f-\ option by setting the +\untrusted@_set@_sender\ option. + +Trusted users are used to run processes that receive mail messages from some +other mail domain and pass them on to Exim for delivery either locally, or over +the Internet. Exim trusts a caller that is running as root, as the Exim user, +as any user listed in the \trusted@_users\ configuration option, or under any +group listed in the \trusted@_groups\ option. + +Admin users are permitted to do things to the messages on Exim's queue. They +can freeze or thaw messages, cause them to be returned to their senders, remove +them entirely, or modify them in various ways. In addition, admin users can run +the Exim monitor and see all the information it is capable of providing, which +includes the contents of files on the spool. + +.index \-M-\ option +.index \-q-\ option +By default, the use of the \-M-\ and \-q-\ options to cause Exim to attempt +delivery of messages on its queue is restricted to admin users. This +restriction can be relaxed by setting the \no@_prod@_requires@_admin\ option. +Similarly, the use of \-bp-\ (and its variants) to list the contents of the +queue is also restricted to admin users. This restriction can be relaxed by +setting \no@_queue@_list@_requires@_admin\. + +Exim recognises an admin user if the calling process is running as root or as +the Exim user or if any of the groups associated with the calling process is +the Exim group. It is not necessary actually to be running under the Exim +group. However, if admin users who are not root or the Exim user are to access +the contents of files on the spool via the Exim monitor (which runs +unprivileged), Exim must be built to allow group read access to its spool +files. + + +.section Spool files +.index spool directory||files +Exim's spool directory and everything it contains is owned by the Exim user and +set to the Exim group. The mode for spool files is defined in the +\(Local/Makefile)\ configuration file, and defaults to 0640. This means that +any user who is a member of the Exim group can access these files. + + +.section Use of argv[0] +Exim examines the last component of \argv[0]\, and if it matches one of a set +of specific strings, Exim assumes certain options. For example, calling Exim +with the last component of \argv[0]\ set to `rsmtp' is exactly equivalent to +calling it with the option \-bS-\. There are no security implications in this. + + +.section Use of %f formatting +The only use made of `%f' by Exim is in formatting load average values. These +are actually stored in integer variables as 1000 times the load average. +Consequently, their range is limited and so therefore is the length of the +converted output. + + +.section Embedded Exim path +Exim uses its own path name, which is embedded in the code, only when it needs +to re-exec in order to regain root privilege. Therefore, it is not root when it +does so. If some bug allowed the path to get overwritten, it would lead to an +arbitrary program's being run as exim, not as root. + + +.section Use of sprintf() +.index \*sprintf()*\ +A large number of occurrences of `sprintf' in the code are actually calls to +\*string@_sprintf()*\, a function that returns the result in malloc'd store. +The intermediate formatting is done into a large fixed buffer by a function +that runs through the format string itself, and checks the length of each +conversion before performing it, thus preventing buffer overruns. + +The remaining uses of \*sprintf()*\ happen in controlled circumstances where +the output buffer is known to be sufficiently long to contain the converted +string. + + +.section Use of debug@_printf() and log@_write() +Arbitrary strings are passed to both these functions, but they do their +formatting by calling the function \*string@_vformat()*\, which runs through +the format string itself, and checks the length of each conversion. + + +.section Use of strcat() and strcpy() +These are used only in cases where the output buffer is known to be large +enough to hold the result. + + + + +. +. +. +. +. ============================================================================ +.chapter Format of spool files +.set runningfoot "spool file format" +.rset CHAPspool ~~chapter +.index format||spool files +.index spool directory||format of files +.index spool||files, format of +.index spool||files, editing +A message on Exim's queue consists of two files, whose names are the message id +followed by -D and -H, respectively. The data portion of the message is kept in +the -D file on its own. The message's envelope, status, and headers are all +kept in the -H file, whose format is described in this chapter. Each of these +two files contains the final component of its own name as its first line. This +is insurance against disk crashes where the directory is lost but the files +themselves are recoverable. + +.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: +.numberpars $. +You must use the \*exim@_lock*\ utility to ensure that Exim does not try to +deliver the message while you are fiddling with it. The lock is implemented +by opening the -D file and taking out a write lock on it. If you update the +file in place, the lock will be retained. If you write a new file and rename +it, the lock will be lost at the instant of rename. +.nextp +If you change the number of lines in the file, the value of +\$body@_linecount$\, which is stored in the -H file, will be incorrect. +.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 +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 +files, used to record addresses to which the message has been delivered during +the course of a delivery run. At the end of the run, the -H file is updated, +and the -J file is deleted. + +.section Format of the -H file +.index uid (user id)||in spool file +.index gid (group id)||in spool file +The second line of the -H file contains the login name for the uid of the +process that called Exim to read the message, followed by the numerical uid and +gid. For a locally generated message, this is normally the user who sent the +message. For a message received over TCP/IP, it is normally the Exim user. + +The third line of the file contains the address of the message's sender as +transmitted in the envelope, contained in angle brackets. The sender address is +empty for bounce messages. For incoming SMTP mail, the sender address is given +in the \\MAIL\\ command. For locally generated mail, the sender address is +created by Exim from the login name of the current user and the configured +\qualify@_domain\. However, this can be overridden by the \-f-\ option or a +leading `From' line if the caller is trusted, or if the supplied address is +`@<@>' or an address that matches \untrusted@_set@_senders\. + +The fourth line contains two numbers. The first is the time that the message +was received, in the conventional Unix form -- the number of seconds since the +start of the epoch. The second number is a count of the number of messages +warning of delayed delivery that have been sent to the sender. + +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 +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 +\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 +\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$\ +variable. +.nextp +\-auth@_sender <<address>>-\: The address of an authenticated sender -- the +value of the \$authenticated@_sender$\ variable. +.nextp +\-body@_linecount <<number>>-\: This records the number of lines in the body of +the message, and is always present. +.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 +.index frozen messages||spool data +\-frozen <<time>>-\: The message is frozen, and the freezing happened at +<<time>>. +.nextp +\-helo@_name <<text>>-\: This records the host name as specified by a remote +host in a \\HELO\\ or \\EHLO\\ command. +.nextp +\-host@_address <<address>>.<<port>>-\: This records the IP address of the host +from which the message was received and the remote port number that was used. +It is omitted for locally generated messages. +.nextp +\-host@_auth <<text>>-\: If the message was received on an authenticated SMTP +connection, this records the name of the authenticator -- the value of the +\$sender@_host@_authenticated$\ variable. +.nextp +\-host@_lookup@_failed-\: This is present if an attempt to look up the sending +host's name from its IP address failed. It corresponds to the +\$host@_lookup@_failed$\ variable. +.nextp +.index DNS||reverse lookup +.index reverse DNS lookup +\-host@_name <<text>>-\: This records the name of the remote host from which +the message was received, if the host name was looked up from the IP address +when the message was being received. It is not present if no reverse lookup was +done. +.nextp +\-ident <<text>>-\: For locally submitted messages, this records the login of +the originating user, unless it was a trusted user and the \-oMt-\ option was +used to specify an ident value. For messages received over TCP/IP, this records +the ident string supplied by the remote host, if any. +.nextp +\-interface@_address <<address>>.<<port>>-\: This records the IP address of the +local interface and the port number through which a message was received from a +remote host. It is omitted for locally generated messages. +.nextp +\-local-\: The message is from a local sender. +.nextp +\-localerror-\: The message is a locally-generated bounce message. +.nextp +\-local@_scan <<string>>-\: This records the data string that was +returned by the \*local@_scan()*\ function when the message was received -- the +value of the \$local@_scan@_data$\ variable. It is omitted if no data was +returned. +.nextp +\-manual@_thaw-\: The message was frozen but has been thawed manually, that is, +by an explicit Exim command rather than via the auto-thaw process. +.nextp +\-N-\: A testing delivery process was started using the \-N-\ option to +suppress any actual deliveries, but delivery was deferred. At any further +delivery attempts, \-N-\ is assumed. +.nextp +\-received@_protocol-\: This records the value of the \$received@_protocol$\ +variable, which contains the name of the protocol by which the message was +received. +.nextp +\-sender@_set@_untrusted-\: The envelope sender of this message was set by an +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 +that sent this message, and the certificate was verified by the server. +.nextp +\-tls@_cipher <<cipher name>>-\: When the message was received over an +encrypted connection, this records the name of the cipher suite that was used. +.nextp +\-tls@_peerdn <<peer DN>>-\: When the message was received over an encrypted +connection, and a certificate was received from the client, this records the +Distinguished Name from that certificate. +.endp + +Following the options there is a list of those addresses to which the message +is not to be delivered. This set of addresses is initialized from the command +line when the \-t-\ option is used and \extract__addresses__remove__arguments\ +is set; otherwise it starts out empty. Whenever a successful delivery is made, +the address is added to this set. The addresses are kept internally as a +balanced binary tree, and it is a representation of that tree which is written +to the spool file. If an address is expanded via an alias or forward file, the +original address is added to the tree when deliveries to all its child +addresses are complete. + +If the tree is empty, there is a single line in the spool file containing just +the text `XX'. Otherwise, each line consists of two letters, which are either Y +or N, followed by an address. The address is the value for the node of the +tree, and the letters indicate whether the node has a left branch and/or a +right branch attached to it, respectively. If branches exist, they immediately +follow. Here is an example of a three-node tree: +.display asis +YY darcy@austen.fict.example +NN alice@wonderland.fict.example +NN editor@thesaurus.ref.example +.endd +After the non-recipients tree, there is a list of the message's recipients. +This is a simple list, preceded by a count. It includes all the original +recipients of the message, including those to whom the message has already been +delivered. In the simplest case, the list contains one address per line. For +example: +.display asis +4 +editor@thesaurus.ref.example +darcy@austen.fict.example +rdo@foundation +alice@wonderland.fict.example +.endd +However, when a child address has been added to the top-level addresses as a +result of the use of the \one@_time\ option on a \%redirect%\ router, each line +is of the following form: +.display +<<top-level address>> <<errors@_to address>> <<length>>,<<parent number>>@#<<flag bits>> +.endd +The 01 flag bit indicates the presence of the three other fields that follow +the top-level address. Other bits may be used in future to support additional +fields. The <<parent number>> is the offset in the recipients list of the +original parent of the `one time' address. The first two fields are the +envelope sender that is associated with this address and its length. If the +length is zero, there is no special envelope sender (there are then two space +characters in the line). A non-empty field can arise from a \%redirect%\ router +that has an \errors@_to\ setting. + + +A blank line separates the envelope and status information from the headers +which follow. A header may occupy several lines of the file, and to save effort +when reading it in, each header is preceded by a number and an identifying +character. The number is the number of characters in the header, including any +embedded newlines and the terminating newline. The character is one of the +following: +.display +.tabs 9 +<<blank>> $t $rm{header in which Exim has no special interest} +#B $t $rm{::Bcc:: header} +#C $t $rm{::Cc:: header} +#F $t $rm{::From:: header} +#I $t $rm{::Message-id:: header} +#P $t $rm{::Received:: header -- P for `postmark'} +#R $t $rm{::Reply-To:: header} +#S $t $rm{::Sender:: header} +#T $t $rm{::To:: header} +#* $t $rm{replaced or deleted header} +.endd +Deleted or replaced (rewritten) headers remain in the spool file for debugging +purposes. They are not transmitted when the message is delivered. Here is a +typical set of headers: +.display asis +111P Received: by hobbit.fict.example with local (Exim 4.00) + id 14y9EI-00026G-00; Fri, 11 May 2001 10:28:59 +0100 +049 Message-Id: <E14y9EI-00026G-00@hobbit.fict.example> +038* X-rewrote-sender: bb@hobbit.fict.example +042* From: Bilbo Baggins <bb@hobbit.fict.example> +049F From: Bilbo Baggins <B.Baggins@hobbit.fict.example> +099* To: alice@wonderland.fict.example, rdo@foundation, + darcy@austen.fict.example, editor@thesaurus.ref.example +109T To: alice@wonderland.fict.example, rdo@foundation.fict.example, + darcy@austen.fict.example, editor@thesaurus.ref.example +038 Date: Fri, 11 May 2001 10:28:59 +0100 +.endd +The asterisked headers indicate that the envelope sender, ::From:: header, and +::To:: header have been rewritten, the last one because routing expanded the +unqualified domain \*foundation*\. + +. +. +. +. +. ============================================================================ +.chapter Adding new drivers or lookup types +.set runningfoot "adding drivers" +.index adding drivers +.index new drivers, adding +.index drivers||adding new +The following actions have to be taken in order to add a new router, transport, +authenticator, or lookup type to Exim: +.numberpars +Choose a name for the driver or lookup type that does not conflict with any +existing name; I will use `newdriver' in what follows. +.nextp +Add to \(src/EDITME)\ the line +.display +<<type>>@_NEWDRIVER=yes +.endd +where <<type>> is \\ROUTER\\, \\TRANSPORT\\, \\AUTH\\, or \\LOOKUP\\. If the +code is not to be included in the binary by default, comment this line out. You +should also add any relevant comments about the driver or lookup type. +.nextp +Add to \(src/config.h.defaults)\ the line +.display +@#define <<type>>@_NEWDRIVER +.endd +.nextp +Edit \(src/drtables.c)\, adding conditional code to pull in the private header +and create a table entry as is done for all the other drivers and lookup types. +.nextp +Edit \(Makefile)\ in the appropriate sub-directory (\(src/routers)\, +\(src/transports)\, \(src/auths)\, or \(src/lookups)\); add a line for the new +driver or lookup type and add it to the definition of OBJ. +.nextp +Create \(newdriver.h)\ and \(newdriver.c)\ in the appropriate sub-directory of +\(src)\. +.nextp +Edit \(scripts/MakeLinks)\ and add commands to link the \(.h)\ and \(.c)\ files +as for other drivers and lookups. +.endp +Then all you need to do is write the code! A good way to start is to make a +proforma by copying an existing module of the same type, globally changing all +occurrences of the name, and cutting out most of the code. Note that any +options you create must be listed in alphabetical order, because the tables are +searched using a binary chop procedure. + +There is a \(README)\ file in each of the sub-directories of \(src)\ describing +the interface that is expected. + +. +. +. +. +. ============================================================================ +. Fudge for the index page number. We want it to be on a right-hand page. +. +.set indexpage ~~sys.pagenumber + 1 +.if even ~~indexpage +.set indexpage ~~indexpage + 1 +.fi +.if ~~sgcal +.%index Index$e~~indexpage-- +.fi +. +. +. End of Exim specification |