Exim FAQ

This is the FAQ for the Exim Mail Transfer Agent. 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 welcome.

This version of the FAQ applies to Exim 3.10 and later releases. The syntax of some of the options was altered and tidied up at release 3.00. Some of the examples quoted here will not work with earlier releases.

References of the form Cnnn and Fnnn are to the sample configuration and filter files that can be found in the separately distributed directory called config.samples. The primary location is

   ftp://ftp.csx.cam.ac.uk/pub/software/email/exim/config.samples.tar.gz

There are brief descriptions of these files at the end of this document.

The FAQ is divided into the following sections: Debugging, Building exim, Mailbox locking, Routing, Directing, Delivery, UUCP, Performance, Policy controls, Majordomo, Rewriting, Headers, Fetchmail, Perl, Dial-up, Millennium, Miscellaneous, HP-UX, BSDI, IRIX, Linux, Sun systems, Cookbook, and List of sample configurations.

Philip Hazel <ph10@cus.cam.ac.uk>
Last updated: 15-December-1999



0. DEBUGGING 1. BUILDING EXIM 2. MAILBOX LOCKING 3. ROUTING 4. DIRECTING 5. DELIVERY 6. UUCP 7. PERFORMANCE 8. POLICY CONTROLS 9. MAJORDOMO 10. REWRITING 11. HEADERS 12. FETCHMAIL 13. PERL 14. DIAL-UP 20. MILLENNIUM 50. MISCELLANEOUS 93. HP-UX 94. BSDI 95. IRIX 96. LINUX 97. SUN SYSTEMS 98. COOKBOOK 99. LIST OF SAMPLE CONFIGURATIONS

0. 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 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. If there is a core file (in Exim's spool directory), see if you can get any information from it.

One thing that has caused crashes in the past has been incorrectly installed DB libraries. In particular, if you are running any version of Berkeley db, it is best to set USE_DB=yes in Local/Makefile before building Exim. This then avoids the use of the "ndbm compatibility interface" via the ndbm.h include file, which has been found to be incorrect on some systems. If you have already built Exim, you can just edit Local/Makefile and run make again to rebuild. Before restarting Exim, delete any existing database files in the spool/db directory.

Q0002: Exim is not working. What is wrong?

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 -d option, to cause Exim to output debugging information. For example:

            exim -d -M 0z6CXU-0005RR-00

On its own, -d produces a small amount of information. Following it with a number increases the amount given: -d9 gives the maximum amount of general information; -d10 gives in addition details of the interpretation of filter files, and -d11 or higher also turns on the debugging option for DNS lookups. The output is written to the standard error stream.

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 -d2 -bt z6abc

will show you how it would handle the local part "z6abc". Increase the debug level to -d9 for more information.

Q0003: What does the error "Child process of address_pipe transport returned 69 from command xxx" mean?

A0003: The most common meaning of exit code 69 is "unavailable", and this often means that when Exim tried to exec the command xxx, it failed. One cause of this might be incorrect permissions on the file containing the command.

Q0004: My virtual domain setup isn't working. How can I debug it?

A0004: You can use an exim command with -d (or -d2, -d3 ... -d9) 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 -d2 -bt localpart@virtualhost

This will show you which directors 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 director (or router) to get Exim to output the expanded string values as it goes along.

Q0005: Why is Exim giving "421 Unexpected log failure, please try later" when receiving an SMTP message with a large number of recipients?

A0005: You are verifying recipients, and your configuration is one that does a different lookup of some sort for each recipient. Exim keeps lookup files open, in case there are several lookups in the same file. Versions of Exim prior to 2.10 did not limit the number of open files used for this purpose, and your operating system's maximum per process has been reached. Exim is trying to log the failure to open a file, but cannot open the log file, for the same reason. If upgrading Exim is not immediately possible, you might be able to increase your operating system's maximum number of open files per process.

Q0006: Why is Exim not rejecting incoming messages addressed to non-existent users at SMTP time?

A0006: Have you remembered to set receiver_verify? It is not the default.

Q0007: I've put an entry for *.my.domain in a DBM lookup file, but it isn't getting recognized.

A0007: You need to request "partial matching" by setting the search type to "partial-dbm" in order for this to work.

Q0008: 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} ...

A0008: As no sender address will ever be *@domain.com this will indeed have no effect as it stands. You need to tell Exim if 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".

Q0009: Is there a way to print recognized local domains?

A0009: If you run "exim -bP local_domains" it will output the string that is set, but it won't print the contents of any files that are referenced.

Q0010: If I run "./exim -d9 -bt user@domain" all seems well, but when I send a message from my User Agent, it does not arrive at its destination.

A0010: Try sending a message directly to Exim by typing this:

         exim -d9 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_arguments option, to see with which arguments the UA is calling Exim.

Q0011: I am getting this message in mainlog every so often: "no immediate delivery: too many connections (19, max 0)". What am I missing?

A0011: A current release of Exim. :-) The message you are getting is the wrong message. What it should be saying is "too many messages received in one SMTP connection" (see next question). This bug was fixed in release 2.051.

Q0012: What does "no immediate delivery: too many messages received in one SMTP connection" mean?

A0012: 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.

Q0013: Exim puts "for <address>" in the Received: headers of some, but not all, messages. Is this a bug?

A0013: 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.

Q0014: 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.

A0014: 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.

Q0015: Exim is unable to route to any remote domains. It doesn't seen to be able to access the DNS.

A0015: Try running "exim -d11 -bt <remote address>". The -d11 will make it show the resolver queries it is building and the results of its DNS queries. If it appears unable to contact any nameservers, check the contents and permissions of /etc/resolv.conf.

Q0016: I'm using ETRN to run a script that checks things and doesn't always end up running "exim -R". However, after it has run once, subsequent attempts fail with "458 Already processing".

A0016: Set no_smtp_etrn_serialize.

Q0017: What does the error message "transport system_aliases: cannot find transport driver "aliasfile" in line 92" mean?

A0017: "aliasfile" is a director, not a transport. You have put a configuration for a director into the transports section of the configuration file.

Q0018: 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.

A0018: (A) 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 Q0021.

(B) This can also happen if a machine has a broken TCP stack and won't reassemble fragmented datagrams.

(C) 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.

Q0019: What does the message "Socket bind() to port 25 for address (any) failed: address already in use" mean?

A0019: 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.

Q0020: I've set headers_check_syntax, but this causes Exim to complain about headers like "To: Work: Jim <jims@email>, Home: Bob <bobs@email>" which look all right to me. Is this a bug?

A0020: 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 822. 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.

Q0021: 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?

A0021: "Broken pipe" is the error you get on some OS when the far end just drops the connection. The alternative is "connection reset by peer".

(A) There are some firewalls that fall over on \0 characters in the mail. Have a look, e.g. with hexdump -c mymail | tail to see if your mail contains any binary zero characters.

(B) 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?

(C) 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's 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 MTU path 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).

Q0022: 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.

A0022: 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 batch_max on the smtp transport, and that limit was reached. This would show as a sequence of n messages down one connection, then another n 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.

Q0023: What does the error "SEGV while reading ... from dbm file: record assumed not to exist" mean?

A0023: A crash is occuring when Exim calls your DBM library in order to read a record from one of its hints files. This kind of problem can be related to incorrectly installed DBM libraries. If you are using Slackware 3.6, the problem is that libgdbm is incorrectly installed on that system, and you will need to re-install it from source.

Q0024: There seems to be a problem in the string expansion code: it doesn't recognize references to headers such as ${h_to}.

A0024: The only valid syntax for header references is (for example) $h_to: because header names are permitted by RFC 822 to contain a very wide range of characters. A colon (or white space) is required as the terminator.

Q0025: Exim is timing out after sending the a message's data to one particular host, and yet the remote host also claims to be timing out. This seems to affect only certain messages.

A0025: See Q0018.

Q0026: When the Exim daemon forks a copy of itself to handle an incoming SMTP request, the forked copy seems to go around in circles for a significant (up to 5 minutes, so far) amount of time before deciding to accept the message.

A0026: 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 message. Configuration options that cause outgoing calls are:

(1) rfc1413_query_hosts and rfc1413_query_timeout (for ident calls); firewalls sometimes block ident calls, which can lead to this problem.

(2) rbl_domains and rbl_hosts.

(3) host_lookup and any other options that require the remote host's name to be looked up from its IP address.

You can use the -bh option to get more information about what is happening at the start of a connection.

Q0027: 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.

A0027: 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.

Q0028: What does "<message filter> transporting defer (-1): No transport set by director" in a log line mean?

A0028: Your system filter contains a "save" command, but you have not set message_filter_file_transport.

Q0029: Why is Exim refusing to relay, saying "failed to find host name from IP address" when I have the sender's IP address in host_accept_relay? My configuration contains this:
         host_accept_relay = "lsearch;/etc/mail/relaydomains:192.168.96.0/24"

A0029: When checking host_accept_relay, 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. The solution is to put all explicit IP addresses first in the list. You would have discovered what was going on if you had run a test such as

         exim -bh 192.168.96.131
Q0030: When I run "exim -bd -q10m" I get "PANIC LOG: exec of exim -q failed".

A0030: 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
Q0031: 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?

A0031: See Q0026.

Q0032: 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}}"

A0032: 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}}\""
Q0033: 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)".

A0033: If your alias entry looks like this:

         alias:  |"/some/command some parameters"

change it to look like this:

         alias:  "|/some/command some parameters"
Q0034: I'm having a problem with an Exim RPM.

A0034: See Q9606.

Q0035: What does the error "Spool file is locked" mean?

A0035: 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 log_level less than 5, 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 - say more than a few hours. That would suggest that the process that is delivering the message has somehow got stuck.


1. BUILDING EXIM

Q0101: I get the error "conflicting types" when Exim is building the libident library.

A0101: The problem is that libident assumes "struct timeval" refers to DST_NONE, and so it tries to avoid using this structure when DST_NONE isn't defined. Unfortunately it doesn't make this change everywhere it should, and so it blows up. The problem has been seen on NetBSD and some versions of the Linux C library. An easy, albeit not particularly neat, fix is to add -DDST_NONE to LIBIDENTCFLAGS for systems that are afflicted like this - there's not a lot else you can do without modifying libident. The value of DST_NONE is never used, so defining it to be empty should be harmless.

Q0102: When I ran make I got the error "undefined reference to dbopen".

A0102: Either:

(A) This means you (or the default configuration for your operating system) have configured Exim to use Berkeley DB version 1.xx and it has not been given access to the DB library (where dbopen should be found). You may need something like DBMLIB=-ldb in Local/Makefile. Berkeley DB is one of several alternative DBM libraries that Exim can make use of. For a discussion of DBM issues, see the file doc/dbm.discuss.txt in the Exim distribution.

(B) You are running on a version of Linux which has a problem in its libraries. This effect isn't fully understood. It has been seen with the libraries used in Caldera OpenLinux Base 1.1.

Q0103: I can't get Exim to compile with Berkeley DB version 2.x.

A0103: 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.

Q0104: 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'".)

A0104: You should either remove the definition of USE_TCP_WRAPPERS or add -lwrap to your EXTRALIBS setting in Local/Makefile.

Q0105: 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?

A0105: If you are changing to release 3.00 or later from a release prior to 3.00, you will probably need to make changes to the runtime configuration file. See README.UPDATING for details. Otherwise, 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 if you are running one.

Q0106: What does the error "install-info: command not found" mean?

A0106: 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.

Q0107: Exim doesn't seem to be recognizing my operating system type correctly, and so is failing to build.

A0107: 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.

Q0108: I am getting an error "`exim' undeclared here" when I compile, in the globals.c module.

A0108: You have set EXIM_UID = exim in your Local/Makefile. Unfortunately, named uids are not permitted here; you must give a numerical uid. However, in the runtime configure file names are permitted.

Q0109: Exim fails to build, complaining about the absence of the "killpg" function.

A0109: 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".

Q0110: I'm getting an unresolved symbol ldap_is_ldap_url when trying to build Exim.

A0110: 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 scanned when linking.


2. MAILBOX LOCKING

Q0201: Why do I get the error "Permission denied: creating lock file hitching post" when Exim tries to do a local delivery?

A0201: 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:

(A) 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.

(B) 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 (A) and (B) 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.

Q0202: I am experiencing mailbox locking problems with Sun's mailtool used over a network.

