Go to the first, previous, next, last section, table of contents.


Using Exim to handle mailing lists

Exim can be used to run simple mailing lists, but for large and/or complicated requirements, the use of additional specialized mailing list software is recommended.

The `forwardfile' director can be used to handle mailing lists where each list is maintained in a separate file, which can therefore be managed by an independent manager. The `domains' director option can be used to run these lists in a separate domain from normal mail. For example:


lists:
  driver = forwardfile
  domains = lists.ref.book
  no_more
  file = /opt/lists/${local_part}
  no_check_local_user
  forbid_pipe
  forbid_file
  errors_to = ${local_part}-request@lists.ref.book

The domain `lists.ref.book' must appear as one of the domains in the `local_domains' configuration option. This director is used only when an address refers to that domain. Because the `no_more' option is set, if the local part of the address does not match a file in the `/opt/lists' directory, causing the director to fail, no subsequent directors are tried, and the whole delivery fails.

The `no_check_local_user' option stops Exim insisting that the local part is the login id of a local user, and because no user or group is specified, no check is made on the ownership of the file. The `forbid_pipe' and `forbid_file' options prevent a local part from being expanded into a file name or a pipe delivery.

The `errors_to' option specifies that any delivery errors caused by addresses taken from a mailing list are to be sent to the given address rather than the original sender of the message. However, before acting on this, Exim verifies the error address, and ignores it if verification fails.

For example, using the configuration above, mail sent to `dicts@lists.ref.book' is passed on to those addresses contained in `/opt/lists/dicts', with error reports directed to `dicts-request@lists.ref.book', provided that this address can be verified. There could be a file called `/opt/lists/dicts-request' containing the address(es) of this particular list's manager(s), but other approaches, such as setting up an earlier director (possibly using the `prefix' or `suffix' options) to handle addresses of the form `owner-xxx' or `xxx-request', are also possible.

Syntax errors in mailing lists

If an entry in a forward file contains a syntax error, Exim normally defers delivery of the entire message. This may not be appropriate when the list is being maintained automatically from address texts supplied by users. If the `skip_syntax_errors' option is set on the `forwardfile' director, it just skips entries that fail to parse, noting the incident in the log. If in addition `syntax_errors_to' is set to a verifyable address, messages about skipped addresses are sent to it.

NFS-mounted mailing lists

It is not advisable to have list files that are NFS mounted, since the absence of the mount cannot be distinguished from a non-existent file. One way round this is to use an `aliasfile' director where the alias file is local and contains a list of the lists, and each alias expansion is simply an `include' item to get the list from a separate, NFS mounted file. If `no_freeze_missing_include' is set for the `aliasfile' director, an unavailable file then just causes delivery to be deferred.

Re-expansion of mailing lists

Exim remembers every individual address to which a message has been delivered, in order to avoid duplication, but it normally stores only the original recipient addresses with a message. If all the deliveries to a mailing list cannot be done at the first attempt, the mailing list is re-expanded when the delivery is next tried. This means that alterations to the list are taken into account at each delivery attempt, and addresses that have been added to the list since the message arrived will thus receive a copy of the message, even though it pre-dates their subscription.

If this behaviour is felt to be undesirable, the `one_time' option can be set on the `forwardfile' director. If this is done, any addresses generated by the director that fail to deliver at the first attempt are added to the message as `top level' addresses, and the parent address that generated them is marked `delivered'. Thus expansion of the mailing list does not happen again at the subsequent delivery attempts. The disadvantage of this is that if any of the failing addresses are incorrect, correcting them in the file has no effect on pre-existing messages.

The original top-level address is remembered with each of the generated addresses, and is output in any log messages. However, any intermediate parent addresses are not recorded. This makes a difference to the log only if `log_all_parents' is set, but for mailing lists there is normally only one level of expansion anyway.

Closed mailing lists

The examples so far have assumed open mailing lists, to which anybody may send mail. It is also possible to set up closed lists, where mail is accepted from specified senders only. This is done by making use of the generic `senders' option. The following example uses the same file for each list, both as a list of recipients and as a list of permitted senders. In this case, it is necessary to set up a separate director to handle the `-request' address.


# Handle mail to xxx-request@lists.ref.book;
# anybody can mail to this address.

lists_request:
  driver = forwardfile
  domains = lists.ref.book
  no_more
  suffix = -request
  file = /opt/lists/${local_part}${local_part_suffix}
  no_check_local_user

# Handle mail to xxx@lists.ref.book;
# only the subscribers to a list may mail to it.
# Use one_time to prevent multiple expansions.

lists:
  driver = forwardfile
  domains = lists.ref.book
  no_more
  require_files = /opt/lists/${local_part}
  senders = lsearch;opt/lists/${local_part}
  file = /opt/lists/${local_part}
  no_check_local_user
  forbid_pipe
  forbid_file
  one_time
  skip_syntax_errors
  errors_to = ${local_part}-request@lists.ref.book

The `require_files' option is needed to ensure that the file exists before trying to search it via the `senders' option; an attempt to search a non-existent file causes Exim to panic. If the file does not exist -- that is, if the mailing list is unknown, the director fails, but because `no_more' is set, no further directors are tried, and so Exim gives up.


Go to the first, previous, next, last section, table of contents.