The sendmail program can be an open door to abuse. Unless
the administrator is careful, the misuse or misconfiguration
of sendmail can lead to an insecure and possibly compromised
system.
Since sendmail is usually installed to run as an suid
root process, it is a prime target for intrusion.
The "Internet worm," for example, used a flaw in old versions
of sendmail as one way to gain entry to thousands of machines.
[1]
If sendmail is not properly installed,
external probes over networks can be used to gain information that is valuable
in attempting entry. Once inside, improper file permissions
can be used to trick sendmail into giving away root privilege.
Even email cannot be trusted, and forged email can cause
some users to give away their passwords.

[1] That flaw has been eliminated - wrongly by some vendors who turned
all debugging completely off correctly by most who
simply disabled SMTP debugging.

In this chapter we present several ways to protect your site from
intrusion via sendmail. Most are just good common sense, and
the experienced system administrator may be offended that we state
the obvious. But not all system administrators are experienced, and
not all who administer systems are system administrators.
If you fall into the latter category, you may wish to keep
keep a good, general UNIX reference by your side to better appreciate
our suggestions.

One common complaint about sendmail centers on the fact
that it must usually be run suid root (that is, run as
root no matter who actually runs it).
[2]
But for the most part it is necessary for sendmail to run as
root to satisfy the legitimate needs of users. Consider the following:

[2] Contrary to popular belief,
sendmail does not run as root to handle local delivery
(except that sendmail can deliver directly to files when necessary,
but that is not directly germane to this discussion).
Local delivery is handled by delivery agents (such as /bin/mail),
which may run suid root themselves (or sgid mail as in
SysV).

Users want ~/.forward files to work even when their home directory is
set to mode 700.
The sendmail program requires root privilege
so that it can temporarily become the user to read and process the ~/.forward
file.

Users want :include: mailing-list files readable only by themselves and
sendmail.
The sendmail program requires root privilege
so that it can temporarily become the owner of the list.

Users want programs that run on their behalf to run as themselves. This
requires root privileges, and running as anything else would be
potentially very dangerous.

Users want sendmail to listen on a TCP/IP port that
is common (port 25). The sendmail program requires root privilege
so that it can initiate a listening connection to its privileged port.

Some folks have been tempted to run sendmail as an untrusted
pseudo-user (such as nobody). But this doesn't really work.
For example, it causes programs in users' ~/.forward files
to be run as nobody, and it requires the queue to be owned
by nobody. Consequently, such a scheme allows any user
to break into and modify the queue.
[3]

[3] But note that V8.8 sendmail has
loosened the latter for use on firewall machines, where it won't complain about
non-rootqf files if it is not running as root.

Clearly, many of sendmail's duties require it to run as root. As a
corollary, however, whenever sendmail does not need to be root,
it should become the appropriate nonprivileged user. It does this by using
the following bit of logic:

If it was compiled with support for seteuid(3) (see Section 18.8.55, USESETEUID),
use that routine to set the effective uid to that of the desired non-root
user. This is less preferred than the following:

If it was compiled with support for setreuid(3) (see Section 18.8.9, HAS...),
use that routine to set the effective and real uids to those of the
desired non-root user.

Otherwise, use setuid(3) to become the desired non-root user.

Note that setreuid(3) is preferred over seteuid(3)
[4]
and setuid(3)
because it allows sendmail to temporarily give away both its
real and effective root
privilege, then to get it back again. To illustrate
the need for this behavior,
consider processing a mailing list that saves mail to two different files:

[4] Except when seteuid(3) is Posix compliant. Old implementations
of seteuid(3) didn't properly save the uid; hence the preference,
in that, case for setreuid(3).

Further consider that these files both have permissions of suid to
the individual users
[5]
and are writable only by the individual users.
To perform delivery in this instance, sendmail must
[6]
first become
bill (this requires root privilege to do). When it is
done, sendmail must become root again so that it can
next become alice. By retaining a real uid of root
(with the seteuid(3) routine), sendmail is able to
change its effective uid back and forth between users and
root as needed.

[5] When delivering to files, sendmail will become the owner of the file
if that file's suid bit is set and if no execute bits are set.

[6] We say "must" because in an NFS environment, root
is mapped to nobody so, in that instance, even root won't be able to
write to bill's files.

See the description of the test directory in Section 18.8.55
for more on this subject.