A0202: See A9705 in the Sun-specific section below.


3. ROUTING

Q0301: What does "lowest numbered MX record points to local host" mean?

A0301: It means exactly what it says. Exim has tried to route a domain that it thinks is not local, and when it looked it up in the DNS, the lowest numbered MX record pointed at the local host.

(A) If the domain is meant to be handled as a local domain, then there is a problem with the setting of the local_domains configuration option. If you have not set this, then only the name of the local host is treated as a local domain. If, for example, your host is called myhost.mydomain.com and you want it to handle mail for the domain mydomain.com as well as for its own name, you must set

             local_domains = myhost.mydomain.com:mydomain.com

or, if you want to be more general, you could use

             local_domains = *.mydomain.com:mydomain.com

If you have a large number of individual local domains, you should investigate storing them in a file and setting local_domains to do a lookup.

All the domains in local_domains are treated as synonymous by default. If you want to specify different handling for different domains, you can either use domains options, to restrict certain directors to certain domains, or use the $domain expansion variable in director options to vary the value according to the domain, for example, setting the name of an alias file to /etc/aliases/$domain.

(B) If the domain is one for which the local host is providing a forwarding service (called "mail hubbing"), possibly as part of a firewall, then you need to set up a router to tell Exim where to send messages addressed to this domain, since the DNS directs them to the local host. The routers section of your configuration file should look something like this:

             hubbed_hosts:
               driver = domainlist
               transport = remote_smtp
               route_list = see discussion below
             other_hosts:
               driver = lookuphost
               transport = remote_smtp

Note that the domainlist router must come first so that it can pick off a hubbed host before it gets to the lookuphost router. 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 byname"

If there isn't a convenient relationship between the domain names and the host names, then 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_file option.

(C) If neither (A) nor (B) is the case, then the lowest numbered MX record for the domain should not be pointing to your host. You should arrange to get the DNS mended.

Q0302: How do I configure Exim to send all non-local mail to a gateway host?

A0302: Replace the lookuphost router in the default configuration with the following:

         send_to_gateway:
           driver = domainlist
           transport = remote_smtp
           route_list = "* gate.way.host byname"

This uses gethostbyname() to find the gateway's IP address. You could alternatively have "bydns" to do a DNS lookup with MX handling, in which case "gate.way.host" is really being treated as a mail domain name rather than a host name. If there are several hosts you can send to, you can specify them as a colon-separated list. See also Q0325 and Q0402.

Q0303: 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.

A0303: 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.

Q0304: How can I arrange for messages submitted by (for example) Majordomo to be routed specially?

A0304: See A0404.

Q0305: 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.

A0305: 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 = domainlist
           transport = special_transport
           route_list = "some.domain"

Alternatively, you could make some.domain a local domain, and use a smartuser director instead.

Q0306: The route_list setting ^foo$:^bar$ $domain byname in a domainlist router does not work.

A0306: 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 byname. Alternatively, you could use several items and write

         route_list = "foo $domain byname; bar $domain byname"

Note the semicolon separator. This is because the second thing in each item can be a list - of hosts.

Q0307: I'm getting "permission denied" when Exim attempts to check a require_files option.

A0307: See A0410 below.

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: The way to do this is not to include the domain in local_domains, so that addresses initially get passed to the routers. The first router should be definied like this:

         special_local:
           driver = domainlist
           local_parts = whatever...
           domains = whatever...
           route_list = * localhost byname
           self = local

That will pick off those addresses with matching local parts and domains, and hand them to the directors, because of the self = local setting. Any other addresses will fall through to the other routers and be handled as normal remote addresses.

Q0309: For certain domains, I don't want Exim to use MX records. Instead, I want it just to look up the hosts' A records. I tried using a negative entry in mx_domains in the smtp router, but it didn't work.

