12.1 The aliases(5) File

The aliases(5) file is one of several sources that can supply system mail aliases. We describe it first because it is the most traditional and because it illustrates the syntax and limitations common to all techniques.

The aliases(5) file is composed of lines of text. Any line that begins with a # is a comment and is ignored. Empty lines (those that contain only a newline character) are also ignored. Any line that begins with a space or a tab is joined (appended) to the line above it. All other lines of text are viewed as alias lines. The format for an alias line is:

local: alias

The local must begin a line. It is an address in the form of a local recipient address (we will discuss this in more detail soon). The colon follows the local on the same line and can be preceded with spaces or tabs. If the colon is missing, sendmail prints and syslog(3)'s the following error message, and skips that alias line:

missing colon

The alias (to the right of the colon) is one or more addresses on the same line. Indented continuation lines are permitted. Each address should be separated from the next by a comma and optional space characters. A typical alias looks like this:

root: jim, sysadmin@server,
  indenting whitespace

Here, root is the local address to be aliased. When mail is to be locally delivered to root, it is looked up in the aliases(5) file. If found, root is replaced with the three addresses shown earlier, and mail is instead delivered to those other three addresses.

This process of looking up and possibly aliasing local recipients is repeated for each recipient until no more aliases are found in the aliases(5) file. That is, for example, if one of the aliases for root is jim and if jim also exists to the left of a colon in the aliases file, he too is replaced with his alias:

jim: jim@otherhost

The list of addresses to the right of the colon can be mail addresses (such as gunther or jim@otherhost), the name of a program to run (such as /etc/relocated), the name of a file onto which to append (such as /usr/share/archive), or the name of a file to read for additional addresses (using :include:, which will be covered in the next chapter).

12.1.1 The aliases(5) File's Location

The location of aliases(5) is specified with the ServiceSwitchFile option (ServiceSwitchFile) and the AliasFile option (AliasFile) in the configuration file. Be aware that, because these two options interact, it might not suffice to simply declare one or the other. Also be aware that some systems (such as Solaris) supply service-switch files that will override the ServiceSwitchFile option's setting.

Note that the service-switch file merely specifies the order in which various methods should be used to look up aliases, not the specific files. If it lists files as a method:

aliases    files

then all the files declared with the AliasFile option will be looked up in the order in which they were declared:

  • If the AliasFile option specifies a file and if a service-switch file omits the files specification, the AliasFile option is ignored.

  • If the AliasFile option specifies a file and if a service-switch file omits the aliases line, the AliasFile option is used.

  • If the AliasFile option specifies a file and if there is no service-switch file, the AliasFile option file is used, except on systems that implement their own service-switch files.

  • If the AliasFile option is omitted and if there is no service-switch file or if there is a service-switch file but it omits an aliases line, sendmail silently presumes that it should not do aliasing.

Note that service-switch files and the AliasFile option can list other techniques for obtaining aliases in addition to, or instead of, an aliases(5) file. But this can lead to a side effect. For example, if your configuration file declares:

O AliasFile=/etc/aliases,nis:

and if the service-switch file aliases line specifies:

aliases    nis files

sendmail looks up aliases first with nis, then in the /etc/aliases file, then with nis a second time.

12.1.2 Local Must Be Local

The local part of an alias must be in the form of a local recipient.[1] This restriction is enforced each time sendmail reads the aliases(5) file. For every name to the left of a colon that it finds, sendmail performs the following normalization and verification steps.

[1] If you set the F=A flag for the various smtp delivery agents, the local part of an alias can be specified as a network or remote address, such as user@host.domain.

To begin, sendmail normalizes each address by removing everything but the address part. For example, consider the following two alias lines:

george (George Washington): gw
George Washington <george>: gw

When sendmail reads these lines, it normalizes each into its address part:

george (George Washington)    becomes  george
George Washington <george>    becomes  george

After the address part is extracted and rewritten by the canonify rule set 3 and the parse rule set 0, to see whether it causes any delivery agent with the F=A flag set (F=A) to be selected. Generally, local addresses select the local delivery agent, which normally has the F=A flag set. Nonlocal addresses (such as gw@another.host) generally select one of the smtp delivery agents, which normally do not have the F=A flag set.

Prior to V8.7 sendmail, an address had to select the local delivery to allow itself to be aliased.

If the selected delivery agent has the F=u flag set (F=u), the address will be converted to lowercase before being looked up in the aliases database.

In the earlier example, the address george (after processing) selects the local delivery agent, and so these alias lines are legal. Internally (or in its database), sendmail stores the earlier alias as:

george: gw

When mail arrives that is addressed for delivery to george, sendmail rewrites that address with the canonify rule set 3 and the parse rule set 0. The parse rule set 0 selects the local delivery agent (or, for V8.7 and above, any agent with F=A set). The address george is looked up and replaced with gw. Internally, sendmail marks the recipient george as defunct, having been replaced with an alias, and then adds gw to the list of recipients.

