Simple mailing lists: an illustration of Exim's flexibility
In PostfixVsExim I wrote that Exim is the better mailer if you want to do complex (even crazy) things, because it is more a mailer construction kit than a mailer (with fixed, pre-existing features). For the benefit of people who haven't been exposed to Exim, I thought I'd illustrate this with one of the things we did in our local Exim configuration.
We have a long-standing system of simple
mailing lists. These lists are nothing more than user-owned files
in a particular directory; to set up a mailing list, all you do is
create a file by that name in the mailing lists directory (which is
world-writeable but sticky-bitted, so you can't remove other people's
mailing lists). The file's contents are what the mailing list will
expand out to, with anything that you could put into a
These simple mailing lists work like mailing lists should; if you mail to the list the envelope sender is rewritten to <list>-owner, and the mailer magically materializes both <list>-owner and <list>-request addresses, sending them to the owner of the list's file.
Exim has no particular built-in mailing list handling features, and certainly nothing on this level (and it shouldn't; there's a lot of policy decisions buried in this system). Instead we were able to build it ourselves out of some relatively simple building blocks that Exim does supply, particularly the ability to rewrite addresses and to expand addresses. It was even relatively straightforward.
(I won't claim that it's simple, because it's not really; we are doing some moderately twisted things once you peek under the hood.)
Shorn of a certain amount of extra complexity that we added later, there are three essential pieces of address processing that we set up:
- if an address has a -request or a -owner suffix, and the suffix-less
part is a file in the lists directory, the address is rewritten to
be the owner of the file.
- if an address is a file in the lists directory and the file is not
writeable by anyone except the owner, the envelope sender is rewritten
to be <list>-owner and the file is expanded to obtain new addresses
(with the permissions of the user who owns the file).
(Exim has a general expand-addresses-in-file facility, which is normally used to implement
.forwards, and since it is used for
.forwardsyou can tell Exim to limit its permissions.)
- if the address is a file in the lists directory but the file is writeable by someone besides the owner, we expand the list as above but we set an Exim option so that none of the addresses in the file can be pipes or files. Pipes or files are normally allowed in file expansions, but in this case allowing them would be a security risk.
Exim has basic operations that will do a lot of this, but not quite
all, so for some things we use some basic Unix programs (particularly
stat, because we can get
stat to not follow symlinks). Exim has
more features to let us use external programs as sources of data and
so on, which makes this possible.