A0309: The mx_domains option specifies domains for which there must be an MX record (an A record isn't good enough). Consequently, a negative item in it doesn't do what you want - any domain matching is is not required to have an MX record, but it doesn't stop Exim from using MX records for any that do have them. You can achieve what you want using either a lookuphost or a domainlist router:

(A) Using lookuphost:

         special_domains:
           driver = lookuphost
           transport = remote_smtp
           domains = list:of:domains:you:want:to:do:this:for
           gethostbyname

(B) Using domainlist:

         special_domains:
           driver = domainlist
           transport = remote_smtp
           domains = list:of:domains:you:want:to:do:this:for
           route_list = * * byname

If the list of domains is actually a lookup in a file, you can dispense with domains in the domainlist case, and put the lookup into the route_list option.

Q0310: 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?

A0310: As your first router, have the standard lookuphost router from the default configuration, with the added options

         no_more
         self = fail_soft

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 fail_soft setting causes it to pass the address on to the next router. (The default causes it to generate an error.)

As your second (and last) router, set up a domainlist router that sends everything to your internal mail server. That is, use an option of the form

         route_list = * internal.server byname
Q0311: How can I arrange that messages larger than some limit are handled by a special router?

A0311: If you are using Exim 2.10 or greater, you can use a condition option on the router of the form

         condition = ${if >{$message_size}{100K}{yes}{no}}

Earlier versions of Exim do not have numerical comparison operators, though you can use tricks like

         condition = ${if eq {${substr_5:$message_size}}{}{no}{yes}}
Q0312: If a DNS lookup returns no MX records why doesn't Exim just bin the message?

A0312: If a DNS lookup returns no MXs, Exim looks for an A 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 lookuphost router, but you will cut yourself off from those sites (and there still seem to be plenty) who do not set up MX records.

Q0313: 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?

A0313: 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 nameservers (or some configurations of some nameservers) 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.

Q0314: Can you specify a list of domains to explicitly reject?

A0314: Use a router like this:

         reject_domains:
           driver = domainlist
           self = fail_hard
           domains = list:of:domains:to:reject
           route_list = * localhost byname
Q0315: Is it possible to use a conditional expression for the host item in a route_list for the domainlist router? I tried the following, but it doesn't work:
         route_list = "* ${if match{$header_from:}{.*\\.usa\\.net\\$} \
                       {<smarthost1>}{<smarthost2>} bydns_a"

A0315: The problem is that the second item in the route_list contains white space, which means that it gets terminated prematurely. To avoid this, you must put the second item in quotes, and because the whole item is already in quotes, you have to escape them like this:

         route_list = "* \"${if match{$header_from:}{.*\\.usa\\.net\\$} \
                       {<smarthost1>}{<smarthost2>}\" bydns_a"
Q0316: 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?

A0316: If you are receiving the mail via SMTP, then you can use verification to weed out the bad addresses. Set no_verify on the router which sends everything to your smart host, and insert a new router with verify_only that does general routing using DNS lookups (e.g. the default lookuphost router), or any other verification you want. Then set receiver_verify so that addresses are accepted only if they verify successfully.

Q0317: I have a dial-up machine, and I use the queue_smtp 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 mins saying 'retry time exceeded', and all addresses are affected.

A0317: See Q1401.

Q0318: How can I route mail for user X@local to a smarthost if X doesn't exist on the local host?

A0318: See A0428.

Q0319: How can I arrange to do my own qualification of non-fully-qualified domains, and then pass them on to the next router?

A0319: If you have some list of domains that you want to qualify, you can do this using a domainlist router. For example,

         qualify:
           driver = domainlist
           route_list = "*.a.b  $domain.c.com"

adds ".c.com" to any domain that matches "*.a.b". In the absence of any options in the route item, the new domain is passed to the next router.

If you want to do this in conjunction with a lookuphost router, the widen_domains option of that router may be another way of achieving what you want.

Q0320: 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.

A0320: Set up a router with senders=nobody@your.domain which routes all mail to a local transport that delivers it to /dev/null (or to a pipe that bounces with an error message, or whatever). That would catch all mail to non-local domains.

Q0321: 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.

A0321: (A) 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.

(B) Effects like this are sometimes seen if a domain's nameservers get out of step with each other.

Q0322: I'd like route all mail with unresolved addresses to a relay machine.

A0322: Set pass_on_timeout on your lookuphost router, and add below it a domainlist router that routes everything to the relay.

Q0323: I would like to forward all incoming email for a particular domain to another machine via SMTP. Whereabouts would I configure that?

A0323: First, do not list the domain in local_domains. Instead, list it in relay_domains. Then, if the domain's lowest numbered MX record points to your host, set up a domainlist router before your normal lookuphost router, in order to route the domain to the specific host.

Q0324: Why does Exim say "all relevant MX records point to non-existent hosts" when MX records point to IP addresses?

A0324: 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.

Q0325: 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.

A0325: 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:
           driver = lookuphost
           transport = remote_smtp
           domains = lsearch;/etc/local_domains.list

This does a perfectly conventional DNS routing operation, but only for your local domains. Follow this with a "smarthost" router:

         internet:
           driver = domainlist
           transport = remote_smtp
           route_list = * mail.isp.net bydns_a

This sends anything else to the smart host.


4. DIRECTING

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 director is something like this:

         virtual:
           driver = aliasfile
           domains = virt.dom.ain
           file = /usr/lib/aliases.virt
           search_type = lsearch
           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.

You can get separate deliveries for each unknown address only if you can direct them to a specific transport, by using a smartuser director like this:

         virtual:
           driver = aliasfile
           domains = virt.dom.ain
           file = /usr/lib/aliases.virt
           search_type = lsearch
         default_virtual:
           driver = smartuser
           domains = virt.dom.ain
           transport = special_delivery
           new_address = postmaster@virt.dom.ain
           no_more

If an address in the virtual domain is not matched by the normal alias lookup, then it gets picked up by the smartuser and passed to the transport with a new address. There is no checking for duplicates, so if there is more than one address that passes through this mechanism, multiple copies get delivered. In order to distinguish them, the envelope_to_add option can be set on the transport, to cause the insertion of an Envelope-To: header containing the original recipient address.

Q0402: How do I configure Exim to send all messages to a central server?

A0402: This implies that you are not doing any local deliveries at all. Set

         local_domains =

in the configuration file. This specifies that there are no local domains (by default your host name is set up as a local domain). Then all addresses are non-local - A0302 tells you how to deal with them.

Q0403: How do I configure Exim to send messages for unknown local users to a central server?

A0403: At the end of the directors section of the configuration, insert the following director:

         unknown:
           driver = smartuser
           transport = unknown_transport

You should add no_verify to this if you are verifying addresses; without it, all local parts will verify as valid in the local domain. Then somewhere in the transports section of the configuration insert

         unknown_transport:
           driver = smtp
           hosts = server.host.name

A colon-separated list of hosts may be given. They are tried in order. By default, the IP address of any host is found by looking in the DNS and doing MX processing (so really it is a domain list rather than a host list). If you don't want MX processing, set the "gethostbyname" option:

         unknown_transport:
           driver = smtp
           hosts = server.host.name
           gethostbyname

This calls the gethostbyname() function to find IP addresses. Depending on your operating system and configuration, this usually consults /etc/hosts and possibly other sources of information, as well as, or instead of, the DNS.

If you want to change the recipient address when doing this, you can use the new_address option on the smartuser director. For example, if the address is user@foo.bar.com and the setting is

           new_address = $local_part@bar.com

The message is sent to the server with the envelope recipient changed to user@bar.com. However, this does not make any changes to the message's headers.

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 director or 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 names in /etc/aliases or do I have to set up an alias file for each domain?

A0405: You can do it either way. If you use a single file, you must set include_domains on the aliasfile director. If you use a separate file for each domain you can use a single director with an option such as

         file = /etc/aliases/$domain

(as in C007), or you can have several different directors, each one with

         domains = domain1:domain2:...

so that each one processes certain domains only. That way you could have several domains sharing an alias file. All of this assumes that you want have different aliases for each domain. If all the domain names are in effect just synonyms, you don't need to do anything other than ensure they all match something in local_domains.

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 forwardfile director, 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: Using the queries option for the aliasfile driver should do what you want. You can supply a second query which gets obeyed when the first query fails. For example,

       queries = "\
         ldap:://x.y.z/l=yvr?aliasaddress?sub?(&(mail=$local_part@$domain)):\
         ldap:://x.y.z/l=yvr?aliasaddress?sub?(&(mail=default@$domain))"
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.

For example, if the alias file for foobar.com is

         foo: joe@some.place.com
         postmaster: foo

then mail sent to postmaster@foobar.com is not delivered to joe@some.place.com but instead goes to foo@localdomain.com.

A0408: Set the qualify_preserve_domain option on the aliasfile director.

Q0409: We've got users who chmod their home to 750, and home is NFS-mounted without root privilege, so Exim cannot access ~user/.forward.

A0409: Set the seteuid option on the forwardfile director so that Exim "becomes" the user before trying to read the file. However, if your operating system does not support the seteuid() function, you cannot do this. In that circumstance, if you cannot persuade your users to make their .forward files world readable, you can set the ignore_eacces option, which causes Exim to ignore unreadable files.

Q0410: I'm getting "permission denied" when Exim tries to check a for the existence of a user's .procmailrc file using require_files.

A0410: Exim is running under its own uid (or root if there isn't an Exim uid) when it checks require_files. You can cause it to change to a specific uid by putting an item not containing any / characters at the start of the require_files list. In this case you probably want a director along these lines:

         procmail:
           driver = localuser
           require_files = ${local_part}:${home}/.procmailrc
           transport = procmail_pipe
Q0411: How can I deliver mail into different directories for each virtual domain, doing user lookups not against /etc/passwd but against /etc/passwd.domain?

A0411: See configuration sample C009.

Q0412: I want mail for any local part at certain virtual domains to go to a single address for each domain.

A0412: One way to to this is

         virtual:
           driver = smartuser
           domains = lsearch;/etc/virtual
           new_address = ${lookup{$domain}lsearch{/etc/virtual}{$value}fail}

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
          etc.

If the number of domains is large, using a DBM or cdb file would be more efficient.

Q0413: How can I make Exim look in the alias NIS map instead of /etc/aliases?

A0413: The default configuration does not use NIS (many hosts don't run it). You should change the system_aliases director to

         system_aliases:
           driver = aliasfile
           file = mail.aliases
           search_type = nis

If you want to use /etc/aliases as well as NIS, put this director (with a different name) before or after the default one, depending on which data source you want to take precedence.

Q0414: What does the error message "error in forward file (filtering not enabled): missing or malformed local part ..." mean?

A0414: If you are trying to use an Exim filter, you have forgotten to enable the facility, which is disabled by default. In the forwardfile director (in the Exim configuration file) you need to set

         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.

Q0415: Exim isn't recognizing certain forms of local address.

A0415: (A) Try using the -bt option with debugging turned on, to see how Exim is handling the addresses. For example,

         exim -d2 -bt z6abc

will show you how it would handle the local part "z6abc". Increase the debug level to -d9 for more information.

(B) If the local user names contain capital letters, that is probably the cause of your problem. Setting up such user names is a bad idea. By default, everything is lowercased before the final delivery for the sake of alias matching and user name matching, because people who type email addresses often get the case wrong. You can stop this by setting

         locally_caseless = false

but then incoming addresses are recognized only in the correct case. See also Q0424 for a way round this.

Q0416: 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.

A0416: See A0308.

Q0417: 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?

A0417: This is not possible. The result of a pipe command is not available to a filter, because it doesn't run any deliveries while filtering. It just sets up deliveries. They all 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.

Q0418: When I set a suffix on one of my directors, it doesn't get stripped when checking the local_parts option. Why is this?

A0418: The test on local parts and domains is done early on, and only if they match is supplementary processing such as prefix and suffix recognition done. There is a section of the manual called "Skipping directors" which gives details. If you want to ignore a prefix or suffix in the initial test of the local part, you can do so by replacing local_parts with a setting of the condition option. For example, suppose you wanted to look up the basic local part in a file, and run the director if it is found:

         condition = "${if lookup{\
           ${if match{$local_part}{^(.*)-request}{$1}{$local_part}}\
           }lsearch{/some/file}{yes}}"

The key that is looked up is the second line, which uses a regular expression to strip "-request" from the local part if it is present.

Q0419: 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?

A0419: 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.

Q0420: Why am I seeing the error "bad mode (100664) for /home/test/.forward (userforward director)"? 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.

A0420: 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 forwardfile director.

Q0421: How can I arrange that messages larger than some limit are handled by a special director?

A0421: See A0311.

Q0422: 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?

A0422: Setting skip_syntax_errors on the forwardfile director 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 director like this one

         real_localuser:
           driver = localuser
           transport = local_delivery
           prefix = real-

before the forwardfile director. 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 forwardfile director:

         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:

         ^real-([^@]+)@your\.dom\.ain$    $1@your.dom.ain   h

This means that users won't ever see the "real-" prefix, unless they look at the Envelope-To header.

Q0423: I have some users on my system with upper case letters in their login names, but these are not recognized.

A0423: See A0424.

Q0424: I have unset locally_caseless 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?

A0424: 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 your directors, put one like this:

         set_case_director:
           driver = smartuser
           new_address = "${lookup{${lc:$local_part}}lsearch{/the/file}\
                          {$value@$domain}fail}"

For efficiency, you should also set the new_director option to cause processing of the changed address to begin at the next director. If you are otherwise using the default configuration, then the setting would be

         new_director = system_aliases

If there are lots of users, then a DBM or cdb file would be more efficient than lsearch. If you are handling several domains, then you will have to extend this configuration to cope appropriately.

Q0425: I want to look up local users in an SQL database instead of looking in the passwd file.

A0425: (A) From release 3.03, Exim contains support for calling MySQL.

(B) If you can set up an LDAP interface to your SQL database, then this is relatively straightforward to do, since Exim contains LDAP support. Sample configuration C009 shows you how to lookup users in /etc/passwd/whatever instead of /etc/passwd. Modifying this to use LDAP instead of looking in a file would be easy.

(C) If you can access SQL from Perl, you could use Exim's embedded Perl facility, but this is expensive in terms of resources used.

You must consider what will happen if your database is down. All local mail delivery will be delayed until it comes up again. Whether this matters is of course something for you to decide. If the database is down a lot and it does matter, then consider some scheme of extracting a list of users from the database at regular intervals, and getting Exim to work off that. This is also likely to be more efficient.

Q0426: Is it possible for Exim to use a SQL database like MySQL for its lists of virtual domains and explicit aliases?

A0426: See A0425.

Q0427: Can I use my existing alias files and forward files as well as procmail and effectively drop in exim in place of Sendmail ?

A0427: Yes, as long as your alias/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).

Q0428: How can I route mail for user X@local to a smarthost if X doesn't exist on the local host?

A0428: This is the same question as Q0402. The duplication is a bug in the FAQ.

Q0429: 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?

A0429: See the example in the section of the manual entitled "System-wide automatic processing".

Q0430: I am building some largish mailing lists with Majordomo, and was wondering if it worth leaving the actually list expansion to the aliasfile :include: mechanism or should I consider using the forwardfile transport? Is there any real difference in terms of facilities and/or performance, and are the expansions basically the same code anyway?

A0430: The code that pulls out individual addresses from a list is the same in both cases, so it's really just a matter of which is the most convenient for you.

Q0431: 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?

A0431: Add a new director like this, immediately before the normal localuser director:

         vacation:
           driver = localuser
           require_files = .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 = forwardfile
           check_localuser
           require_files = $home/.vacation.msg
           file = /some/central/filter
           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 message goes on to be delivered as normal.

Yet another possibility is to make use of Exim's autoreply transport. See C033.

Q0432: I want to use a default entry in my alias file, 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.

A0432: (A) If you know for certain that no alias in your alias file ever generates another alias that is in the same file, then the most efficient solution is to put

         new_director = name-of-following-director

in your aliasfile director. This stops Exim from processing the generated names as aliases the second time.

(B) If you can't give that guarantee, then you have to put dummy entries in the alias file for all your local parts, for example:

         luke: luke

(C) Another possibility is to put the aliasfile director for these aliases after the localuser director, so that local parts get picked off first. You will need to have two aliasfile directors if there are some local parts (e.g. root) which you do want to handle as aliases rather than local users.

Q0433: 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?

A0433: If you are using release 3.10 or later, you can use a smartuser director like this:

         obsolete:
         domains = lsearch;/etc/exim/obsolete.domains
         new_address = :blackhole:

If you want to make any exceptions, for example, for mail to postmaster at those domains, you can add the line

         local_parts = !postmaster

If you are using an earlier release of Exim, you have to set up an alias file in order to use :blackhole:

         obsolete:
         domains = lsearch;/etc/exim/obsolete.domains
         file = /blackhole/all
         search_type = lsearch*

with the file containing

*: :blackhole:

and possibly a postmaster alias if you want.

Q0434: How can I arrange that mail addressed to anything@something.mydomain.com gets delivered to something@mydomain.com?

A0434: Ensure that all the relevant domains are local, by setting

         local_domains = mydomain.com : *.mydomain.com

Then set up a smartuser director like this:

         user_from_domain:
           driver = smartuser
           new_address = "${if match{$domain}{^(.+)\\\\.mydomain.com\\$}\
             {$1@mydomain.com}fail}"
Q0435: I can't get a regular expression to work in this local_parts option on one of my directors:
         local_parts = ^0740\d{6}

A0435: The local_parts option is expanded before use, so that you can, for example, make it dependent on the domain. Therefore, you need to write

         local_parts = ^0740\\d{6}

so as to preserve the backslash.

Q0436: 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.

A0436: For a single group you could just hardwire the file name into a director 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
         ...

Arrange that the domains are treated as local by setting

         local_domains = "partial-lsearch;/that/file"

Then create a director like this

         domain_aliases:
           driver = aliasfile
           domains = partial-lsearch;/that/file
           file = /etc/aliases.d/$domain_data
           search_type = lsearch*

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.

Q0437: When Exim tries to read /usr/lib/majordomo/lists/lists.aliases it is giving "Permission denied", but that file is world-readable!

A0437: Check the permissions on the superior directories.


5. DELIVERY

Q0501: What does the error "Neither the xxx director nor the yyy transport set a uid for local delivery of..." mean?

A0501: 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 director that handled 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 director or the transport. A setting on the transport overrides a setting on the director, so if the same transport is being used with several directors, 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 aliasfile director. 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 director. What you put for the ???? is up to you, and depends on the particular circumstances.

Q0502: Exim won't deliver to a host with no MX record.

A0502: (A) 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 nameservers 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 an A record. You can check for this state using one of the DNS interrogation commands, such as "dig".

(B) Is there a wildcard MX record for your domain? Is the search_parents option on in your lookuphost router? (Prior to Exim version 1.80 this was the default; it was changed because of this problem.) If the answer to both these questions is "yes", then 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 a machine 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 machine 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 lookuphost router may be helpful in this circumstance.

Q0503: How should Exim be configured when it is acting as a temporary storage system for a domain on a dial-up host?

A0503: See Q1402.

Q0504: I would like to deliver mail addressed to a given domain normally, but also to generate a message to the envelope sender.

A0504: If the domain is a local one, you can do this with an "unseen" smartuser director and an autoreply transport, along the following lines:

         # 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}"
         # Director
         auto_warning_d:
           driver        = smartuser
           domains       = <domains you want to do this for>
           condition     = ${if eq{$sender_address}{}{no}{yes}}
           transport     = warning_t
           no_verify
           unseen

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 delivery error report). 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.

Q0505: 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.

A0505: This could be a problem with Exim's databases. 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 of Berkeley db, because no ndbm.h file is distributed with it.

Q0506: Whenever Exim tries to do a local delivery, 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 director): Permission denied (euid=1234 egid=101)

A0506: Have you remembered to make Exim setuid root?

Q0507: I have installed Exim, but now I can't mail to root any more. Why is this?

A0507: Most people set up root as an alias for the manager of the machine. 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 local 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.

Q0508: How can I stop undeliverable bounce messages (e.g. to routeable, but undeliverable, spammer senders) from clogging up the queue for days?

A0508: Set ignore_errmsg_errors to drop them immediately, or set ignore_errmsg_ errors_after to specify a (short) time to keep them for. I use 12h so that I notice them, but they go away relatively quickly.

Q0509: How can mails that are being routed through directors other than localuser be delivered under the uid of the recipient?

A0509: A0501 contains background information on this. If you are using, say, an alias file to direct messages to specific mailboxes, then you can use the "user" option on either the aliasfile director or the appendfile 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.

Q0510: I want to use MMDF-style mailboxes. How can I get Exim to append the ctrl-A characters that separate indvidual emails?

A0510: Set the 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:

         prefix = "\1\1\1\1\n"
         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.

