diff options
author | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 09:44:07 +0000 |
---|---|---|
committer | Daniel Baumann <daniel.baumann@progress-linux.org> | 2024-04-27 09:44:07 +0000 |
commit | 39ce00b8d520cbecbd6af87257e8fb11df0ec273 (patch) | |
tree | 4c21a2674c19e5c44be3b3550b476b9e63d8ae3d /doc/Exim4.upgrade | |
parent | Initial commit. (diff) | |
download | exim4-upstream.tar.xz exim4-upstream.zip |
Adding upstream version 4.94.2.upstream/4.94.2upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'doc/Exim4.upgrade')
-rw-r--r-- | doc/Exim4.upgrade | 1734 |
1 files changed, 1734 insertions, 0 deletions
diff --git a/doc/Exim4.upgrade b/doc/Exim4.upgrade new file mode 100644 index 0000000..86d4a4d --- /dev/null +++ b/doc/Exim4.upgrade @@ -0,0 +1,1734 @@ +Upgrading Exim from Release 3.33 to 4.xx +---------------------------------------- + +Exim 4.00 represents the largest upheaval in Exim's history. There are a lot of +changes to the way some parts of Exim work, and a lot of incompatible changes +to the run time configuration file. + +This document is in two parts. The first part contains instructions and +suggestions for how you might go about performing the upgrade. The second part +is a brief list of all the changes that have taken place. For full details of +all the new features, please consult the current version of the reference +manual. + + +HOW TO UPGRADE YOUR EXIM +------------------------ + +When you compile Exim 4, a Perl script called convert4r4 is built in the build +directory. It is not installed by the install script, because it is likely that +you will run it only once. + +This script is provided to assist in updating Exim configuration files. It +reads an Exim 3 configuration file on the standard input, and writes a modified +file on the standard output. It also writes comments about what it has done to +the standard error file. It assumes that the input is a valid Exim 3 +configuration file. A typical call to the conversion script might be + + ./convert4r4 </etc/exim/configure >/etc/exim/configure.new + +The output file MUST be checked and tested before trying to use it on a live +system. The conversion script is just an aid which does a lot of the "grunt +work". It does not guarantee to produce an Exim 4 configuration that behaves +exactly the same as the Exim 3 configuration it reads. + +Each option change in the new file is preceded by an identifying comment. In +fact, the conversion script tends to make quite a mess of your configuration, +and you should expect to go through it afterwards and tidy it up by hand. + +Unless you are running a very straightforward configuration, the automatic +conversion is likely to generate a non-optimal configuration. You should not +only check it thoroughly, but also run as many tests as you can, to ensure that +it is working as you expect. In particular, you should test address routing, +using -bt and -bv, and the policy controls, using -bh. If possible, you should +also do some live tests (i.e. send and receive some messages) before putting +Exim 4 into service. + +If you have a very complicated configuration, it is possible that convert4r4 +will break it in some situations, which is why thorough testing is strongly +recommended. + + ********************************* + ***** You Have Been Warned ****** + ********************************* + + +HOW TO MOVE FROM AN EXIM 3 RELEASE TO AN EXIM 4 RELEASE +------------------------------------------------------- + +One way of upgrading to Exim 4 from a version 3 release is as follows: + +1. Suppose your run time configuration file is called /usr/exim/configure, and + you want to continue with this name after upgrading. The first thing to do + is to make another copy of this file called, say, /usr/exim/configure.r3. + +2. Rebuild your existing Exim to use the copy of the run time configuration + file instead of the standard file. Install this version of Exim and HUP your + daemon. You can check on the name of the configuration file by running + + exim -bP configure_file + + Ensure that everything is running smoothly. You now have something you can + fall back to. IMPORTANT: when you do this re-install, you should also + re-install the utilities because four of them (exicyclog, eximon, exinext, + and exiwhat) also refer to the configuration file. + +3. Build the new release, configured to use the standard configuration file. + +4. Use the convert4r4 utility to upgrade your configuration file for the new + release. After running the conversion utility, check the file by hand, and + tidy it up. + +5. Test, test, test! And test some more! + +6. You can run complete tests, including actual deliveries, from an uninstalled + binary, but you have to tell it where it is, so that any re-executions can + be done. You can do this by temporarily inserting a setting such as + + exim_path = /source/exim/exim-4.00/build-SunOS5-5.8-sparc/exim + + into the run time configuration. If you want to, you can also insert + settings for spool_directory and log_file_path to divert those away from + their normal places. Remember to remove these temporary settings when you + eventually install the binary for real. + +7. The new installation script installs the new release as exim-4.00-1, and + set a symbolic link called "exim" to point to it. The old version of Exim + will be renamed to something like exim-3.33-1. + +8. You can now easily change between the new and old releases simply by moving + the symbolic link and HUPping your daemon. The format of message files on + Exim's spool has _not_ changed, so there should be no problem in changing + between releases while there are messages on the queue. + +9. HOWEVER: If you do change back and forth between releases, you must also + change the utilities exicyclog, eximon, exinext, and exiwhat if you are + going to use them. Installing Exim 4 will have left the old versions with a + .O suffix. It might be helpful to rename these so that you don't lose them. + + +WHAT HAS NOT CHANGED IN EXIM 4.00 +--------------------------------- + +The basic overall philosophy, design, and process structure has not changed. +The format of spool files is the same. The transports have had only minor +modifications. The command line options remain the same, with a couple of +additions. + +The general run time configuration approach has not changed, but the actual +details of the configuration file are different. + +The Exim monitor has not changed, and there have been only very minor changes +to other Exim utilities. + + +WHAT HAS CHANGED IN EXIM 4.00 +----------------------------- + +The rest of this document lists the very many changes that have taken place. +I'm going to give only brief details here, because this part of the document is +intended as a way of alerting you to areas of difference. The reference manual +describes how the new features work in detail. + + +Named domain, host, address, and local part lists +------------------------------------------------- + +A new feature makes it possible to give names to lists of domains, hosts, +addresses, and local parts. The syntax used is + + domainlist <name> = <a domain list> + hostlist <name> = <a host list> + addresslist <name> = <an address list> + localpartlist <name> = <a list of local parts> + +For example: + + domainlist local_domains = *.my.domain + addresslist bad_senders = cdb;/etc/badsenders + +These lists are referenced in options by giving the name preceded by a + sign. +For example, in a router you might have + + domains = +local_domains + +At first sight, these lists might seem to be the same as macros, but they are +not. Macros are just textual substitutions. If you write + + ALIST = host1 : host2 + auth_advertise_hosts = !ALIST + +it probably won't do what you want, because that is exactly the same as + + auth_advertise_hosts = !host1 : host2 + +Notice that the second host name is not negated. However, if you use a host +list, and write + + hostlist alist = host1 : host2 + auth_advertise_hosts = ! +alist + +the negation applies to the whole list, and so that is equivalent to + + auth_advertise_hosts = !host1 : !host2 + +These named lists also have a performance advantage. When Exim is routing an +address or checking an incoming message, it caches the result of tests on the +lists. So, if you have a setting such as + + domains = +local_domains + +on several of your routers, the actual test is done only for the first one. +However, this caching works only if there are no expansions within the list +itself or any sublists that it references. In other words, caching happens only +if the list is known to be the same each time it is referenced. + +By default, there may be up to 16 named lists of each type. This limit can be +extended by changing a compile-time variable. + +The use of domain and host lists is recommended for concepts such as local +domains, relay domains, and relay hosts. The default configuration is set up +like this. + + +Processing of domain, host, local part, and address lists +--------------------------------------------------------- + +The handling of these lists is now more uniform. Every list is expanded as a +single string before it is used. (In Exim 3, some options were expanded and +some weren't, and query-style lookup items were then re-expanded.) + +If an expansion is forced to fail, Exim behaves as if the item has not been +found in the list. + +The confusing $key variable has been abolished. When processing a domain list, +$domain contains the relevant domain and can be used in generating database +queries. Other appropriate variables are set when processing other kinds of +list; $sender_host and $sender_host_address for checking incoming hosts and +$host and $host_address for checking outgoing hosts. + +Note that this means that any \ and $ characters in regular expressions must be +escaped if they appear in one of these lists. The new expansion feature to turn +off expansion (\N ... \N) which is described below can be helpful here. + +IMPORTANT: The details of the processing of address lists has been revised. In +particular, the handling of the case of an item that is a single-key lookup has +changed. It no longer looks up the domain on its own before looking up the +complete address. You need to supply an explicit "*@" before the lookup if you +want just the domain to be looked up. Please check the manual for full details. + +If an item in a host list is the empty string, it matches only when no host is +defined. If used when checking an incoming message, it matches only when the +message is arriving by SMTP on the standard input from a local process (using +-bs). This provides a way of distinguishing between SMTP mail from local +processes and from remote hosts. + +The +allow_unknown and +warn_unknown settings for host lists have been replaced +by a single item, +include_unknown. By default, failure to find a host name +when needed causes Exim to behave as if the host does not match the list, but +if +include_unknown is set, the opposite behaviour happens. Whenever ++include_unknown is invoked, the incident is logged. + + +Merge of Directors and Routers +------------------------------ + +There are no longer any directors in Exim 4. There are just routers. All +addresses are passed to a single list of routers which typically makes use of +the "domains" option to choose which way to handle specific groups of domains. + +A consequence of this is that the code no longer contains any concept of "local +domains". However, a typical configuration will probably define a named domain +list (see above) called local_domains, and use it to control routing something +like this: + + route_remote: + driver = dnslookup + domains = ! +local_domains + transport = remote_smtp + no_more + + system_aliases: + .... + +The first router does DNS routing for all domains that are not in the named +list of local domains, and no_more ensures that it is the last router for those +domains. All other domains fall through to the system_aliases and subsequent +routers. For a complete configuration example, look at the default +configuration file in src/configure.default. + + +Router Actions +-------------- + +The concept of how the routers work is as follows: + +A number of pre-conditions are tested (details below). If any of them fails, +control is passed to the next router. We say "the router is skipped". Otherwise +the router is run, and can yield one of several different results: + +. accept: The router accepts the address, and either queues it for a transport, +or generates one or more "child" addresses. Processing the original address +ceases, unless "unseen" is set on the router, in which case the address is +passed to the next router. Processing of any child addresses starts with the +first router by default, or at the router defined by redirect_router if it is +set. This may be any router in the list. + +. decline: The router declines to accept the address because it does not +recognize it at all. The address is passed to the next router, unless no_more +is set, in which case the address fails. + +. pass: The router recognizes the address, but cannot handle it itself. It +requests that the address be passed to another router. This overrides no_more. +By default the address is passed to the next router, but this can be changed by +setting pass_router. However, in this case (unlike redirect_router) the named +router must be below the current router (to avoid loops). + +. fail: The router determines that the address should fail, and queues it for +the generation of a bounce message. There is no further processing of the +original address, unless "unseen" is set. + +. defer: The router cannot handle the address at the present time. (For +example, a database may be offline.) No further processing of the address +happens in this delivery attempt. It is tried again next time. + +. error: There is some error in the router (for example, a syntax error in +its configuration). The action is as for defer. + + +Router pre-conditions +--------------------- + +In Exim 3 there are some strange interactions between the generic options that +test things before running a director or router and the no_more test that +happens afterwards. + +In Exim 4 it is all more straightforward. If any of the pre-condition tests +fail, the router is skipped and control passes to the next router. The no_more +option has an effect only if the router is actually run - that is, if all the +pre-condition tests succeed. The order in which these tests are run is: + + verify status, expn status, domains, local_parts, check_local_user + +If all those match, the debug_print string is output when debugging. Exim then +goes on to test + + senders, require_files, condition + +Note that require_files comes near the end of the list, so you cannot use it to +check for the existence of a file in which to lookup up a domain, local part, +or sender. However, as these options are all expanded, you can use the "exists" +expansion condition to make such tests. The require_files option is intended +for checking files that the router may be going to use internally, or which are +needed by a specific transport (e.g. .procmailrc). + +In Exim 4, local part prefixes and suffixes are recognized and removed before +any of the other pre-condition tests are done (in Exim 3 they were removed +afterwards). Note that this means that the local_parts option now tests the +local part without its prefix or suffix. + +If you want to use local parts that include any affixes in a pre-condition +test, you can do so by using a "condition" option that uses the variables +$local_part, $local_part_prefix, and $local_part_suffix as necessary. + + +A New Set of Routers +-------------------- + +The two sets of routers and directors of Exim 3 have been replaced by a single +set of routers for Exim 4. These are as follows: + +. accept Always accepts an address. It has no private options. + +. dnslookup Routes by DNS lookup (descended from lookuphost). + +. ipliteral Routes IP literal addresses (unchanged). + +. iplookup Special-purpose lookup router (unchanged). + +. manualroute Routes domains from explicit data (descended from domainlist). + +. queryprogram Routes addresses by running a program (detail changed). + +. redirect Redirects addresses; handles all the functions previously + supported by aliasfile, forwardfile, and smartuser without + a transport. + + +Saving duplication of effort while routing +------------------------------------------ + +Early versions of Exim used to copy the routing of one address for all other +addresses in the same domain, thereby possibly saving some repeated DNS +lookups. This feature was removed for release 2.12, after the possibility of +varying the router actions according to the local part (the local_parts option) +was added. (In fact, the use of $local_part could have broken it earlier.) + +For Exim 4, I have added an option called same_domain_copy_routing to the +dnslookup and manualroute routers. When one of these routers routes an address +to a remote transport and this option is set, any other addresses in the +message that have the same domain are automatically given the same routing, but +only if the router does not set headers_add or headers_remove, and does not +`widen' the domain during the routing. + + +Generic Router Options +---------------------- + +. The global locally_caseless option is replaced by a generic router option + called caseful_local_part. By default, routers handle local parts caselessly. + +. check_local_user is now a generic option that is needed to check for a local + account. Typically used on redirect (for user's forward files) and on accept + (for local deliveries). + +. The setting self=local has been removed (since there's no concept of local + domains in the code). The same kind of effect can be achieved by using + self=reroute or self=pass. + +. expn is now a generic router option. + +. local_part_prefix and local_part_suffix are now generic router options, + replacing prefix and suffix on directors. + +. Exim 3 has two logging styles for delivery, depending on whether the domain + is a local domain or not. For local domains, the address is given just as the + local part - this makes these deliveries easier to spot in the log. In Exim 4 + there's no concept of local domains, so this functionality cannot be + automatic. Instead, there's a generic router option called log_as_local which + requests "local-style" logging. This option defaults on for the "accept" + router, and off for all the others. + +. There's an option called retry_use_local_part which is the default for any + router that has check_local_user set, and it applies to routing delays. (The + same option for transports applies to transport delays.) + +. transport_home_directory and transport_current_directory are new generic + options on all routers. They set up default values for home_directory and + current_directory on the transport to which they route an address. Any + settings in the transport override. + +. If transport_home_directory is not set, but check_local_user is set, the + user's home directory is used as a default value. + +. The special fudge that exists in Exim 3 for handling home_directory settings + in forwardfile directors is not needed in Exim 4. It has therefore been + removed. + +. The new_director option in Exim 3 allows the direction of redirected + addresses to start at a given director, instead of the first one. In Exim 4, + this option is now called redirect_router. The option is used when a redirect + router succeeds, and when a queryprogram router returns a "redirect" + response. + +. There is a new option called pass_router, which specifies the router to go to + when a router "passes" on an address. The named router must follow the + current router (to avoid routing loops). Note: if a router declines, control + always passes to the next router, unless no_more is set. + +. There is a new router option called address_data. This is set to a string + which is expanded just before the router is run, that is, after all the + pre-tests have succeeded. If the expansion is forced to fail, the router + declines. Other expansion failures cause delivery of the address to be + deferred. + + When the expansion succeeds, the value is retained with the address, and can + be accessed using the variable $address_data. Even if the router declines or + passes, the value remains with the address, though it can be changed by + another address_data setting on a subsequent router. If a router generates + child addresses, the value of $address_data propagates to them. + + The idea of address_data is that you can use it to look up a lot of data for + the address once, then then pick out parts of the data later. For example, + you could use an LDAP lookup to return a string of the form + + uid=1234 gid=5678 mailbox=/mail/xyz forward=/home/xyz/.forward + + In the transport you could then pick out the mailbox by a setting such as + + file = ${extract{mailbox}{$address_data}} + + This makes the configuration file less messy, and also reduces the number of + lookups. (Exim does cache the most recent lookup, but there may be several + addresses with different lookups.) + +. When a transport is run for several addresses simultaneously, the values of + $address_data, $local_part_data, and $domain_data are taken from the first + address that the transport handles. However, the order in which multiple + addresses are processed is not defined. You therefore need to be careful if + you want to use these variables with multiple addresses. The smtp transport + is the only one which by default handles multiple addresses. + +. When an address is routed by a router with the "unseen" option set, a "clone" + address is created, and it starts being routed at the next router. (This is + what people expect. In Exim 3 it starts at the top - in simple cases that has + the same effect because of the anti-looping rule, but if aliases are involved + it sometimes doesn't do what you want.) + +. The way that require_files works has been changed. Each item in the list is + now separately expanded as the test proceeds. The use of leading ! and + + characters is unchanged. However, user and group checking is done differently. + Previously, seteuid() was used, but seteuid() is no longer used (see + "Security" below) for checking the files required by this option. Instead, + Exim now scans along the components of the file path and checks the access + for the given uid and gid. It expects "x" access on directories and "r" on + the final file. This means that file access control lists (on those + operating systems that have them) are ignored. + + +Other Consequences of the Director/Router Merge +----------------------------------------------- + +. The -odqr option is abolished, as there is no inbuilt concept of remote + domains. + +. The -odqs option is equivalent to queue_smtp_domains = *. + +. queue_remote_domains is renamed queue_domains, and applies to any domain. + +. The -ql option now suppresses remote delivery; routing always happens. + +. The "remote" facility of queue_only_file has been removed. + +. The match_directory option for forwardfile and localuser has been entirely + abolished. Its function can be achieved using the "condition" option in + conjunction with check_local_user. + +. When an address is being verified, if it is redirected to a single new + address, verification continues with that address. If it is redirected to + more than one address, verification ceases with a success result. (In Exim 3, + this applied only to aliasing, not to forwarding.) + + +The dnslookup router +-------------------- + +This router replaces the lookuphost router of Exim 3. It is much the same, +except that the "gethostbyname" option has been removed. It now does only DNS +routing - hence the change of name. Routing using gethostbyname() can be done +by the manualroute router. + + +The manualroute router +---------------------- + +This is the new name for the domainlist router, supposedly to make its function +clearer and to avoid confusion with the "domainlist" that is used to set up +named domain lists. Several things have been removed and reorganized. + +. The old search mechanism (route_file, route_query, route_queries, + search_type) have been removed. Instead there is a new option called + route_data, which is an expanded string. It should expand to a single routing + entry. If the expansion ends up empty (or is forced to fail), the router + declines. The route_list option still exists, for convenient listing of a few + inline routes. + +. There is no longer any MX processing function in this router. The keywords + bydns_mx and bydns_a have been removed, leaving just + + bydns => find IP addresses from address records in the DNS + byname => find IP addresses by calling gethostbyname() + + The default lookup type is "byname", and this can be omitted from a route + data line. If an IP address is given, both "byname" and "bydns" are ignored + (so typically you omit this field). + +. The qualify_single and search_parents options have also been removed. + +. A transport is always required to be set, unless verify_only is set. + +. The host_find_failed option can be set to "decline", to cause the router to + decline if it can't find an IP address for a listed host. + +. If manualroute routes to a local transport, there is no need to specify + byname or bydns in the routing data. Any supplied host list is passed as a + string in $host, but $host_address is unset. + + +The queryprogram router +----------------------- + +This router has been re-designed: + +. You must now specify a user and group for the program to be run using + command_user and (if necessary) command_group. It no longer defaults to + "nobody". These options are expanded. + +. The command is now split up and each argument expanded separately, as happens + for the pipe transport. The command name is also expanded. + +. The return value "forcefail" has been renamed "fail", and it causes delivery + to fail. (The original usage of "fail" meaning "decline" has finally been + removed.) + +. The $route_option variable, which queryprogram used to be able to set has + been abolished. A facility to set the new $address_data variable replaces it. + +. The string returned from queryprogram must now be one of: + + DECLINE + FAIL text + DEFER text + PASS + FREEZE text + REDIRECT text + ACCEPT TRANSPORT=transport HOSTS=host list LOOKUP=byname|bydns DATA=text + +The text returned for "redirect" is a list of new addresses. The text for FAIL +is returned in the SMTP dialogue when the router is run as part of address +verification. It is also logged. The text for DEFER and FREEZE is just logged. + +The data items in the "accept" return can be given in any order, and all are +optional. If no transport is included in the "accept" return, the router's +default transport is used. The host list and lookup type are needed only if the +transport is an smtp transport that does not itself have a host list. The +default lookup type is "byname". If the "data" field is set, its value is +placed in the $address_data variable. + + +The redirect router +------------------- + +This router replaces forwardfile, appendfile, and the use of smartuser without +a transport. It has two mutually exclusive options for specifying the data that +it uses. If "file" is set, the data is taken from a file. Otherwise "data" must +be set, and the data is the expanded value of that option. + +The data may be an alias list, possibly including special entries such as +:fail:, or it may be a list of filtering instructions. + +If "file" is set, but the file does not exist or is empty, or its contents have +no effect (entirely comments, or a filter that does nothing), the router +declines. This also happens if the expansion of "file" is forced to fail. Any +other expansion failure causes the router to defer. + +Ownership of the file is checked if check_local_user is set or if owners is +set, unless check_owner is explicitly set false. + +Likewise, the group is checked if owngroups is set, or if check_local_user is +set and a modemask not containing 020 is set, unless check_group is explicitly +set false. + +If "data" is set, a forced expansion causes the router to decline. This also +happens if "data" is an empty string or a string that causes nothing to be +generated and no action to be taken. + +Because "data" is now used for traditional /etc/aliases lookups, an empty alias +no longer gives an error. It behaves in the same way as :unknown: (which is +still recognized, but ignored). + +. If no_repeat_use is set, the router is skipped if _any_ ancestor of the + current address was routed by this router. This pre-test happens before any + of the others. (Contrast the default loop avoidance logic, which skips a + router if an ancestor with the same local part was routed by the router.) + +. If include_directory is set, :include: files are constrained to this + directory. + +. When an address is redirected to a file or a pipe, $address_file or + $address_pipe (as appropriate) is set when expanding the value of + file_transport or directory_transport. + +. There are new options forbid_filter_readfile and forbid_filter_run to lock + out the use of the new ${readfile and ${run expansion items in filters. + +. If one_time is set, forbid_pipe, forbid_file, and forbid_filter_reply are + forced to be true, and headers_add and headers_remove are forbidden. + + +Generic transport options +------------------------- + +. All remote deliveries are now done in subprocesses running with specified + UIDs and GIDs. (Formerly, only remote parallel deliveries were done in + subprocesses.) As a result, user and group are now generic options that can + be used on all transports. The default for both local and remote transports + is to run as the Exim user and group. For remote transports, this should not + normally be changed, but if it is, the user or group should be able to access + the hints databases, though failure to open a hints database is always + ignored. + + If it turns out that a transport user is in the never_users list, Exim now + defers delivery and writes to the panic log. (Previously it just ran the + delivery as "nobody".) Because subprocesses (usually running as "exim") + are now always used for remote deliveries, you should *not* include "exim" in + the never_users list. + +. initgroups is now also a generic transport option. + +. home_directory and current_directory are generic options on all transports, + though some transports (e.g. smtp) make no use of them. If they are unset, + values supplied by the router are used. + +. The message_size_limit option is now expanded, which makes it possible to + have different limits for different hosts, for example. + + +Multiple (batch) deliveries in the appendfile, lmtp, and pipe transports +------------------------------------------------------------------------ + +The options controlling batch deliveries, including BSMTP, were a mess, and +have been reworked. + +. The batch option has been removed from all three transports, and the bsmtp + and bsmtp_helo options have been removed from appendfile and pipe. + +. The batch_max option defaults to 1 in all three transports. + +. A new option called use_bsmtp has been added to appendfile and pipe. When + set, the message is delivered in BSMTP format. If you want to have a HELO + line at the start of the message, you can configure this by making use of the + message_prefix option. You must include the terminating newline. + +. A new option called batch_id has been added to all three transports. + +Batching is now achieved by setting batch_max to a value greater than 1. This +is recommended for lmtp. When multiple addresses are routed to the same +transport that has a batch_max value greater than one, the addresses are +delivered in a batch, subject to certain conditions: + +. If any of the transport's options contain a reference to "$local_part", no + batching is possible. + +. If any of the transport's options contain a reference to "$domain", only + addresses with the same domain are batched. + +. If batch_id is set, it is expanded for each address, and only those addresses + with the same expanded value are batched. + +. Batched addresses must also have the same errors address (where to send + delivery errors), the same header additions and removals, the same user and + group for the transport, and if a host list is present, the first host must + be the same. + + +The appendfile transport +------------------------ + +. The prefix and suffix options have been renamed message_prefix and + message_suffix to avoid confusion with address affixes. The default values, + which are suitable for mbox deliveries, now apply only if "file" is set and + use_bsmtp is not set. Otherwise, the default values for these options are + unset. They can, of course, always be overridden. + +. If "directory" is set (which means that "file" is not set), the check_string + and escape_string options now default unset. + +. The require_lockfile options has been abolished. If use_lockfile is set, a + lock file is always required. + +. The quota_filecount option is now expanded. + +. The create_file option now also applies when delivering into an individual + file in a given directory, as well as when appending to a single file. In the + case of maildir delivery, the restriction applies to the top directory of the + maildir folder. + +. There's a new option called directory_file which is expanded to form the + final leaf name of files when "directory" is set, but neither maildir nor + mailstore is set. The default is "q${base62:$tod_epoch}-$inode", which + reproduces the old fixed value. The variable $inode is available only when + expanding this new option. + + +The pipe transport +------------------ + +. The prefix and suffix options have been renamed message_prefix and + message_suffix to avoid confusion with address affixes. The default values + that are suitable for vacation deliveries now apply only if use_bsmtp is not + set. Otherwise the default values for these options are unset. They can, of + course, always be overridden. + + +The smtp transport +------------------ + +. The badly-named batch_max option is now called connection_max_messages. + +. If hosts_randomize is set, it now affects host lists that come from a router + as well as the contents of the "hosts" option, but only if the hosts were not + obtained from MX records. Typically, such lists come from the manualroute + router. This change means that the router can provide the same host list for + multiple addresses - causing them all to be sent to the transport at once. + Randomizing is then done each time the transport is called. (If you set + hosts_randomize on the router, the randomizing happens for each address.) + +. The way that smtp operates when there are multiple addresses to be sent to + the same host is now different. Previously, the transport was called many + times, with a maximum of max_rcpt addresses per call. Each call made a new + connection to the host. When remote_max_parallel = 1, all the addresses are + now passed to the transport at once. It makes a single TCP/IP call, but may + send multiple copies of the message, each with no more than max_rcpt + recipients. + + When remote_max_parallel is greater than 1, a heuristic is used. The number + of addresses passed to a single call of the transport is limited to + + (the total number of recipients) / (the value of remote_max_parallel) + + so, for example, if there are 100 recipients and remote_max_parallel is 2, no + more than 50 are passed in one call, even if max_rcpt is 100. (The idea is + that the other 50 will be passed to another call running in parallel.) + + There is an option of the smtp transport called connection_max_messages + which limits the number of messages, or copies of a message, that Exim sends + down a single TCP/IP connection. This applies both to this mechanism for + multiple copies of a single message, and the re-use of a TCP/IP connection + for sending other messages destined for the same host, after a delivery + delay. The default value is 500. + +. The "interface" option is now expanded. If the result is a forced failure or + an empty string, it is ignored. Otherwise, the result must be a list of IP + addresses. The first one of the correct type (IPv4 or IPv6) for the outgoing + connection is used. If there isn't one of the correct type, the option is + ignored. + +. At the start of running the transport, the value of $host is taken from the + first host in a multi-host list. However, just before the transport connects + to a host, the value is changed to refer to that particular host. (This + applies to $host_address as well.) This means that options such as helo_data + and the tls_options can be made host-specific. + +. The tls_verify_ciphers option has been renamed tls_require_ciphers, in order + to leave the word "verify" as something that refers to the verification of + certificates. + +. The resolution of hosts and fallback_hosts used to look up MX records. This + was some kind of ancient silliness that I recently noticed. These are + definitely hosts, not mail domains. Exim 4 just looks up address records. + As a consequence of this, the mx_domains option of the smtp transport is + removed. + +. The authenticate_hosts option has been renamed as hosts_try_auth. A new + option called hosts_require_auth has been added; if authentication fails for + one of these hosts, Exim does _not_ try to send unauthenticated. It defers + instead. The deferral error is detectable in the retry rules, so this can be + turned into a hard failure if required. + + +The System Filter +----------------- + +. The system filter options that were called message_filter_xxx have all been + renamed as system_filter_xxx. + +. The value of system_filter is expanded. + +. message_filter_directory_transport and message_filter_file_transport are now + both expanded before use. If the filter set up any file or pipe deliveries, + $address_file and $address_pipe are set as appropriate while doing the + expansions. + +. message_filter_directory2_transport has been removed. The effect of using + different directory-style transports can be achieved by specifying a suitable + expansion string to system_filter_directory_transport. + +. When a system filter added recipients to a message, Exim 3 added an + X-Envelope-To: header, listing the real recipients (up to 100). This has been + abolished because you can do this kind of thing using "headers_add" nowadays. + +. The "fail" command has been extended to allow for two different messages, one + for Exim's log and the other to be returned to the sender. The syntax is + + fail "<<log message>>user message" + + That is, if the first two characters of the message are "<<" the following + text, up to ">>", is written to the log, and the remainder is returned to the + user. If there is no log message, the user message is logged. The motivation + for this feature was to reduce the amount of text logged, while being able to + send quite long (maybe even multi-line) messages back to the sender. + + +Changes to Lookups +------------------ + +. Oracle support is available. It works like the mysql and pgsql support, + except that there is no "database name" involved, and the "host name" field + is used for what is called "service name" in Oracle. This often looks like a + host name. Also, semicolons are not used at the end of an SQL query for + Oracle. + +. There's a new single-key lookup type called dsearch. It searches a directory + for a file whose name matches the key. The result of a successful search is + the key. One possible use of this could be for recognizing virtual domains. + If each domain is represented by a file whose name is the domain name, you + needn't make a separate list of the domains. You could test for them in an + ACL (see below), for example, by a line like this + + accept domains = dsearch;/etc/virtual/domains + +. The format of LDAP output has been changed for cases where multiple + attributes are requested. The data for each attribute is now always quoted. + Within the quotes, the quote character, backslash, and newline are escaped + with backslashes and commas are used to separate multiple values for the + attribute. Thus, the string in quotes takes the same form as the output when + a single attribute is requested. If multiple entries are found, their data is + still separated by a newline. + +. There's a new expansion condition called ldapauth which exists so that the + LDAP authentication mechanism can be used for user authentication. It is + described under "string expansion" below. + +. Exim now supports ldaps:// URLs as well as ldap:// URLs. The former do LDAP + over TLS (i.e. encrypted) connections. + +. There is now support for the "whoson" mechanism for doing "POP-before-SMTP" + authentication. This is provided by new query-style lookup type called + "whoson", with queries that consist of IP addresses. For example, in an ACL + you can write + + require condition = ${lookup whoson {$sender_host_address}{yes}{no}} + + +Special items in domain and host lists +-------------------------------------- + +. In a domain list, the special item @ matches the primary host name, and the + special item @[] matches any local interface address enclosed in square + brackets (as in domain literal email addresses). The special item @mx_any + matches any domain that has an MX record pointing to the local host. The + special items @mx_primary and @mx_secondary are similar, except that the + first matches only when the primary MX is to the local host, and the second + only when the primary MX is not the local host, but a secondary MX is. + +. In a host list, the special item @ matches the primary host name, and the + special item @[] matches any local interface address (not in brackets). + + +Access Control Lists (ACLs) +--------------------------- + +All the policy control options for incoming messages have been replaced by +Access Control Lists (ACLs). These give more flexibility to the sysadmin, and +allow the order of testing to be specified. For example, using an ACL, it is +possible to specify "accept if authenticated, even if from an RBL host, but +otherwise deny if from an RBL host", which is not possible in Exim 3. + +ACLs are defined in a new part of the configuration file, and given names. +Which ones to run are controlled by a new set of options that are placed in the +main part of the configuration. + + acl_smtp_auth specifies the ACL to run when AUTH is received + acl_smtp_data specifies the ACL to run after a message has been received + acl_smtp_etrn specifies the ACL to run when ETRN is received + acl_smtp_expn specifies the ACL to run when EXPN is received + acl_smtp_rcpt specifies the ACL to run when RCPT is received + acl_smtp_vrfy specifies the ACL to run when VRFY is received + +The default actions vary. If acl_smtp_auth is not defined, AUTH is always +accepted (and an attempt is made to authenticate the session). If acl_smtp_data +is not defined, no checks are done after a message has been received, and it is +always accepted at that point. + +However, if any of the others are not defined, the relevant SMTP command is +rejected. In particular, this means that acl_smtp_rcpt must be defined in order +to receive any messages over an SMTP connection. The default configuration file +contains a suitable default for this. + +ACLs can be provided in line, or in files, or looked up from databases. One ACL +can call another in a subroutine-like manner. String expansion is used, and +which ACL to run can be varied according to sender host or any other criterion +that a string expansion can test. + +This is not the place to give a full specification of ACLs, but here is a +typical example for checking RCPT commands, taken from the default +configuration. The tests are performed in order. + +acl_check_rcpt: + # Accept if source is local SMTP (i.e. not over TCP/IP - undefined host) + accept hosts = : + + # Deny if the local part contains @ or % or / + deny local_parts = ^.*[@%/] + + # Accept mail to postmaster in any local domain, regardless of the source, + # and without verifying the sender. + accept domains = +local_domains + local_parts = postmaster + + # Deny unless the sender address can be verified. + require verify = sender + + # Accept if the address is in a local domain, but only if the recipient can + # be verified. Otherwise deny. The "endpass" line is the border between + # passing on to the next ACL statement (if tests above it fail) or denying + # access (if tests below it fail). + accept domains = +local_domains + endpass + message = unknown user + verify = recipient + + # We get here only for non-local domains. Accept if the message arrived over + # an authenticated connection, from any host. These messages are usually from + # MUAs, so recipient verification is omitted. + accept authenticated = * + + # Reaching the end of the ACL causes a "deny", but we might as well give + # an explicit message. + deny message = relay not permitted + +The following options have been abolished as a consequence of the introduction +of ACLs: + +auth_hosts, auth_over_tls_hosts, headers_checks_fail, headers_check_syntax, +headers_sender_verify, headers_sender_verify_errmsg, host_accept_relay, +host_auth_accept_relay, host_reject_recipients, prohibition_message, +rbl_domains, rbl_hosts, rbl_log_headers, rbl_log_rcpt_count, +rbl_reject_recipients, rbl_warn_header, receiver_try_verify, receiver_verify, +receiver_verify_addresses, receiver_verify_hosts, receiver_verify_senders, +recipients_reject_except, recipients_reject_except_senders, relay_domains, +relay_domains_include_local_mx, relay_match_host_or_sender, +sender_address_relay, sender_address_relay_hosts, sender_reject, +sender_reject_recipients, sender_try_verify, sender_verify, +sender_verify_batch, sender_verify_hosts, sender_verify_fixup, +sender_verify_hosts_callback, sender_verify_callback_domains, +sender_verify_callback_timeout, sender_verify_max_retry_rate, +sender_verify_reject, smtp_etrn_hosts, smtp_expn_hosts. smtp_verify, tls_hosts. + +The variable $prohibition_reason has been abolished. + +The host_reject option has been retained, but with its name changed to +host_reject_connection, to emphasize that it causes a rejection at connection +time. I've left it available just in case it is needed - but its use is not +recommended in normal circumstances. + + +Other Incoming SMTP Session Controls +------------------------------------ + +. The option smtp_accept_max_per_connection (default 1000) limits the number of + messages accepted over a single SMTP connection. This is a safety catch in + case some sender goes mad (incidents of this kind have been seen). After the + limit is reached, a 421 response is given to MAIL commands. + +. Some sites find it helpful to be able to limit the rate at which certain + hosts can send them messages, and the rate at which an individual message can + specify recipients. There are now options for controlling these two different + rates. + + Rate limiting applies only to those hosts that match smtp_ratelimit_hosts, + whose value is a host list. When a host matches, one or both of the options + smtp_ratelimit_mail and smtp_ratelimit_rcpt may be set. They apply to the + rate of acceptance of MAIL and RCPT commands in a single SMTP session, + respectively. + + The value of each option is a set of four comma-separated values: + + 1. A threshold, before which there is no rate limiting. + 2. An initial time delay. Unlike other times in Exim, fractions are allowed + here. + 3. A factor by which to increase the delay each time. + 4. A maximum value for the delay. + + For example, these settings have been used successfully at the site which + first suggested this feature, for controlling mail from their customers: + + smtp_ratelimit_mail = 2, 0.5s, 1.05, 4m + smtp_ratelimit_rcpt = 4, 0.25s, 1.015, 4m + +. The default value for smtp_connect_backlog has been increased to 20. + +. The SMTP protocol specification requires the client to wait for a response + from the server at certain points in the dialogue. (Without PIPELINING these + are after every command; with PIPELINING they are fewer, but still exist.) + Some spamming sites send out a complete set of SMTP commands without waiting + for any response. Exim 4 protects against this by rejecting messages if the + client has sent further input when it should not have. The error response + "554 SMTP synchronization error" is sent, and the connection is dropped. + + This check is controlled by smtp_enforce_sync, which is true by default. + +. helo_strict_syntax has been abolished. The default is now to enforce strict + domain syntax for HELO/EHLO arguments. You can use helo_accept_junk_hosts if + you want to avoid this. + +. There's a new option called helo_lookup_domains. If the domain given in a + HELO or EHLO command matches this list, a reverse lookup is done in order to + establish the host's true name. The default setting is + + helo_lookup_domains = @ : @[] + + That is, a lookup is forced if the client host gives the server's name or + [one of its IP addresses] in HELO or EHLO. (In Exim 3 this happened + automatically and was not configurable.) + +. The value of the global message_size_limit option is now expanded. For + locally submitted messages this happens at the start of message reception. + For messages from remote hosts, the expansion is done just after the host + connects, so that the value can depend on the host. + + +Handling of Resent- Fields +-------------------------- + +RFC 2822 makes it clear that Resent- fields are purely informational. Exim used +to make use of Resent-Reply-To: which does not actually exist, and it also used +to use the last set of resent- fields for all the address fields it recognized. + +In Exim 4, resent- headers are dealt with as follows: + +. A Resent-From: header that just contains the login id as the address is + automatically rewritten in the same way as From: is (using qualify domain, + and user name from the passwd data). + +. If there's a rewrite rule for a header, it is also applied to resent- headers + of the same type. For example, a rule that rewrites From: headers also + rewrites Resent-From: headers. + +. For local messages, if Sender: is being removed on input, Resent-Sender: is + also removed. + +. If there are any resent- headers but no Resent-Date: or Resent-From: they are + added. + +. The logic for adding Sender: is now duplicated for Resent-Sender. + +. If there's no Resent-Message-Id: one is created, and it is the + Resent-Message-Id: which is included in the log line. + + +Authentication +-------------- + +. The auth_hosts option has been abolished; this functionality is now + controlled by ACLs. + +. The auth_always_advertise option has been abolished because it depended on + auth_hosts and host_auth_accept_relay, both of which are no more. In its + place there is a new option called auth_advertise_hosts, whose default value + is *, meaning "advertise AUTH to all". + +. The value of server_setid is now used when logging failed authentication + attempts. + +. The -oMaa option allows trusted users to set the value of + $sender_host_authenticated (the authenticator name). This is normally used in + conjunction with -oMa. + + +Encryption +---------- + +. Because tls_hosts is no more, tls_advertise_hosts is now the only means of + controlling the advertisement of STARTTLS (previously, tls_hosts overrode). + +. The global option tls_verify_ciphers has been abolished. There are now + facilities for checking which cipher is in use in ACLs. + +. There's a new option called tls_try_verify_hosts. Like tls_verify_hosts, this + causes the server to request a certificate from a client, and it verifies the + certificate that it receives. However, unlike tls_verify_hosts, Exim + continues with the SMTP connection (encrypted) if a client certificate is not + received, or if the certificate does not verify. This state can be detected + in an ACL, which makes it possible to implement policies such as "accept for + relay only if a verified certificate has been received but accept for local + delivery if encrypted, even without a verified certificate". + + A match in tls_verify_hosts overrides tls_try_verify_hosts. + + +The Daemon +---------- + +. local_interfaces can now specify a port number with each address, thus + allowing a single Exim daemon to listen on multiple ports. The format of each + address is either [aaaa]:ppp or aaaa.ppp where aaaa is an IP address and ppp + is a port number. For example: + + local_interfaces = 192.168.3.4.25 : 192.168.3.4.26 + + If an address is listed without a port, the setting of daemon_smtp_port, or + the value of the -oX option, is the default. + +. The -oX option can now override local_interfaces. That is, it can supply IP + addresses as well as just a port. It is interpreted in this way if its value + contains any of the characters . : or []. For example: + + exim -bd -oX 10.9.8.7:10.11.12.13.2525 + + The format of the string is identical to the format recognized by the + local_interfaces option. + +. The way the daemon wrote PID files was overly complicated and messy. It no + longer tries to be clever. A PID file is written if, and only if, -bd is used + and -oX is _not_ used. In other words, only if the daemon is started with its + standard options. There is only one PID file. If pid_file_path is unset, it + is exim-daemon.pid in Exim's spool directory. Otherwise the value of + pid_file_path is used. For backwards compatibility, "%s" in this value is + replaced by an empty string. + + +Logging +------- + +The log_level option and all the various independent logging control options +have been abolished. In their place there is a single option called +log_selector. It takes a string argument composed of names preceded by + or - +characters. These turn on or off the logging of different things. For example: + + log_selector = +arguments -retry_defer + +The optional logging items (defaults marked *) are: + + address_rewrite address rewriting + all_parents all parents in => lines + arguments exim arguments + *connection_reject connection rejections + *delay_delivery immediate delivery delayed (message queued) + delivery_size add S=nnn to delivery lines + *dnslist_defer defers of DNS list (aka RBL) lookups + incoming_interface incoming interface on <= lines + incoming_port incoming port on <= lines + *lost_incoming_connection as it says (includes timeouts) + *queue_run start and end queue runs + received_sender sender on <= lines + received_recipients recipients on <= lines + *retry_defer "retry time not reached" + sender_on_delivery add sender to => lines + *size_reject rejection because too big + *skip_delivery "message is frozen" + smtp_confirmation SMTP confirmation on <= lines + smtp_connection SMTP connections + smtp_protocol_error SMTP protocol errors + smtp_syntax_error SMTP syntax errors + subject contents of Subject: on <= lines + *tls_cipher TLS cipher on <= lines + tls_peerdn TLS peer DN on <= lines + + all all of the above + +"retry time not reached" is always omitted from individual message logs after +the first delivery attempt. + +The log line "error message sent to" has been abolished, because the R= item on +the incoming message line gives the relationship between the original message +and the bounce. + +The logging options that have been abolished are: log_all_parents, +log_arguments, log_incoming_port, log_interface, log_ip_options, +log_level, log_queue_run_level, log_received_sender, log_received_recipients, +log_rewrites, log_sender_on_delivery, log_smtp_confirmation, +log_smtp_connections, log_smtp_syntax_errors, log_subject, tls_log_cipher, +tls_log_peerdn. + + +Debugging +--------- + +The debug_level option has been removed. The -dm option has been removed. The +-df option has also be removed, along with its related build-time option +STDERR_FILE. (To debug inetd usage, an auxiliary script should be used.) + +The -d option has been reworked. It no longer takes a debug level number +argument, but instead takes a list of debugging names, each preceded by + or - +to turn on or off individual sets of debugging messages. + +. The -v option now shows just the SMTP dialog and any log lines. + +. -d with no argument gives a lot of standard debugging data. This is in effect + the equivalent of the old -d9, the thing you ask people to set for an initial + debugging test. + +. -d+x adds debugging option x to the default set + -d-x removes debugging option x from the default set + -d-all+x leaves only debugging option x + +The available debugging names are: + + acl ACL interpretation + auth authenticators + deliver general delivery logic + dns DNS lookups (see also resolver) + dnsbl DNS black list (aka RBL) code + exec arguments for execv() calls + filter filter handling + hints_lookup hints data lookups + host_lookup all types of name->IP address handling + ident ident lookup + interface lists of local interfaces + lists matching things in lists + load system load checks + lookup general lookup code and all lookups + memory memory handling (replaces the old -dm) + process_info setting info for the process log + queue_run queue runs + receive general message reception logic + resolver turn on the DNS resolver's debugging output; goes to stdout + retry retry handling + rewrite rewriting + route address routing + tls TLS logic + transport transports + uid changes of uid/gid and looking up uid/gid + verify address verification logic + + all all of the above, and also -v + +The default (-d with no argument) includes all of the above, plus -v, with the +exception of filter, interface, load, memory, and resolver. Some debugging +output always happens unconditionally whenever any debugging is selected. This +includes some initial output and every log line. + +-d without any value was previously allowed for non-admin users because it used +to be synonymous with -v. In Exim 4, non-admin users may use -v, but not -d. + +If the debug_print option is set in any driver, it produces output whenever any +debugging is selected, or if -v is used. + + +Local Scan Function +------------------- + +For customized message scanning, you can now supply a C function that is linked +into the Exim binary. The function is called local_scan(), and it is called +when Exim has received a message, but has not yet sent a final +acknowledgement to the sender. This applies to all messages, whether local or +remote, SMTP or not. + +From within your function you can inspect the message, change the recipients, +add or remove headers, and tell Exim whether to accept or reject the message. + +The manual contains the specification of the API for this function. + + +String Expansion +---------------- + +. The lookup feature that allowed for subkeys using the syntax + + ${lookup {key:subkey} type {data... + + has been abolished (a) because the effect can be achieved using ${extract, + and (b) because in non-lsearch lookups, a colon can be a valid character in a + key. + +. When a string key is used in a ${extract expansion item, it is now handled + case-insensitively. + +. A new expansion variable called $tod_epoch gives the time as a single decimal + number representing the number of seconds from the start of the Unix epoch. + +. There's a new expansion operator that can turn numbers into base 62, for + example, ${base62:$tod_epoch}. + +. ${extract{number} now recognizes a negative number as a request to count + fields from the right. + +. There's a new expansion feature for reading files: + + ${readfile{/some/file}{eolstring}} + + The contents of the file replace the item. If {eolstring} is present (it's + optional) any newlines in the file are replaced by that string. + +. There's a new expansion feature for running commands: + + ${run{command args}{yes}{no}} + + Like all the other conditional items, the {yes} and {no} strings are + optional. Omitting both is equivalent to {$value}. The standard output of the + command is put into $value if the command succeeds (returns a zero code). The + value of the code itself is put into $runrc, and this remains set afterwards, + so in a filter file you can do things like + + if "${run{x y z}{}}$runrc" is 1 then ... + elsif $runrc is 2 then ... + + As in other command executions from Exim, a shell is not used by default. + If you want a shell, you must explicitly code it. + +. The redirect router has options for forbidding ${readfile and ${run in + filters. + +. A feature is provided to suppress expansion of part of a string. Any + characters between two occurrences of \N are copied to the output string + verbatim. This is particularly useful for protecting regular expressions from + unwanted expansion effects. For example: + + queue_smtp_domains = ! \N^ten-\d+\.testing\.com$\N + + Without \N the \ and $ characters in the regex would have to be escaped. + +. Radius authentication is supported in a similar way to PAM. You must set + RADIUS_CONFIG_FILE in Local/Makefile to specify the location of the Radius + client configuration file. Then you can use expansions such as + + server_condition = ${if radius{arguments}{yes}{no}} + +. User authentication can now also be done by attempting to bind to an LDAP + server. The syntax is again similar to PAM and Radius. + + server_condition = ${if ldapauth{ldap query}{yes}{no}} + + A user and password are required to be supplied with the query. No actual + data is looked up; Exim just does a bind to the LDAP server and sets the + condition according to the result. Here's an example of an SMTP + authenticator: + + login: + driver = plaintext + public_name = LOGIN + server_prompts = "Username:: : Password::" + server_condition = ${if ldapauth \ + {user="uid=${quote_ldap:$1},ou=people,o=example.org" pass="$2" \ + ldap://ldap.example.org/}{yes}{no}} + server_set_id = uid=$1,ou=people,o=example.org + + + +Security +-------- + +Exim 3 could be run in a variety of ways as far as security was concerned. This +has all been simplified in Exim 4. Exim dropped the use of seteuid() in +most places. But recent (2020-10/2021-04) vulnerabilities forced us to +re-introduce seteuid() for opening the database files (hint files) as secure as +possible. For future (>= 4.95) versions we work on a solution that +does not need the seteuid call. + +. A UID and GID are required to be specified when Exim is compiled. They can be + now specified by name as well as by number, so the relevant options are now + called EXIM_USER and EXIM_GROUP. If you really feel you have to run Exim as + root, you can specify root here, but it is not recommended. + +. The "security" option has been abolished. Exim always releases its root + privilege when it can. In a conventional configuration, that means when it is + receiving a message, when it is delivering a message, when it is running a + queryprogram router, and when it is obeying users' filter files (and system + filters if it has been given a user for that purpose). + +. One important change is that Exim 4 runs as root while routing addresses for + delivery. Exim 3 used seteuid() to give up privilege temporarily while + routing. Apart from the unliked use of seteuid(), this sometimes gave rise to + permissions problems on configuration files. + +. However, Exim still runs as the Exim user while receiving messages, and + therefore while using the routing logic for verifying at SMTP time. + +. There is a new option called deliver_drop_privilege. If this is set, Exim + gives up its privilege right at the start of a delivery process, and runs the + entire delivery as the Exim user. This is the same action that used to be + requested by setting security=unprivileged. + + +Hints Databases +--------------- + +. A single "misc" hints database is now used for ETRN and host serialization. + There have been appropriate consequential changes to the utilities for + managing the hints. + +. The exim_tidydb -f option has been abolished. A full tidy is now always done + (it hasn't proved to be very expensive). + + +The run time Configuration File +------------------------------ + +. The format of the configuration file has changed. Instead of using "end" to + terminate sections, it now uses "begin <name>" to start sections. This means + that the sections, apart from the first, may appear in any order. + +. You can now include other files inside Exim run time configuration files, by + using this syntax: + + .include <file name> + +. Quotes round the file name are optional. Includes may be nested to any depth, + but remember that Exim reads its configuration file often. The processing of + .include happens early, at a physical line level, so, like comment lines, it + can be used in the middle of an options setting, for example: + + hosts_lookup = a.b.c \ + .include /some/file + + Include processing happens _before_ macro processing. Its effect is simply to + process the lines of the file as if they occurred inline where the .include + appears. + +. A macro at the start of a configuration line can now turn the line into an + empty line or a comment line. This applies to _logical_ input lines, that is, + after any concatenations have been done. + + +Format of spool files +--------------------- + +. -local_scan is used in spool files to record the value of $local_scan_data, + the string returned from the locally-provided local_scan() function. + + +Renamed Options +--------------- + +Some options have been renamed, to make their function clearer, or for +consistency. + +. receiver_unqualified_hosts has been renamed as recipient_unqualified_hosts. + I'm going to use "recipient" everywhere in future. + +. helo_verify has become helo_verify_hosts. + +. remote_sort has become remote_sort_domains. + +. In the appendfile and pipe transports, "prefix" and "suffix" have become + "message_prefix" and "message_suffix". In the generic router options, + "prefix" and "suffix" have become "local_part_prefix" and "local_part_suffix". + + +Miscellaneous +------------- + +. ETRN serialization now uses a double fork, so that an Exim process (detached + from the original input process) can wait for the command to finish. This + means that it works whatever command ETRN causes to run. (Previously it + worked only if ETRN ran "exim -Rxxx".) + +. For incoming messages, the server's port number is preserved, and is + available in $interface_port. The privileged option -oMi can be used to + set this value. + +. The -Mmd option (to mark addresses delivered) now operates in a + case-sensitive manner. + +. Checks for duplicate deliveries are now case-sensitive in the local part. + +. The number of situations where Exim panics has been reduced. For example, + expansion failures for the "domains" or "local_parts" options in a router now + cause deferral instead of a panic. + +. EXPN no longer attempts to distinguish local and remote addresses (but you + can cause it to be rejected for certain arguments in the ACL). + +. accept_timeout has been renamed as receive_timeout, to match + smtp_receive_timeout. + +. The ability to check an ident value as part of an item in a host list has + been removed. + +. The reject log shows a message's headers only if the rejection happens after + the SMTP DATA command (because they aren't available for earlier checks). The + sender, and up to five recipients are listed in Envelope-from: and + Envelope-to: header lines. After the headers, a line of separator characters + is output. Separators are no longer used for other reject log entries. + +. Because header checks are now done as part of ACLs, they now apply only to + SMTP input. + +. The port number on SMTP connections is now logged in the format [aaaa]:ppp + where aaaa is an IP address and ppp is a port, instead of in the format + [aaaa.ppp] because the former format causes some software to complain about + bad IP addresses. + +. The -oMa and -oMi options can now use the [aaaa]:ppp notation to set a port + number, but they still also recognize the aaaa.ppp notation. + +. The build-time option HAVE_AUTH is abolished. Exim automatically includes + authentication code if any authenticators are configured. + +. The nobody_user and nobody_group options have been abolished. + +. The $message_precedence variable has been abolished. The value is now + available as $h_precedence:. + +. There's a new utility script called exim_checkaccess which packages up a call + to Exim with the -bh option, for access control checking. The syntax is + + exim_checkaccess <IP address> <email address> [exim options] + + It runs "exim -bh <IP address>", does the SMTP dialogue, tests the result and + outputs either "accepted" or "Rejected" and the SMTP response to the RCPT TO + command. The sender is <> by default, but can be changed by the use of the + -f option. + +. The default state of Exim is now to forbid domain literals. For this reason, + the option that changes this has been renamed as allow_domain_literals. + +. The dns_check_names boolean option has been abolished. Checking is now turned + off by unsetting dns_check_names_pattern. + +. The errors_address and freeze_tell_mailmaster options have been abolished. In + their place there is a new option called freeze_tell, which can be set to a + list of addresses. A message is sent to these addresses whenever a message is + frozen - with the exception of failed bounce messages (this is not changed). + +. The message_size_limit_count_recipients option has been abolished on the + grounds that it was a failed experiment. + +. The very-special-purpose X rewrite flag has been abolished. The facility it + provided can now be done using the features of ACLs. + +. The timestamps_utc option has been abolished. The facility is now provided by + setting timezone = utc. + +. The value of remote_max_parallel now defaults to 2. + +. ignore_errmsg_errors has been abolished. The effect can be achieved by + setting ignore_bounce_errors_after = 0s. This option has been renamed from + ignore_errmsg_errors_after to make its function clearer. The default value + for ignore_bounce_errors_after is now 10w (10 weeks - i.e. likely to be + longer than any other timeouts, thereby disabling the facility). + +. The default for message_size_limit is now 50M as a guard against DoS attacks. + +. The -qi option does only initial (first time) deliveries. This can be helpful + if you are injecting message onto the queue using -odq and want a queue + runner just to process new messages. You can also use -qqi if you want. + +. Rewriting and retry patterns are now anything that can be single address list + items. They are processed by the same code, and are therefore expanded before + the matching takes place. Regular expressions must be suitably quoted. These + patterns may now be enclosed in double quotes so that white space may be + included. Normal quote processing applies. + +. Some scripts were built in the util directory, which was a mistake, because + they might be different for different platforms. Everything that is built is + now built in the build directory. The util directory just contains a couple + of scripts that are not modified at build time. + +. The installation script now installs the Exim binary as exim-v.vv-bb (where + v.vv is the version number and bb is the build number), and points a symbolic + link called "exim" to this binary. It does this in an atomic way so that + there is no time when "exim" is non-existent. The script is clever enough to + cope with an existing non-symbolic-link binary, converting it to the new + scheme automatically (and atomically). + +. When installing utilities, Exim now uses cp instead of mv to add .O to the + old ones, in order to preserve the permissions. + +. If the installation script is installing the default configuration, and + /etc/aliases does not exist, the script installs a default version. This does + not actually contain any aliases, but it does contain comments about ones + that should be created. A warning is output to the user. + +. A delay warning message is not sent if all the addresses in a message get a + "retry time not reached" error. Exim waits until a delivery is actually + attempted, so as to be able to give a more informative message. + +. The existence of the three options deliver_load_max, queue_only_load, and + deliver_queue_load_max was confusing, because their function overlapped. The + first of them has been abolished. We are left with + + queue_only_load no immediate delivery if load is high when + message arrives + deliver_queue_load_max no queued delivery if load is too high + +. The ability to edit message bodies (-Meb and the Eximon menu item) has been + removed, on the grounds that it is bad practice to do this. + +. Eximstats is now Steve Campbell's patched version, which displays sizes in K + and M and G, and can optionally generate HTML. + +. If bounce_sender_authentication is set to an email address, this address is + used in an AUTH option of the MAIL command when sending bounce messages, if + authentication is being used. For example, if you set + + bounce_sender_authentication = mailer-daemon@your.domain + + a bounce message will be sent over an authenticated connection using + + MAIL FROM:<> AUTH=mailer-daemon@your.domain + +. untrusted_set_sender has changed from a boolean to an address pattern. It + permits untrusted users to set sender addresses that match the pattern. Like + all address patterns, it is expanded. The identity of the user is in + $sender_ident, so you can, for example, restrict users to setting senders + that start with their login ids by setting + + untrusted_set_sender = ^$sender_ident- + + The effect of the previous boolean can be achieved by setting the value to *. + This option applies to all forms of local input. + +. The always_bcc option has been abolished. If an incoming message has no To: + or Cc: headers, Exim now always adds an empty Bcc: line. This makes the + message valid for RFC 822 (sic). In time, this can be removed, because RFC + 2822 does not require there to be a recipient header. + +. ACTION_OUTPUT=no is now the default in the Exim monitor. + +. dns_ipv4_lookup has changed from a boolean into a domain list, and it now + applies only to those domains. Setting this option does not stop Exim from + making IPv6 calls: if an MX lookup returns AAAA records, Exim will use them. + What it does is to stop Exim looking for AAAA records explicitly. + +. The -G option is ignored (another Sendmail thing). + +. If no_bounce_return_message is set, the original message is not included in + bounce messages. If you want to include additional information in the bounce + message itself, you can use the existing errmsg_file and errmsg_text + facilities. + +. -bdf runs the daemon in the foreground (i.e. not detached from the terminal), + even when no debugging is requested. + +. Options for changing Exim's behaviour on receiving IPv4 options have been + abolished. Exim now always refuses calls that set these options, and logs the + incident. The abolished options are kill_ip_options, log_ip_options, and + refuse_ip_options. + +. The pattern for each errors_copy entry is now matched as an item in an + address list. + +. A number of options and variables that used the word "errmsg" have been + changed to use "bounce" instead, because it seems that "bounce message" is + now a reasonably well-understood term. I used it in the book and am now using + it in the manual; it's a lot less cumbersome than "delivery error + notification message". The changes are: + + $errmsg_recipient => $bounce_recipient + errmsg_file => bounce_message_file + errmsg_text => bounce_message_text + ignore_errmsg_errors_after => ignore_bounce_errors_after + + For consistency, warnmsg_file has been changed to warn_message_file. However, + the two variables $warnmsg_delay and $warnmsg_recipients are unchanged. + + The hide_child_in_errmsg option has not changed, because it applies to both + bounce and delay warning messages. + +. smtp_accept_max_per_host is now an expanded string, so it can be varied on + a per-host basis. However, because this test happens in the daemon before it + forks, the expansion should be kept as simple as possible (e.g. just inline + tests of $sender_host_address). + +. The retry rules can now recognize the error "auth_failed", which happens when + authentication is required, but cannot be done. + +. There's a new option called local_sender_retain which can be set if + no_local_from_check is set. It causes Sender: headers to be retained in + locally-submitted messages. + +. The -dropcr command line option now turns CRLF into LF, and leaves isolated + CRs alone. Previously it simply dropped _all_ CR characters. There is now + also a drop_cr main option which, if turned on, assumes -dropcr for all + non-SMTP input. + + +Removal of Obsolete Things +-------------------------- + +. The obsolete values "fail_soft" and "fail_hard" for the "self" option have + been removed. + +. The obsolete "log" command has been removed from the filter language. + +. "service" was an obsolete synonym for "port" when specifying IP port numbers. + It has been removed. + +. The obsolete option collapse_source_routes has been removed. It has done + nothing since release 3.10. + +. The obsolete from_hack option in appendfile and pipe transports has been + removed. + +. The obsolete ipv4_address_lookup has been abolished (dns_ipv4_lookup has been + a synonym for some time, but it's changed - see above). + +. The obsolete generic transport options add_headers and remove_headers have + been abolished. The new names, headers_add and headers_remove, have been + available for some time. + +Philip Hazel +February 2002 |