The new recipient, gw, is then processed for delivery. The canonify rule set 3 and the parse rule set 0 are called once more and again select a local delivery agent. As a consequence, gw is also looked up. If it is found to the left of a colon in the aliases file, it too is replaced with yet another address (or addresses). This process repeats until no new local addresses are found.

Note that the entry george is marked defunct rather than being deleted to detect alias loops. To illustrate, consider the following two mutually referencing aliases:

george: gw
gw: george

The sendmail program first replaces george with gw, marking george as defunct. It goes to mark gw as defunct but notices that a loop has been formed. If sendmail is running in verbose mode (Verbose), it prints:

aliasing/forwarding loop broken

and bounces the message.

Note also that aliases can get pretty complex. As a consequence, when one address aliases to many new addresses, this autodetection of loops can fail (but the problem will be caught later with "hop counting"; see MaxHopCount).

12.1.3 Alias Nonlocal Addresses

As distributed, a normal configuration file will disallow certain addresses on the left side of the aliases file. Consider the following two addresses:

Bob@our.host:           bob
Bob@another.host:       bob@home.isp

In both examples, the intention is for mail to bob at the local host ( our.host ) to be delivered to the local mailbox for the user bob. This will happen in the first example (assuming a normal configuration file) because the @our.host part of the address will be removed by rule sets:

canonify           input: Bob @ our.host
Canonify2          input: Bob < @ our.host >
Canonify2        returns: Bob < @ our.host . >
canonify         returns: Bob < @ our.host . >
parse              input: Bob < @ our.host . >
Parse0             input: Bob < @ our.host . >
Parse0           returns: Bob < @ our.host . >
ParseLocal         input: Bob < @ our.host . >
ParseLocal       returns: Bob < @ our.host . >
Parse1             input: Bob < @ our.host . >
Parse1           returns: $# local $: Bob
parse            returns: $# local $: Bob
2                  input: Bob
2                returns: Bob
EnvToL             input: Bob
EnvToL           returns: Bob
final              input: Bob
final            returns: Bob
mailer local, user Bob

Because the local delivery agent was selected, and because that delivery agent has the F=A flag set (F=A), mail to BobI@our.host will be aliased for local delivery to the user bob.

The second address, Bob@another.host, however, selects an smtp delivery agent:

canonify           input: Bob @ another . host
Canonify2          input: Bob < @ another . host >
Canonify2        returns: Bob < @ another . host >
canonify         returns: Bob < @ another . host >
parse              input: Bob < @ another . host >
Parse0             input: Bob < @ another . host >
Parse0           returns: Bob < @ another . host >
ParseLocal         input: Bob < @ another . host >
ParseLocal       returns: Bob < @ another . host >
Parse1             input: Bob < @ another . host >
MailerToTriple     input: < > Bob < @ another . host >
MailerToTriple   returns: Bob < @ another . host >
Parse1           returns: $# esmtp $@ another . host $: Bob < @ another . host >
parse            returns: $# esmtp $@ another . host $: Bob < @ another . host >
2                  input: Bob < @ another . host >
2                returns: Bob < @ another . host >
EnvToSMTP          input: Bob < @ another . host >
PseudoToReal       input: Bob < @ another . host >
PseudoToReal     returns: Bob < @ another . host >
MasqSMTP           input: Bob < @ another . host >
MasqSMTP         returns: Bob < @ another . host >
EnvToSMTP        returns: Bob < @ another . host >
final              input: Bob < @ another . host >
final            returns: Bob @ another . host
mailer esmtp, host another.host, user Bob@another.host

Because the esmtp delivery agent does not have the F=A flag set, the presence of the address Bob@another.host will be disallowed on the lefthand side of the aliases file:

% newaliases
/etc/mail/aliases: line 2: Bob@another.host... cannot alias nonlocal names

In the rare circumstance that you need to be able to alias nonlocal addresses, you can do so by adding the F=A flag to the smtp class of delivery agents. You do this by editing your mc configuration file and adding the following line above the definition for that class of delivery agents:

APPENDDEF(`SMTP_MAILER_FLAGS', `A')     prior to V8.10
MODIFY_MAILER_FLAGS(`smtp', `+A')       V8.10 and above
MAILER(smtp)                            this must follow flag modifications

After that, build a new configuration file from this new mc file and install it. Thereafter, you will be able to successfully alias nonlocal addresses without errors.

Before undertaking this step, however, see FEATURE(virtusertable) in Chapter 4 for a description of the virtusertable mc feature, which also allows nonlocal addresses to be transformed into inside or outside addresses. Note, too, that the User Database (userdb) allows recipient addresses to be changed so that they can be delivered to new hosts, and that the genericstable mc feature (FEATURE(genericstable)) allows sender addresses to be changed to appear to be coming from new hosts. Clearly, there are many ways to achieve the same result, and one of those might be more suitable to your needs than the F=A flag.

    Part I: Build and Install
    Part II: Administration
    Part III: The Configuration File