Q0511: I have an ISDN connection and would like a way of running the queue automatically when it is up.

A0511: 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.

Q0512: 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?

A0512: 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.

Q0513: 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.

A0513: You need to unset the 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
           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 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.

Q0514: What does the message "Unable to get root to set uid and gid for local delivery to xxx: uid=yyy euid=zzz" mean?

A0514: 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".

Q0515: I upgraded to 2.04 and now my Envelope-To: header for my virtual domains is gone. Any idea how to get it back?

A0515: Read paragraph 1 of the 1.92 information in README.UPDATING. Add envelope_to_add to your transports for your virtual domains. You may also want to set return_path_add and delivery_date_add.

Q0516: The Exim log records the arrival of a message, and then "Completed", without logging any deliveries. What's going on?

A0516: This is unlikely in current versions of Exim, because more logging has been added. In versions before 2.053, one scenario is that the message was addressed to some user who has set up an Exim filter containing the command "seen finish", which discards a message without doing any deliveries. (In current versions of Exim this is logged as "discarded".) More information can be obtained by setting

         log_received_recipients

so that next time you can see to whom it is addressed. Another possibility, prior to version 2.053, was that the message was injected using the -t option, but all the addresses in the message were also on the command line. See A5020 for more detail. Current versions of Exim generate a bounce message in this case.

Q0517: 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?

A0517: Exim does not support any kind of delivery notification.

(A) You can configure it to recognize headers such as "Return-receipt-to:" if you wish.

(B) Some people want MSN (message status notification). Such services are implemented in MUAs, and don't impact on the MTA at all.

(C) I investigated the RFCs which describe the DSN (delivery status notification) system, and there is even a bit of code in there (excluded by #ifdef) for handling some of the data. 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.

Q0518: 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.

A0518: Your ISP is delivering all the messages in a single SMTP session. Exim limits the number of immediate delivery processes it will create as a result of a single SMTP connection, in order to avoid creating a zillion processes on systems that can have many incoming connections. In your situation, you should probably set smtp_accept_queue_per_connection to some number larger than 10.

Q0519: 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?

A0519: Because the RFCs say it must be. Your ISP is at fault. Send them this extract from RFC 1123 section 5.3.3 ("Reliable Mail Receipt"):

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; see Section 3.6 of RFC-821. The recipient of this notification SHOULD be the address from the envelope return path (or the Return-Path: line). However, if this address is null ("<>"), the receiver-SMTP MUST NOT send a notification. If the address is an explicit source route, it SHOULD be stripped down to its final hop.

Q0520: What does the message "retry time not reached [for any host]" on the log mean? Why won't Exim try to deliver the message?

A0520: 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.

Some MTAs have a retrying schedule for each message. Exim does not work like this. Retry timing is normally host-based for remote domains and address-based for local domains. (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 setting log_level to a value that is less than 5. 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. See also Q0533.

Q0521: 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 dequeued. Why doesn't Exim support this?

A0521: 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/.

Q0522: 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.

A0522: 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 forwardfile director, but you are not allowed to have expansions to pipes or files on directors that have one_time set. Therefore, you will have to have a separate director 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 then 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 A0521 for a discussion of an alternative approach.

Q0523: 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.

A0523: 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 the draft of the forthcoming revision to RFC 821:

... 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. However, exploiting the case sensitivity of mailbox local-parts impedes interoperability and is discouraged.

Q0524: How can I force the next retry time for a host to be now?

A0524: (A) You can force a particular message to be delivered with the -M command line option. If it 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.

(B) You can change the retry time with the exim_fixdb utility, but its interface is very clumsy.

Q0525: I set up "|/bin/grep Subject|/usr/bin/smbclient -M <netbiosname>" as an alias but it doesn't work.

A0525: 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>'"
Q0526: Why does the pipe transport add a line starting with ">From" to messages?

A0526: Actually, it adds a line starting with "From", because that is the default of the "prefix" option (/usr/ucb/vacation needs it, and that is the most common use of piping). If you don't want it, change the setting of "prefix".

Q0527: 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.

A0527: fallback_hosts only works 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 Q0322 for a possible solution.

Q0528: 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?

A0528: Unless you have changed smtp_accept_queue_per_connection (introduced at release 2.03) it should only spawn that many processes per connection (default 10). Your ISP may be making many connections, of course. That is limited by smtp_accept_max.

Q0529: 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.

A0529: 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.

Q0530: Can Exim add a Content-Length: header to messages it delivers?

A0530: 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

Q0531: 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

A0531: 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".

Q0532: 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.

A0532: 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.

Q0533: 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.

A0533: 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).

Q0534: Why does Exim bounce messages without even attempting delivery, giving the error "retry time not reached for any host after a long failure period"?

A0534: 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.

Q0535: 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?

A0535: 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.


6. UUCP

Q0601: The MX records for some UUCP domains point to my local host. How do I get it to pass the messages on to UUCP?

A0601: There are several possibilities. One straightforward way is to set up a domainlist router which matches the UUCP domains and routes to a suitable transport. Sample configuration C003 is such a configuration, while C004 shows another way to do it, by defining the domains as local and using a smartuser director.

If all the domains whose MX records point to the local host are either local domains or UUCP domains, you can do without the domainlist router altogether, by making use of the "self" option. This means that only the DNS has to be updated when a UUCP domain is added or removed.

For example, this router routes to remote hosts over SMTP using a DNS lookup with default options, and fails for unknown domains (because of the no_more setting), but if the MX for a domain points at the local host, Exim continues on to the next router (self = fail_soft overrides no_more).

         lookuphost:
           driver = lookuphost
           transport = smtp
           no_more
           self = fail_soft

The next router can just send everything to a suitable UUCP transport:

         uucp:
           driver = domainlist
           transport = uux_transport
           route_list = "* $domain"

This assumes that the transport can determine the UUCP host name from the domain name.

Q0602: How can I get Exim to handle "bang path" addresses?

A0602: In general, you can't (Exim is an Internet mailer and recognizes only RFC 822 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

         ^([^!]+)!(.+)@your\.domain$   $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

         ^([^!]+)!([^@%]+)(.+)$   $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.

See also sample configuration C002, which contains some more sophisticated rewriting rules.

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

         ^([^!]+)!(.+)$  $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.

Q0603: We see something strange on our system in regards to mail comming 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.

A0603: 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.


7. PERFORMANCE

Q0701: I'm running a large mail server. Should I set split_spool_directory to improve performance?

A0701: There doesn't seem to be any significant performance hit using a flat queue on Solaris systems, so there is no need to do this for them. On the other hand, there is a known performance problem on Linux filing systems, where split_spool_directory can make a significant difference. ???? Other operating systems ????

Q0702: How well does Exim scale?

A0702: 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
         auto_thaw 60s
         max_queue_run 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."

Q0703: We have a large password file. Can Exim use alternative lookups during delivery to speed things up?

A0703: Yes. You don't have to use the password file at all. See sample configuration C009 for some suggestions. (It shows lsearch lookups, but these could equally be DBM or cdb or NIS or LDAP lookups.)


8. POLICY CONTROLS

Q0801: How do I block unwanted messages from outside my host?

A0801: There are several different options that can be used to block incoming SMTP messages according to different criteria. The following are the most commonly used:

(A) Set sender_verify; this causes rejection of any message whose envelope sender cannot be successfully routed. This is mainly a check on the existence of remote domains, though it the domain is a local one, the local part also gets checked. Unfortunately, error mesages do not have envelope sender addresses, so cannot be checked in this way. See the headers_sender_verify options for ways of checking header addresses.

(B) If you want to block all mail from specific hosts or IP networks, set host_reject_recipients. The _recipients form of the option is more likely to prevent the remote hosts from keeping on trying. For example:

             host_reject_recipients = 209.12.111.0/24

If you have many such blocks, they can be put in a file which is named in the option. If you have a mixture of IP addresses and names in your list, it is best to put the addresses first, because they can be checked without the need for a DNS lookup.

(C) If you want to block mail from specific envelope sender addresses, one convenient way is to organize a file of local parts indexed by domain names, for example

             x.y.z     creditrepair:^betterlovelife[0-9]+$:...
             p.q.r     *

This would block creditrepair@x.y.z, any local part starting with betterlovelife and ending with digits in the x.y.z domain, and all addresses in the p.q.r domain. You refer to the file in the Exim configuration as follows:

             sender_reject_recipients = @@lsearch*;/name/of/the/file

If the file is big, you can convert it into a DBM or cdb file and use a faster lookup method. The asterisk on the end of the search type causes a lookup for "*" if the domain is not found; that is, it permits a default list of local parts that are blocked at any domain that is not specifically listed. If you use this, you probably also want to end each local part list with ">*" (except those that consist of "*"). This causes Exim to check the default list of local parts if none of the specific ones for a domain are matched. So, the file above could become

             *         yourfriend:a.friend:...
             x.y.z     creditrepair:^betterlovelife[0-9]+$:>*
             p.q.r     *

If you are using an lsearch file, putting the * entry first saves a bit of processing.

(D) If you want to allow mail to postmaster through the blocks, you can set

             recipients_reject_except = postmaster@your.domain

This overrides any of the policy controls that cause rejection by recipient.

Q0802: I don't want to block spam entirely; how can I inspect each message before deciding whether to deliver it or not?

A0802: This can be done by using a system filter. See the sample configuration F003.

Q0803: How can I test that my spam blocks are working?

A0803: The -bh option allows you to run a testing SMTP session as if from a given IP address. For example,

         exim -bh 192.203.178.39

In addition to the normal SMTP replies, it outputs commentary about which tests have succeeded or failed.

Q0804: How can I test that Exim is correctly configured to use the Realtime Blocking List (RBL)?

A0804: The -bh option allows you to run a testing SMTP session as if from a given address. 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.

Q0805: How can I use tcpwrappers in conjunction with Exim?

A0805: 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(5) man page for more ways of specifying clients, including ports, etc., and on logging connections.

Q0806: How can I get POP-auth-before-relay support in Exim?

A0806: See http://cc.ysu.edu/~doug/exim-pop.tar.Z which has some scripts for this, courtesy of Doug S <doug@cc.ysu.edu>.

Q0807: I have one or two cases where my machine correctly rejects messages, but the remote machine is quite persistent, and keeps trying over and over.

A0807: 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 MAIL FROM command or the DATA portion of the transaction as a permanent error. Consequently they keep resending the message. Failing checks on a message's headers (the headers_... options) necessarily result in an error code after the data has been received.

Q0808: I am seeing the error "no valid sender in message headers: return path is <>" in the reject log. Isn't <> a valid return path for error messages?

A0808: It is indeed valid. The complaint here is about the contents of the message's headers, not the return path. This message has been reworded in later versions of Exim. You must have set the headers_sender_verify option. Check the From:, Reply-to: and Sender: headers that were logged with the error. You can use Exim's -bv option to find out why verification of those addresses failed.

Q0809: Let's say that we want to run a mail server that does not care if you have proper reverse DNS. If you include host_reject lines in your config file, Exim will always reject connections from such hosts. How can this be avoided?

A0809: This is true only if you have wild-carded host names in host_reject. For complete host names, Exim uses a DNS forward lookup to obtain an IP address to compare. If you are using wild cards of any sort, put +allow_unknown as an item in your host list, for example:

         host_reject = +allow_unknown : *.def.zz : *.stu.yy

This will allow any host without reverse DNS to bypass the checks. Note that it means that the owner of abc.def.zz (for example) can trivially get round your block simply by deleting the PTR record for abc.def.zz. If you use +warn_unknown instead of +allow_unknown, the action is the same, but every time the exception is invoked, it is logged.

Q0810: Is there a way to prevent lookups in the RBL for local hosts?

A0810: Check out the rbl_hosts option.

Q0811: How can I set up the sender_reject option in my config file so I can reject mail by matching regular expressions?

A0811: You must either put the regular expressions directly in the option setting, or in a file that is referenced by a plain file name, or use an @@ type of search. If the regular expressions match the domain as well as the local part, then the first two approaches are the only possible ones. For example:

         sender_reject_recipients = ^.*\.spam\.com$ : ^.*@[0-9]+\.com$

or

         sender_reject_recipients = /some/file

Each line of the file is treated as if it were an entry in the list, and must begin with ^ if it is a regular expression. No keys are involved because this is not a lookup,

If you are using version 2.10 or later, the first of those regular expressions can be rewritten to execute much more efficiently by using lookbehinds and once-only subpatterns:

         sender_reject_recipients = ^(?>.*$)(?<=\.spam\.com)

See the manual section entitled "Address lists" for a description of the @@ type of split domain/local part lookup. See also Q0801.

Q0812: Normally sender_reject_recipients works fine, but addresses that have some uppercase letters in them seem to come through.

A0812: This should no longer be the case from release 3.00 onwards. Although host and domain names are case-insensitive, the RFCs about mail specify that local parts are case sensitive. When earlier versions of Exim looked up a sender address in sender_reject_recipients, they did so using the caseful form, in order to be compliant with the mail RFCs. (In principle, user@domain and USER@domain might be different people. Silly, I know, but that's the rule. It has caused a lot of grief.) However, RFC 2305 (Anti-Spam Recommendations for SMTP MTAs) recommends that address checking in blocking lists should be done caselessly, so Exim now does this by default.

Q0813: I want to accept some sender addresses, even though they do not verify. There doesn't seem to be an option for verification exceptions, so how can I do this?

A0813: Set up a special director or router to ensure that those addresses do verify, using verify_only and verify_sender so that it is not used during delivery or recipient verification. For example, here is a router which verifies the address root@somedomain.com:

         verify_exceptions:
           driver = domainlist
           verify_only
           verify_sender
           domains = some.domain.com
           local_parts = root
           route_list = *
Q0814: We are being plagued by forged mail coming from a number of different hosts and sender addresses. The guy however leaves a fingerprint. The first received line always contains 'Received: from baby'. What is the best suggested way for eliminiating him from our systems?

A0814: You cannot, unfortunately, prevent the message from getting into your system, because the message has to be read before you can inspect the Received: header. The best you can do is to install a system filter which junks any message containing such a header. Thus the sender still wastes bandwidth and your resources in transporting the message to you, but you just throw it away. A simple system filter that does this is

         # Exim filter
         if $h_Received: contains "from baby" then seen finish endif
Q0815: I have set host_accept_relay, but my host still refuses to relay from matching hosts.

A0815: (A) Did you remember to HUP or restart the Exim daemon after changing the configuration? You can get information as to what options Exim is checking by using the -bh option to test how it would handle mail from a specific host.

(B) Have you used any wild-card host names in host_accept_relay? E.g:

             host_accept_relay = *.aaa.bbb

If so, the problem may be that the relevant hosts do not have reverse DNS entries for their IP addresses. In order to match a wild card name, Exim has to look up the calling host's name from its IP address, and if it cannot do so, it takes a hard line by default. Exim processes lists from left to right, and so will attempt a reverse DNS lookup at the first wild-carded entry it reaches. If you have IP addresses in your list, it is best to put them first for this reason. Suppose you had

             host_accept_relay = *.x.y : 10.9.8.7

Then when the host 10.9.8.7 connects, a reverse lookup will still be done, because the first check is against *.x.y. If the lookup fails, relaying is rejected. However, if the list were in the opposite order, the IP check would succeed, and no DNS lookup would be done. See also Q0809.

Q0816: How can I run customized verification checks on incoming addresses?

A0816: If you can implement your checks in Perl, then 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 install this as your first director:

         private_verify:
           driver = smartuser
           condition = ${perl{verify}{$local_part}{$domain}}
           verify_only

If you want this to be the only means of verification, you can set no_verify on all the other directors. Otherwise, if this director fails to verify, the address gets passed on to those that follow.

The verify_sender and verify_recipient options can be used to restrict the director to sender or recipient verification only, and if necessary you could have two different directors, one for senders and one for recipients.

If the result of the expansion of condition is not "no", "false" or "0", then address verification succeeds, because the director itself matches any address. The expansion of condition causes the Perl subroutine called "verify" to be run, with two arguments, the local part and the domain. The subroutine must be provided in Perl code that is referenced by the perl_startup option. See the chapter on embedded Perl for details.

Remote addresses can be handled in a similar way by using a domainlist router that matches all domains. See also Q0813.

Starting up a Perl interpreter is not cheap. On a busy system you should first make sure that there isn't some way of using Exim's own facilities for doing what you want before going down this road.

Q0817: Does Exim apply RBL checks to error messages, those with an envelope sender of "<>" ?

A0817: Yes, it does, because the RBL check happens immediately on connection, before any commands are passed, and so therefore before it even knows that the envelope sender is "<>".

Q0818: I want to be able to set up a list, similar to sender_reject_recipients, but with a user-defined message. I believe I have to use a director for this.

A0818: You can do this using the prohibition_message mechanism (see the section entitled "Customizing prohibition messages" in the manual). This avoids having to use a director, and therefore doesn't require you to let the message into your host at all. Use something like this:

         prohibition_message = "\
           ${if eq {$prohibition_reason}{sender_reject_recipients}\
           {${lookup{$sender_address}lsearch{/some/file}{$value}}}{}}"

This example looks up a message that is specific to the sender, but you can of course tailor the message any way you like. Vertical bar is treated as a line separator in prohibition texts.

Q0819: I want to reject certain sender-recipient combinations, with a specific message for each such combination.

A0819: That needs a special director, using the "senders" option to predicate it on the sender, and a file of recipients to fail for each sender. Something like this:

         forced_fail:
           driver = aliasfile
           senders = sender@domain.com : *@otherdomain.com
           file = /blocked/${lc:$sender_address}
           search_type = lsearch

with the files containing lines like

         recipient:  :fail:  message

If you are handling multiple local domains, you may want to set include_domain so you can specify fully qualified addresses in the files. If the files get big, an indexed search type such as DBM or cdb should be used.

If you want to block an entire domain from a specific sender, you could use this director:

         domain_block:
           driver = aliasfile
           senders = dislikedsender@wherever
           file = /fail/all
           search_type = lsearch*

with the file containing

         *:   :fail:   message

The message text supplied after :fail: is restricted to a single line. If you want to send several paragraphs of message, instead of using :fail: you could use the aliasfile to pipe the message off so some script which generates a long message and then gives a non-zero return code so that the message gets returned to the sender.

In all of these cases you are in trouble if the sender address is bad, because the bounce message you generate will get stuck.

Q0820: 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?

A0820: 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.

Q0821: 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?

A0821: This could be done by arranging for a quota check to happen during the verification of the address after RCPT, but without hacking Exim you would have to use the embedded Perl facility to get it to run a Perl script to do the test.

If the reason you want to do this is to avoid having messages for over- quota users sitting on your spool for many days, there is an alternative. In Exim you can set up special retry rules for quota excession (what we use is "if mailbox not read for 7 days, bounce immediately, otherwise try every hour for one day, then bounce").

Q0822: I'm looking for a rule to reject special unknown recipients.

A0822: If the messages in question are coming in via SMTP, you can turn on receiver_verify (if you haven't already) and arrange for these addresses not to verify. For example, if they are not in your local domains, you could use a router like this:

         verify_check_specials:
           driver = domainlist
           condition = "\
             ${if eq {$local_part@$domain}{account@host.domain}{yes}{no}}"
           verify_only
           fail_verify
           route_list = *

where of course you can extend the condition setting to use regular expressions, file lookups, Perl calls, or anything else that is available. The failure of the verification causes an error return to the SMTP RCPT command, so the messages never get into your system. For addresses in your local domains you could use a smartuser director in a similar fashion, but you could also use an alias file with :fail: entries.

If you are receiving such messages from the local host, then they are already in the system, and have to be failed locally as part of the delivery process. The :fail: mechanism is the simplest for local addresses. For remote addresses, one possibility would be to use a router with a condition setting to send such messages to an autoreply transport that sends back an error message to the sender. See also Q0826.

Q0823: I'd like to pass all messages through a virus-scanning system before delivery. Can Exim do this?

A0823: 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 director 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 = smartuser
           transport = virus_scan
           condition = "${if or {{eq {$received_protocol}{scanned-ok}} \
                                 {eq {$sender_host_address}{127.0.0.1}}}\
                                 {0}{1}}"

A similar router could be used if you want to scan messages for remote addresses. 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.

Q0824: How can I accomplish this: a message sent from any host must either be sending to a domain in a list (a dbm file) or the sender's address domain must be in the list.

A0824: First of all, set

         relay_domains = dbm;/the/dbm/file

This allows relaying from any host, provided that the recipient address matches one of the domains in the list. Then set

         host_accept_relay = *
         sender_address_relay = dbm;/the/dbm/file

This allows relaying from any host (because of the *) to any arbitrary domain, provided that the sender's address matches a domain in the list.

WARNING: This setting makes it possible for your host to be used as an open relay by those unscrupulous enough to forge sender addresses. Your host may end up on one of the open relay blocking lists as a result.

Q0825: I've set relay_domains and sender_address_relay, but if user@mydomain tries sending to an arbitrary domain, Exim rejects it.

A0825: The safest way to control relaying arbitrary domains is by host, not by sender address. If you are able to specify the hosts which your users use, then set host_accept_relay to match them. You can then remove the setting of sender_address_relay, unless you also want to limit relaying to specific senders.

If you want to permit relaying from specific senders on arbitrary hosts, you can set relay_match_host_or_sender. This requires that only one of the host or sender address be recognized, instead of both of them.

WARNING: This setting makes it possible for your host to be used as an open relay by those unscrupulous enough to forge sender addresses. Your host may end up on one of the open relay blocking lists as a result.

Q0826: I set sender_reject_recipients, but Exim is not rejecting those recipients.

A0826: You have misunderstood the option. A setting like that rejects all the recipients of an incoming message with that sender. To reject a specific recipient in your own domain you can set up an alias like this:

         reject-me:  :fail: mail for reject-me is not acceptable

If you want to reject a recipient that is not in a local domain, one approach is to set up a router to send the address to your directors, and then use an alias file to generate a :fail: message as above. Alternatively, you can use the verification mechanism: see Q0822.

Q0827: I can't find an option to deny "RCPT TO:" addresses.

A0827: Denying RCPT TO addresses is the job of verifying. You can set up directors and routers that are run only when verifying and not when delivering. This gives you a great deal of flexibility. See Q0822.

Q0828: My problem is that Exim replaces $local_part with an empty string in the system filtering. What's wrong or what did I miss?

A0828: 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.

Q0829: Using $recipients in a system filter gives me another problem: how can I do a string lookup if $recipients is a list of addresses?

A0829: Check out section 25 of the filter document ("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.

Q0830: Is there a way to configure Exim to reject mail to a certain local host?

A0830: No, only to certain domains. Use a configuration like this:

         receiver_verify
         local_domains = rejected.domain : <other local domains>

with the first director as

         reject_domains:
           driver = smartuser
           domains = rejected.domain
           verify_only
           fail_verify
Q0831: Exim sometimes rejects messages with bad senders after the DATA and sometimes after the MAIL command. What is the difference?

A0831: The first time Exim encounters a particular bad sender, it rejects the message after the data has been received, so that it can log the headers. If the same sender re-appears within 24 hours, Exim assumes that the remote host has (in violation of RFC 821) not interpreted the previous 550 error code correctly, so this time it rejects the MAIL command. Some hosts don't even managed to handle that, so if the same sender turns up for a third time within 24 hours, Exim accepts MAIL, but rejects every RCPT command instead.

Q0832: How can I get Exim to remove attachments from messages?

A0832: (A) The cleanest way is to check for the existence of a "Content-type" header line, and route messages containing it down a pipe to some other program that strips the attachments and re-submits the message to Exim. Alternatively, a transport filter can be used to do the job, as described in C028.

(B) A somewhat more hairy way is to use embedded Perl from a system filter to truncate the message's data file directly, and then use the "headers remote" filter command to get rid of the associated headers.

Q0833: I ran a relay test against my host and it failed with an address containing a %, though I don't have percent_hack_domains set. Is Exim broken? This is what the tester said:
         Relay test 6
         >>> RSET
         <<< 250 Reset OK
         >>> MAIL FROM:<spamtest@example.com>
         <<< 250 <spamtest@example.com> is syntactically correct
         >>> RCPT TO:<relaytest%mail-abuse.org@example.com>
         <<< 250 <relaytest%mail-abuse.org@example.com> is syntactically correct
         Relay test result
         Uh oh, host appeared to accept a message for relay.
         The host may reject this message internally, however

A0833: This does not prove that your host is open for relaying. Notice the wording of the last two sentences: "appeared to accept" and "may reject internally". Assuming that your Exim configuration is correct, Exim will discover that the local part "relaytest%mail-abuse.org" is not valid on your host, and it will bounce the message.

Why doesn't it reject the RCPT TO command? Answer: because you have not set receiver_verify in your configuration file, or you have excluded these particular sender or recipient domains from receiver verification.


9. MAJORDOMO

Q0901: How do I set up Majordomo to work with Exim?

A0901: Users have found several ways of setting up Exim for use with Majordomo. There's a web page at

         http://www.netmaster.ca/exim/majordomo.html

which shows one way to do it, and discusses some of the issues. The sample configuration C018 is another approach which automates a lot of the functions based on whether the files or directories exist. Only three aliases per list are needed.

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.

Q0902: I have set $mailer in majordomo.cf, but it still isn't setting the sender correctly in the messages it sends.

A0902: 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.

Q0903: I'm trying to set up majordomo, but I'm getting a "wrong mode" error when I try to send it mail. The panic log entry reads:

1999-01-05 11:23:34 0zxZGY-0000vB-00 majordomo_aliases director: /var/lib/majordomo/lists/lists.aliases (lsearch lookup): wrong mode

A0903: Check the mode of /var/lib/majordomo/lists/lists.aliases and compare it with the setting of the modemask option in the majordomo_aliases director. This option specifies bits which must not be set for the alias file, and it defaults to 022.

Q0904: I'm getting return code 9 from /home/majordomo/majordomo-1.94.4/wrapper when it is passed a message from Exim.

A0904: A problem like this turned out to be the Perl version that came with RedHat 5.2. Rebuilding Perl 5.005x solved it.


10. REWRITING

Q1001: How can I get Exim to strip the hostname from the sender's address?

A1001: 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 "From" address and to the From:, Reply-to:, and Sender: headers.

Q1002: 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.

A1002: Check the DNS record for your domain. If the MX record points to a CNAME record instead of to an A record, MTAs are liable to rewrite addresses, changing your domain name to its "canonical" form, as obtained from the CNAME record.

Q1003: I want to rewrite local addresses in mail that goes to the outside world, but not for messages that remain within the local intranet.

A1003: Exim wasn't really designed to handle this kind of split world. Because it keeps only one copy of a message, and does all the rewriting at the time of reception, a standard configuration cannot handle this kind of rewriting in a message that has both internal and external recipients.

However, what can be done is to split off a copy of the message to be sent to all external recipients, and do the rewriting on that. This can be achieved by running two differently-configured versions of Exim, either on a single host, or on two different hosts. If you have a gateway or firewall machine, that is the natural place to run the rewriting version.

On a single machine, the following is one way of handling this:

(1) Set up the normal configuration (in the configuration file whose name is screwed into the binary) such that it does local deliveries as required, but forwards a copy of the message for non-local recipients to a different incarnation of Exim via a private SMTP port. For example, use this transport and router:

             # Transport to send SMTP using port 26
             internal_smtp:
               driver = smtp
               service = 26
             # Router to send everything the internal_smtp transport
             pass_remotes:
               driver = domainlist
               transport = internal_smtp
               route_list = * localhost byname
               self = send

This should be the only router. Because of the self = send setting, Exim will transport the messages, even though it knows it is going to the local host.

(2) Set up a different configuration file for the rewriting version of Exim. This need do no local deliveries, so it needs no local domains or directors, and as it accepts mail only from the local host, there is no need for any spam-blocking or other policy controls. However, it does need to have its own spool area. The main part of the configuration could be like this:

             local_domains =
             local_interfaces = 127.0.0.1
             host_reject = !127.0.0.1
             spool_directory = /var/spool/exim-external
             end

Note the use of a negated item for host_reject, causing rejection of SMTP calls from all but the local host.

The directors section can be completely empty (apart from the line saying "end"), while the routers section should be as in a normal configuration, as it is going to control external delivery.

The rule(s) for rewriting your internal addresses into external ones should be in this configuration. This is one example of what might be done:

           *@*.your.domain  "\
              ${lookup{$1}cdb{/etc/$2/mail.handles.cdb}{$value}fail}"

which looks up each local part in a per-host file to obtain the externally-visible address, including (in this example) the domain.

(3) You have to arrange for a daemon to be listening on port 26, and to be using the alternate configuration file. It is necessary to do this as root so that Exim retains its privilege after reading a non-standard configuration. A command such as

             exim -C /etc/exim-configure2 -bd -oX 26

could be used in a suitable system start-up file. Alternatively you could set up inetd to run Exim with the -C option for incoming connections on port 26.

The net result of all of this is that when a message has one or more external recipients, a copy of it is sent via port 26 to the second version of Exim, which rewrites any internal addresses and does the external deliveries. The cost of this is that the message has to be copied and spooled twice, and you have two different Exim queues to manage. Note that if the "external" Exim has to send a delivery failure message, it will use the rewritten sender address.

Q1004: 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

A1004: Replace $1 in your rule by ${lc:$1} to force the local part to lower case before it is used as a lookup key.

Q1005: Is it possible to completely fail a message if the rewrite rules fail?

A1005: 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.

Q1006: 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?

A1006: 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

(not the best example) 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}".

Q1007: I want to rewrite local sender addresses depending on the domain of the recipient.

A1007: 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. 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. See also Q1003.


11. HEADERS

Q1101: I would like add some custom headers to selected outgoing mail based on a specific domain and the subject line.

A1101: 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.

Q1102: Is it possible to have Exim add a header to only certain local_parts of outgoing mail?

A1102: 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. Then you could use conditions in an expansion string to add or not add a header.

Q1103: How can I remove some part of the Received: header?

A1103: Set received_header_text.

Q1104: How I can insert the PGP header line using exim filters?

A1104: 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.


12. FETCHMAIL

Q1201: When I run fetchmail, I get the error "SMTP listener doesn't like recipient address xxx@localhost".

A1201: Put "localhost" in a list of local domains, that is, add it to the local_domains option in your Exim configuration file.

Q1202: Fetchmail is passing on bounce messages to Exim with the sender address set to <@some.domain> which causes Exim to complain, because there is no local part.

A1202: This was a fetchmail problem which has been fixed. Ideally, you should upgrade to the current fetchmail release. If you cannot do this, there is some Exim magic that might help. The 'S' rewriting flag allows rewriting of envelope addresses to be done as soon as they are received in the SMTP protocol, before any kind of checking or other processing is done. This is specifically provided for installations that have to cope with mangled addresses coming in over SMTP.

Q1203: 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.01. Will it check the source address against RBL? Or will it check the From: header?

A1203: 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 fetchmail 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

Q1401: How can I arrange for mail to other hosts on my local network to be delivered when I'm not connected to the Internet?

A1401: Use the queue_remote_domains option to control which domains are held on the queue for later delivery. For example,

         queue_remote_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: (A) You should be using queue_remote_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 not relevant. You should probably also be using -qq to do your queue run rather than -q.

(B) An alternative approach if you are sending all your outgoing mail to the same smart host is to use a single router like this:

   	 route_append:
	 driver = domainlist
	 transport = remote_smtp
	 route_list = "* smarthost.isp.net byname"

and put the address of the smart host in /etc/hosts, so that it can be found without the need of a DNS lookup. Then you can use queue_smtp_ domains so that Exim does the routing for every message, but doesn't try to deliver it. See also Q1403.

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 your host. You should set a large retry time for that 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. See the manual chapter entitled "Intermittently connected hosts" and also Q5014 and Q0521.

Q1404: I have queue_remote_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: (A) Instead of queue_remote_domains or queue_smtp_domains, use the queue_only_file option. This causes messages to be queued only if a particular file exists. The word "remote" or "smtp" before the file name controls which type of queueing is used. For example:

         queue_only_file = remote/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.

(B) An alternative is to set hold_domains to point to a file lookup and switch that file appropriately.


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.


50. MISCELLANEOUS

Q5001: What does the error "Unable to get interface configuration: 22 Invalid argument" mean?

A5001: 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.

Q5002: 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.

A5002: 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.

Q5003: How can I test for a message's size being greater or less than a given value in an expansion string?

A5003: This isn't straightforward in versions of Exim prior to 2.10, because there were no arithmetic operators in expansion strings. In version 2.10 or later you can write, straightforwardly,

         ${if > {$message_size}{10K} {yes} {no}}

In earlier versions, low cunning can be used to achieve certain kinds of test. For example, to test if the message size is less than or equal to 1000000:

       ${if eq{${expand:\$\{substr_-1000000_$message_size:x\}}} {} {yes} {no}}
Q5004: 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.

A5004: 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.

Q5005: I would like to have Exim log information written to syslog.

A5005: Support for this is available from version 3.10 onwards.

Q5006: What does the error "Failed to create spool file" mean?

A5006: 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 disc being full. 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".

Q5007: Exim keeps crashing with segmentation errors (signal 11 or 139).

A5007: This might be a problem with the db library. See Q0505.

Q5008: Exim's databases keep getting corrupted.

A5008: See Q0505.

Q5009: I've been using an autoreply director to try and mimic a bounce message, but I can't get it to have an envelope from of <>.

A5009: You haven't, by any chance, put "exim" in the list of never_users, have you?

Q5010: 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]

A5010: 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

         HELO [36.173.0.189]

when it sent your server the message. This is, of course, very misleading.

Q5011: How can I persuade Exim to accept ETRN commands without the leading # character?

A5011: 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.

If you use smtp_etrn_command to run something other than Exim with the -R option, you must disable smtp_etrn_serialize, because otherwise the serialization lock (which is set by default) never gets removed.

Q5012: 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.

A5012: 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. From RFC 822:

5.3. BCC / RESENT-BCC

This field contains the identity of additional recipients of the message. The contents of this field are not included in copies of the message sent to the primary and secondary recipients. Some systems may choose to include the text of the "Bcc" field only in the author(s)'s copy, while others may also include it in the text sent to all those indicated in the "Bcc" list.

Only the initiating software (i.e. the MUA) can tell what to do with Bcc; any MTA software has to leave it alone.

Q5013: I used gv v3.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?

A5013: 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.

Q5014: I would like to have a separate queue per domain for hosts which dial in to collect their mail.

A5014: 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 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 would be 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 Q0503 and Q0521.

Q5015: A short time after I start Exim I see a <defunct> process. What is causing this?

A5015: 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.

Q5016: 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?

A5016: -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.

Q5017: I would like to restrict e-mail usage for some users to the local machine, ideally on a group basis.

A5017: See A9802

Q5018: Whenever exim restarts it takes up to 3-5 minutes to start responding on the SMTP port. Why is this?

A5018: 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.

Q5019: Why aren't there any man pages for Exim? I don't always carry my printed documentation.

A5019: As well as plain ASCII text, the Exim documentation is provided in two online 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 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.

There is a contributed man page for a previous version of Exim in

ftp://ftp.cus.cam.ac.uk/pub/software/programs/exim/Contrib/doc/exim.8

This was written by a previous maintainer of the Debian GNU/Linux Exim package. You can view a nicely formated version at:

http://dwww.jimpick.com/cgi-bin/dwww?type=man&location=/usr/man/man8/exim.8.gz

This contains some introductory text and the command line options only.

Q5020: 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.

A5020: By default Exim operates according to the Sendmail documentation, 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. There is some confusion in the Sendmail community about the interpretation of recipient addresses on the command line if the -t option is used.

Here is an except from one version of the sendmail documentation

-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.

Earlier versions of the sendmail documentation are ambiguous (unlike the snippet above). Apparently the code and documentation streams resolved the ambiguity differently.

Q5021: If I set up, for example, local_domains = *customer.com, then 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?

A5021: (A) You have to specify two entries in the list:

         local_domains = customer.com : *.customer.com

because * in a domain list matches any characters, including "." and including a null sequence.

(B) Alternatively, you could use a regular expression:

          local_domains = ^(.+\.|)customer\.com$

but that probably will not be as efficient.

(C) If you have lots of local domains, you could put them into a file to be searched (using lsearch, dbm, cdb, or whatever) and use a partial search such as

         local_domains = partial-dbm;/list/of/domains

If the file contains the key *.customer.com then the desired effect is achieved, because partial lookups do operate on a component basis. See the section entitled "Partial matching in domain lists". It is a bit confusing that "*" is used in this context, because its meaning is not the same as when it appears directly in a domain list.

Q5022: I want to match all local 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 treated as local. What is the best way to do this?

A5022: (A) From release 3.00 onwards, you can put negative items in the local_domains setting, like this:

         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.

(B) Otherwise, you can use a regular expression:

         local_domains = ^.*(?<!^foo|^bar)\.oyoy\.org$

An alternative formulation that is more efficient in execution (because it doesn't backtrack for .* in cases that don't match) is

         local_domains = ^(?>.*$)(?<=\.oyoy\.org)(?<!^(foo|bar)\.oyoy\.org)

If you are using an earlier version of Exim in which the regular expression library does not have lookbehind support (versions prior to 2.051, but after 1.735):

         local_domains = ^(?!(foo|bar)\.oyoy\.org$).+\.oyoy\.org$

If you are using a version of Exim that is earlier than 1.735, consider upgrading!

Q5023: I can't seem to find a pre-built version of Exim anywhere. The machine is a Sparc 5 running Solaris 2.6.

A5023: The problem is that there are a number of build-time options, requiring the answer 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?

... and so on. One could impose a set of values, but I suspect they would probably please nobody.

Q5024: Is there a Windows NT version of Exim available?

A5024: A long time ago somebody took a copy of the Exim source with the aim of trying to port it to NT. However, I never heard anything more.

Q5025: Does Exim support Delivery Status Notificaion (DSN), Message Status Notification (MSN), or any other form of delivery acknowledgement?

A5025: See A0517.

Q5026: What does "Exim" stand for?

A5026: 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...

Q5027: What does the log message "no immediate delivery: more than 10 messages received in one connection" mean?

A5027: See A0518.

Q5028: 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?

A5028: 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.

Q5029: 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?

A5029: Yes. This indicates a delivery failure report (aka "bounce message"). Here is what RFC 1123 has to say about this:

"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; see Section 3.6 of RFC-821. The recipient of this notification SHOULD be the address from the envelope return path (or the Return-Path: line). However, if this address is null ("<>"), the receiver-SMTP MUST NOT send a notification. If the address is an explicit source route, it SHOULD be stripped down to its final hop."

The reason for using empty sender addresses is to identify bounce messages so that they themselves do not cause further bounces. However, this has made life harder for those that want to check incoming mail for valid senders. It is a pity that some other mechanism (e.g. a keyword on the MAIL command) was not used instead, but it is far too late to change now.

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.

Q5030: 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?

A5030: 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 normally works entirely with the "envelope" addresses, not with those in the header lines. However, you can specify that it should do some checking of header addresses by setting a number of options whose names begin with headers_.

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.

Q5031: Can (or will) Exim ever handle a message delivery purely in memory, that is, it is handled without it ever hitting the disc?

A5031: 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 disc.

Q5032: 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?

A5032: 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) then 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.

Q5033: What are the main differences between using an Exim filter and using procmail?

A5033: Exim filters and procmail provide different facilities. Exim filters run at directing 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.

Q5034: 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.

A5034: 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 .forward and alias files that are causing delivery delays. However, there is an option you can set on an aliasfile or forwardfile director 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.

Q5035: 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.

A5035: See smtp_accept_max and related options such as smtp_accept_reserve.

Q5036: 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".

A5036: Use the -bF option to test system filters. This gives you access to the freeze and fail actions.

Q5037: 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.

A5037: (1) Set queue_only in the Exim configuration. (2) Kill off 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. To stop just local deliveries, assuming that none of your routers are configured to send messages directly to a local transport, make this your first director:

         defer_all:
           driver = smartuser
           new_address = :defer:

When you are ready to go again, remove that director and do a -qf run to override the retry times. This solution works from release 3.10 onwards. In earlier releases an aliasfile director must be used because :defer: was not available for use in smartuser.

Q5038: What does the rejection message "reject all recipients: 3 times bad sender" mean?

A5038: See the section of the manual entitled "Sender verification". Exim has failed to verify a sender from the same host 3 times within a period of 24 hours.

Q5039: The menu in Eximon isn't working. It displays, but I can't select anything from it.

A5039: On some X implementations, if the numlock key is pressed (so that the numeric keypad is working) then the menu didn't work properly in versions of Eximon before Exim release 3.10. The problem is an infelicity in the particular implementation of X. A workaround was introduced at release 3.10, so this problem should no longer be encountered.

Q5040: What does "ridiculously long message header" in an error report mean?

A5040: 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 machine ran out of memory. (Exim stores all the header lines in main memory). 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. Exceeding the limit provokes the "ridiculous" error message.

Prior to release 3.022 Exim used two separate limits, one on the length of an individual header line and one on the total number of header lines. A header line longer than 8192 used to provoke the error "Header line is ridiculously overlong". In subsequent releases there is no limit on individual header lines; only the total matters.

Q5041: What does Exim use for POP as a default? Do I have to install anything else?

A5041: Yes. Exim provides MTA functionality. That is, it delivers mail. POP is one of several ways of reading previously-delivered mail. Exim does not provide that functionality.


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: I'm running IRIX 6.2 with a number of alias IP addresses set up, but Exim doesn't seem to recognize them as local addresses.

A9501: This problem was fixed in Exim release 2.03. If you are running an earlier version you should use the local_interfaces option to specify all your IP addresses explicitly.

Q9502: The IP addresses for incoming calls are all being given as 255.255.255.255.

A9502: If you used the gcc compiler 2.8.x there is a known bug with the "gethost" function under Irix. SGI recommends using either their cc compiler in Irix 6.5, or a lesser version of the gnu compiler (2.6.x).

Alternatively, there is an Inst-able port of exim for Irix at http://freeware.sgi.com, but it is not likely to be the latest release.


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: Exim has created a directory called build-Linux-libc5-i386 but is trying to reference build-Linux-libc5-i386-linux while building.

A9602: You have several shells installed, which are setting conflicting values in the HOSTTYPE environment variable that is used to construct the name of the build directory. One way round this is to run this command:

         ln -s build-Linux-libc5-i386-linux build-Linux-libc5-i386

This problem should no longer be encountered in release 3.10 or later. Exim has been changed to get the host type from the "uname" command preferentially.

Q9603: 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?

A9603: 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.

Q9604: 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 Uni vers 12.250. Could this be anything to do with Exim?

A9604: 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.

Q9605: I get the "too many open files" error especially when a lot of messages land for majordomo at the same time.

A9605: 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.

Q9606: I'm having a problem with an Exim RPM.

A9606: 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.


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: The menu in Eximon isn't working on my Sun system.

A9704: With OpenWindows, if the numlock key is pressed (so that the numeric pad is working) then some menus don't work. This appears to be true for the console and (some) remote X-window servers. A workaround for this problem was introduced in the 3.10 Exim release, so it should no longer be encountered.

Q9705: I am experiencing mailbox locking problems with Sun's mailtool used over a network.

A9705: 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.

Q9706: Exim has been crashing on my Solaris x86 system, apparently while running DBM functions.

A9706: The use of ndbm with gcc has caused problems on x86 Solaris systems. Try changing one or the other; using either db 1.85 with gcc, or Sun's WS compiler with ndbm, has fixed this in the past.

Q9707: The exiwhat utility isn't working for me on a Solaris 2 system.

A9707: 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.

Q9708: How do I stop Sun's dtcm from hanging?

A9708: 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."

Q9709: 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.

A9709: 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

Exim uses gethostbyname and gethostbyaddr only, but may use others in the future. 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.


98. COOKBOOK

Q9801: How do I configure Exim as part of TPC (http://www.tpc.int)?

A9801: (1) add partial-lsearch;/etc/mail/tpc.domains to local_domains; /etc/mail/tpc.domains is a text file with lines in this format:

             9.3.5.1.0.8.1.tpc.int.

This sample line indicates that we accept faxes destined for 1(801)539-*.

(2) Set up the following transport:

             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.

(3) Set up the following director:

             tpc_director:
               driver = smartuser
               transport = tpc
               domains = "partial-lsearch;/etc/mail/tpc.domains"

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: There are several possible ways that this can be done.

(A) You can restrict the senders directly by putting a setting such as this one on all the drivers that route to the outside (usually this is just the final lookuphost router):

             senders = ":^[^@]+@(?!${rxquote:your.domain}\\$):\
                       lsearch;/permitted/senders"

The first item in this list is empty, to match the empty sender. This is necessary because bounce messages have null senders. The second item is a regular expression that matches any address whose domain is not your domain. This caters for cases when mail from an external user has arrived for a local user who has forwarding set up to some outside address.

If the first two items do not match (that is, the address is in your domain) the sender is looked up in a file of permitted senders; each item in the file must be a complete address, including the domain. If the sender is unacceptable, an "unrouteable mail domain" error will occur because the router won't run, and there are no more to try.

(B) If your local users are in many domains, it may be easier to use a condition option to test the domain and local part independently, along these lines:

             condition = "\
               ${lookup{${domain:$sender_address}}lsearch{/domain/list}\
               {\
                 ${lookup{${local_part:$sender_address}}lsearch\
                 {/permitted/senders}{yes}{no}}\
               }\
               {yes}}"

Obviously other means of testing the domain and local part could be substituted, for example, by having separate files of valid local parts for each local domain.

(C) If your local users are logged in to your host, you could use a special group for those that are permitted to mail to the world. Assuming your groups are defined in /etc/group you could arrange to look up the group in that file and then check that the sender was in the group,using something along these lines:

             condition = "\
               ${lookup{groupname}lsearch{/etc/group}\
               {${if match {$value}\
               {[:,]${rxquote:${local_part:$sender_address}}(,|\\\$)}\
               {yes}{no}}}{no}}"

This is checking the local part of the sender; a alternative might be to check $sender_ident. However, you should really also check that $sender_host_address is either unset or set to 127.0.0.1 or your IP address, so you check only locally-originated mail.

A block like this does not prevent a logged in user from sending mail by telnetting to another host's SMTP port, or indeed from installing a private version of Exim to do the job for her.

(D) On a gateway server that has no local users and so receives all the mail via SMTP from client hosts, you could use a rewriting rule to rewrite sender addresses in your local domain from a table of legal local parts, replacing any illegal addresses with an address such as unknown@your.domain. If this is combined with sender_verify=true it causes messages from users that are not in the table to be refused, assuming that the gateway is capable of verifying the local part of user@your.domain.

Q9803: How do I configure Exim to run with SmartList?

A9803: This is what was done for Exim's own mailing list, using SmartList/ procmail 3.11pre7. It runs as its own user - trying to manage mailing lists under your own ID can be hard work. Smartlist is installed into /var/spool/slist, and there is an slist user defined. Each list appears as a directory under /var/spool/slist (as per usual for Smarlist). Exim is configured like this:

         # slist added to list of trusted users so it can
         # manipulate sender addresses
         trusted_users = exim:slist
         # in transports, a list transport is defined:
         list_transport:
           driver = pipe
           command = "/var/spool/slist/.bin/flist \
                     ${local_part}${local_part_suffix}"
           current_directory = /var/spool/slist
           home_directory = /var/spool/slist
           user = slist
           group = slist
         # in directors a list director is defined:
         list_director:
           driver = smartuser
           suffix = -request
           suffix_optional
           local_parts = !.bin:!.etc
           require_files = /var/spool/slist/${local_part}/rc.init
           transport = list_transport

and thats it - no aliases, no special handling of out lists etc. What you do need is to ensure that choplist is used for distribution (that is, do not uncomment the alt_sendmail entry which is blank).

A couple of other things are forced - for example since the list runs in its own domain the domain value is forced to exim.org.

Then everything else is basic SmartList configuration - and that's moderately well documented. A confirmation stage on signup was added - now when you subscribe you are sent a confirmation which you must return before the system subscribes you (this prevents people subscribing their "friends" and makes sure that the addresses really do work). The confirm package is available at:

          ftp://ftp.fatfree.com/confirm-1.1.tar.gz

and was written by Michelle Dick.

Q9804: How do I configure Exim to minic PP's "tripnote" facility?

A9804: See C005.

Q9805: How do I configure Exim to handle local parts with extensions?

A9805: See C010.

Q9806: How do I configure Exim so that only a restricted list of users can receive mail from external domains?

A9806: See C013.

Q9807: I have someuser@mydomain.com that I only want certain users to be able to mail to. How do I accomplish this?

A9807: This is a transport:

         bounce:
           driver  = autoreply
           from    = postmaster@mydomain.com
           to      = $sender_address
           user    = exim
           subject = "Re: Your mail to ${local_part}"
           text    = "You are not allowed to mail to ${local_part}."

This is a director that should come before all the others:

         special_user:
           driver = smartuser
           local_parts = someuser
           transport = bounce
           senders = !: !lsearch;/list/of/permitted/senders

Note that leading "!:" in senders. It allows the null sender <> to be valid (i.e. not to match this director). This is necessary, since bounce messages have null senders. All other permitted senders must be in the file as complete addresses, including a domain.

Q9808: 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?

A9808: 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. There is an example of the latter approach in C014.

Q9809: How do I implement VERP (Variable Envelope Return Paths) in Exim?

A9809: See C017.

Q9810: I'd like to make a copy of all outgoing messages to a local mailbox. Is there a solution for this using an Exim filter?

A9810: The following filter makes a copy of every message, except for delivery failure reports:

         # Exim filter
         # Ignore error messages
         if error_message then finish endif
         # Copy if this is the first delivery attempt
         if first_delivery then
           unseen deliver copy@your.domain errors_to postmaster@your.domain
         endif

The keyword "unseen" stops this being a "significant delivery", so that the message goes on to be delivered as normal. The errors_to setting changes the envelope sender on the copy so that if there is a problem delivering it, the bounce message is sent to postmaster.

You can add to the condition setting to select specific messages. To make a copy of outgoing messages only requires a definition of "outgoing". Because a message may have many recipients, simply testing for your own domain in both the From: and the To: headers is not enough. You can craft your own conditions, but here is one suggestion:

         if $h_from: contains your.domain and
             foranyaddress $h_to:,$h_cc:
               ($thisaddress does not contain your.domain)
         then
           unseen deliver copy@your.domain errors_to postmaster@your.domain
         endif

This takes copies of messages whose From: header contains your.domain and whose To: and Cc: headers contain at least one address that does not contain your.domain. See also Q9817.

Q9811: I want to make a copy of outgoing messages to a specific file for each user in a specific directory, using a "save" command in a system filter. How can I arrange for Exim to write to these files under the correct UID/GID?

A9811: You need to set up a special transport and tell Exim to use it for file deliveries from the system filter. Add the following setting to your configuration:

         message_filter_file_transport = copy_transport

Then define copy_transport like this

         copy_transport:
           driver = appendfile
           delivery_date_add
           envelope_to_add
           user = ${local_part:$sender_address}

This assumes that you want to run the delivery under the uid associated with the local part of the sender address. Alternatively, you could just use user=exim and do all the writing under the same UID/GID.

Q9812: How can I keep an archive of all mail for some specific local email addresses?

A9812: You could use a system filter, along the lines of

         if
           first_delivery and <tests for appropriate addresses>
         then
           unseen save
             /mail/archive/${substr_0_10:$tod_log}
         endif

That would create a new file for each day. However, in order to use this, you will need to set message_filter_file_transport to point to an appropriate transport which includes a setting of "user" to specify which uid to run the saving under, as is described in Q9811.

Q9813: How can I configure Exim to provide a vacation message when there are no local users on my mail hub?

A9813: See C019.

Q9814: 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?

A9814: 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 director, which is placed immediately after system_aliases:

         cancelled_users:
           driver = localuser
           transport = cancelleduser_pipe
           fail_verify
           match_directory = /home/CANCELLED

This sends messages for cancelled users to the following special transport:

         cancelleduser_pipe:
           driver = pipe
           command = "/opt/exim/util/cancelleduser.sh"
           ignore_status
           return_output
           user = nobody

The script simply generates a message saying that the user is cancelled on its standard output. This gets returned to the original message sender in an error report.

If you don't want to change the home directory in the passwd file, an alternative is to check for the non-existence of the home directory with

         require_files = +!$home

instead of setting match_directory.

Q9815: I need an alias, say "fakeaddress" that should receive a message, strip all reply-to: headers present, substitute another one pointing to "otheraddress" and forward a message to "realaddress".

A9815: Add this director:

         fakeaddress_director:
           driver = smartuser
           domain = (if necessary to restrict the domain)
           local_parts = fakeaddress
           headers_remove = reply-to
           headers_add = reply-to: otheraddress
           new_address = realaddress

If there are several of these aliases then you could list them in a file along with the corresponding other addresses, and use lookups instead of the fixed values shown above.

Q9816: How can I set up Exim to work with Listar?

A9816: See http://www.cs.huji.ac.il/~vadik/listar-exim/.

Q9817: I need to take copies of all incoming and outgoing mail for certain users. For each user there may be a different monitoring address.

A9817: You can adapt the filter solution given in Q9810 by adding a test for the relevant local parts. Create a file containing lines like this:

         user1@domain1:   monitor1@monitor.domain1
         user2@domain2:   monitor2@monitor.domain2

and then use the following command in a system filter:

         if ${lookup{$sender_address}lsearch{/some/file}{$value}{}} is not ""
         then
           unseen deliver ${lookup{$sender_address}lsearch{/some/file}{$value}}
             errors_address = postmaster@your.domain
         else
           if foranyaddress $recipients
             (${lookup{$thisaddress}lsearch{/some/file}{$value}{}} is not "")
           then
             unseen deliver ${lookup{$thisaddress}lsearch{/some/file}{$value}}
               errors_address = postmaster@your.domain
           endif
         endif

It is messy to have to repeat the lookups, but it won't be inefficient, because Exim caches the results of successful lookups.

Q9818: How can I add a disclaimer to the end of every message?

A9818: This isn't as easy as it appears. You cannot just add text to the bottom of messages because of the possibility of MIME attachments. In any case, it is not the job of an MTA to mess with the contents of messages. You can perhaps do things with Exim's transport filters if you really have to, but if the messages originate locally, it would be better to do what you want in the MUA (e.g. force all your local users to have it in their .sig files).

Q9819: I would like to append a simple advertisement text to all outgoing and local mails.

A9819: See Q9818.

Q9820: How can I configure Exim so that all mails adressed to something@username.domain.net get delivered to /var/spool/mail/username?

A9820: There are several possibilities, depending on exactly how you are set up. Here is one approach: First, arrange that all the domains you are interested in are local domains, for example, by listing them in a file:

         local_domains = /list/of/domains

If there are lots of them, a DBM or cdb file should be used for a faster lookup. Assuming that "username" is set up as a user on your system, and you have a configuration that can handle username@domain.net in the normal way, all you have to do is to arrange to convert the recipient address by means of a smartuser director like this:

         user_in_domain:
           driver = smartuser
           domains = /list/of/domains
           new_address = ${if match{$domain}{^([^.]+)\\.domain\\.net\$}{$1}fail}@domain.net

This should be the first director.

Q9821: How do I get exim not to add a Sender: header to locally originated mail?

A9821: It only adds it if the From: header doesn't correspond to the user sending the message. You can't remove it in general (but this may be possible in a future release). However:

(1) You can get it removed later, by putting

         headers_remove = Sender

on all your transports. This doesn't test for locally originated mail, but you could use a more complicated expansion string to make that test. For example

         headers_remove = ${if eq{$sender_host_address}{}{Sender}}

which removes it only if there is no sending host address.

(2) If your real question "how do I submit mail from UUCP without it adding Sender:?" Then see Q0603.

Q9822: How can I get Exim to work with mailman?

A9822: The Exim mailing list uses the configuration that is given in the "how to" information at http://www.exim.org/howto/mailman.html.

Q9823: Is there any way to have messages sent to a specific local address delayed by - say - 24 hours?

A9823: Using Exim 3.10 or later, the answer is "yes". Set up a smartuser director like this:

         delay:
           driver = smartuser
           domains = the.domain
           local_parts = thelocalpart
           condition = ${if < ${$message_age}{86400}{yes}{no}}
           new_address = :defer: message not old enough

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.


99. LIST OF SAMPLE CONFIGURATIONS

Each sample configuration is held in a separate file in the config.samples directory. Those with names of the form Cnnn are Exim configurations; those with names of the form Fnnn are filter file fragments.

C001: "This config will support delivery across multiple systems using NIS to look up delivery addresses from the mail.aliases database."

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."

C003: "I've read down through Q0601 and your request for UUCP examples. Here's how I'm doing it." (This example uses routers.)

C004: "Here's a BSMTP over UUCP [configuration] - the transport is Taylor/GNU UUCP - which takes the long option types." (This example uses directors.)

C005: "I am using a virus scanner program that is invoked by a pipe, scans the mail and re-invokes Exim to do the delivery. The pipe is invoking a perl script that tries to unpack and MIME, zip and other archives and then applies the McAfee scanner on the results."

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."

C007: "If I host a domain foo.dom on my machine as a virtual domain I expect it to be completely virtual and separate from other mail domains that end up on my machine."

C008: "And of course it is possible to do a very interesting solution to this [virtual domains] using LDAP."

C009: "These are suggested parts of a configuration for looking up users in /etc/passwd.domain rather than in /etc/passwd ..."

C010: "One of our customers is looking for us to support addresses of the form username+extension@domain.com, primarily for use with procmail."

C011: "Thanks to Philip and others I now have my ISP style config built and therefore am posting the final configuration fragments to the list in case anyone else wants to do a similar thing."

C012: "I've written a small chapter how-to configure Exim for use with UUCP (mostly condensed from the exim-user mailing list plus some experimenting) and would be glad if it could be included in the Exim documentation."

C013: "I've take some tips from the FAQ about permitting only certain users to send to external mail and came up with my own for the receiving part."

C014: "If I have a situation where a site I MX for has a known outage I stash all their mail into a directory in BSMTP format."

C015: "This approach to virtual domains has helped me a great deal, and is so easy to maintain (add and modify as appropriate)."

C016: "Herewith my configuration." (A complete configuration, including simple virtual domains, along the lines of C015).

C017: "I have gotten the new VERP feature of Exim 2.054 working in test, along with some supporting programs to handle bounces that do come back."

C018: "This Majordomo configuration removes a lot of the aliases, and automates a lot of the other functions based on whether the files or directories exist."

C019: "The following configuration file entries can be used to provide a 'vacation'-style function for a mailhub which has no local users."

C020: "I was asked for a copy of the programs we were using to mail everybody."

C021: "Here is some sample code that might be useful for handling X-Failed-Recipients headers generated by Exim, with mailing lists."

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)."

C023: A Perl script and instructions for hooking it into Exim in order to handle disposition-notification-to and return-receipt-to by using a shadow transport to send copies of delivered messages to the script.

C024: "In case anybody wants to use a MySql database to store aliases this is how I managed to get my site working."

C025: "As promised here is the way I got Exim to delver to Cyrus mailboxes if the user exists in the MySql database."

C026: "The following configuration and program will allow messages going to AOL only, to be filtered thru a Perl script. This Perl script will convert any URL's to the HTML syntax. In addition, the transport will use VERP to send a unique envelope sender with each message."

C027: "This is an FYI to demonstrate how to have exim work with SSL using the stunnel wrapper and its underlying OpenSSL libraries and toolkit."

C028: "This Python script reads from stdin and writes to stdout. It strips all the MIME attachments from a mail message that are one of the mime types listed on the command line. Exim can use it in its configuration file, for example, as follows:"

C029: "The standard way to connect one's MTA to a list manager seems to be to add a set of aliases for every list one creates. Once upon a time, I crufted a set of configs from Smail to work with majordomo, to automaticaly recognize the standard patterns, for all lists in existence...I have setup a set of transports and directors for Exim, which will do the same thing for mailman."

C030: "I am currently configuring an exim for a site that will to mail hosting for several domains. I want the domain holders to have control over 'their' alias files, being able to create their own aliases. However, I don't want them to have postmaster, abuse and other role accounts under their control."

C031: "These are config file snippets for handling certain remote addresses as local, and making only real external addresses visible to users."

C032: "This is the Exim Nervous Mailbox Quota Suite. It does not impose hard quotas on users' mailboxes, but it makes a user nervous by putting all his mail in a secondary mailbox, inaccessible to the user, when he is over his quota. When the user clears his mailbox (i.e., deletes mail to make his mailbox below the quota again), mail from his secondary mailbox is transferred back to his primary mailbox, in FIFO order."

C033: "Here's our current automatic vacation recipe".

C034: "This is a HOW-TO for setting up Exim to support SMTP authentication under different environments, including regular password files, PAM and NIS."

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."