Chapter 1. Getting Started

Introduction

To follow a recipe successfully, you must clearly understand the instructions it contains. You must understand the difference between folding and stirring and be able to find the spices when the recipe calls for a pinch of cumin. Just as you must be able to find your way around the kitchen to become a cook, you must know your way around the sendmail distribution in order to build or customize a sendmail configuration.

The directory structure—created by the sendmail source code distribution tarball— contains the tools and ingredients used to build and configure sendmail. The top-level directory created by the tarball is assigned a name that identifies the sendmail version number. At the time of this writing, the current version is sendmail 8.12.9; therefore, the top-level directory is named sendmail-8.12.9. By the time you read this, there will be a newer version of sendmail, and the directory name will reflect that new version number. An ls of the top-level directory shows the following:[1]

$ ls sendmail-8.12.9
Build     doc      INSTALL    libsmdb     mailstats  praliases      sendmail
cf        editmap  KNOWNBUGS  libsmutil   Makefile   README         smrsh
contrib   FAQ      libmilter  LICENSE     makemap    RELEASE_NOTES  test
devtools  include  libsm      mail.local  PGPKEYS    rmail          vacation

Most of these files and directories are used to compile sendmail. The Build script uses the Makefile to compile sendmail and its utilities. The devtools directory is used to set compiler options, as discussed in Recipe 1.2 to Recipe 1.7. The source code is located in aptly named subdirectories. For example, the sendmail source code is in the sendmail directory, the libraries are in directories such as libsm and libsmutil, and the source code of utilities such as makemap and smrsh is located in easily identified directories.

There are also several important sources of information in the distribution:

  • The INSTALL and README files provide the latest information on compiling and installing sendmail.

  • The RELEASE_NOTES file lists the important features of the new release.

  • The KNOWNBUGS and FAQ files explain solutions to chronic and common problems.

  • The doc subdirectory contains the Sendmail Installation and Operations Guide, which is an excellent source of information for the sendmail administrator.

Of all of these important directories and files, the most important (from the perspective of this book) is the cf directory, because the cf directory contains the configuration files (and this is a book about sendmail configuration).

The cf directory structure

The m4 source files and libraries used to build the sendmail configuration are located in the cf directory, which contains the following items:

$ ls sendmail-8.12.9/cf
cf      feature  m4      ostype  sendmail.schema  siteconfig
domain  hack     mailer  README  sh

The cf directory contains two files, README and sendmail.schema, and nine subdirectories. The sendmail.schema file is an experimental LDAP schema that predefines attribute types and object classes that can be used with LDAP. The sendmail schema is used in most LDAP examples in this book. The README file is a comprehensive reference to the syntax and usage of all of the m4 macros and variables used to configure sendmail. The README file is an invaluable reference, particularly when used with this book.

The directories hack, sh, and siteconfig have very little use for most configurations.

hack directory

The hack directory is intended to hold m4 source files built by the local system administrator to solve temporary sendmail configuration problems. There is only one file in the hack directory, built years ago, which serves as an example of a sendmail hack. The hack directory and the HACK macro are still there, but, with all of the power and flexibility available to configure sendmail, there is simply no good reason to use them.

siteconfig directory

The siteconfig directory is intended to hold files that use sendmail m4 SITE macros to list the locally connected UUCP sites. The siteconfig directory, the SITECONFIG macro, and the SITE macro are maintained for backward compatibility. However, the directory and the macros are obsolete and should no longer be used to define the UUCP connectivity for a UUCP mail server.

sh directory

The sh directory contains only the makeinfo.sh file. Most of the files in the cf subdirectories are m4 macro source files that end with the .m4 extension. This file, however, ends with the .sh extension, indicating that it is a shell script. The script produces three lines of comments for the sendmail.cf file that identify who built the configuration, when they built it, and in what directory.

The remaining six directories are the real heart of sendmail configuration. Four of these directories, domain, feature, ostype, and mailer, have the same names as sendmail m4 macros, and provide the source code used by those macros. The purposes of these four directories are:

domain directory

The domain directory holds m4 source files that define configuration values that are specific to your domain or network. If you need to define such values, create your own file; the six files contained in the domain directory are just examples. The configuration file you create for your environment is then used in the master configuration file via the DOMAIN macro.

ostype directory

The files in the ostype directory define operating system-specific characteristics for the sendmail configuration. Every master configuration file must contain an OSTYPE macro to process the correct macro source file for the sendmail server’s operating system.[2] The sendmail-8.12.9/ostype directory contains configuration files for more than 40 different operating systems, each one easily identified by name. Select the file that matches your server’s operating system.

mailer directory

In addition to an OSTYPE macro, most master configuration files have at least one MAILER macro. MAILER macros process source files from the mailer directory. Each file in the mailer directory contains the definition of a set of mailers. The current mailer directory contains 12 different files. Many configurations use only the two most basic sets of mailers: local.m4 for local mail delivery and smtp.m4 for SMTP mail delivery.

feature directory

The feature directory contains the m4 source code files that implement various sendmail features. There are more than 40 feature files available in the directory. Features are used to address specific configuration problems.

The other two remaining directories, cf and m4, contain the master configuration files and macro source libraries used by m4. The four directories described above contain files that are invoked inside the sendmail configuration by m4 macros. The cf/cf directory and the cf/m4 directory contain m4 source files that are normally invoked on the m4 command line.

The cf/m4 directory

The cf/m4 directory contains the m4 macro definitions and the sendmail.cf skeleton code needed to build a sendmail.cf configuration file. Remember that m4 is a general purpose macro language; it is not a language specifically designed to build sendmail configurations. sendmail configurations are built using macros defined by the sendmail developers. The cf/m4 directory contains the four files that define those macro commands.

version.m4

The version.m4 file defines the sendmail.cf Z variable, which is assigned the sendmail version number. Because this value changes with each sendmail release, it is defined in a separate file for easy maintenance.[3]

cf.m4

The cf.m4 file is specified on the m4 command line to incorporate the library of sendmail m4 macro commands into the m4 process. The cf.m4 file includes, by reference, the cfhead.m4 file that contains the macro definitions.

cfhead.m4

The cfhead.m4 file defines the m4 macros used to configure sendmail. This file includes lots of stuff, most importantly the definition of many of the commands used to build a configuration.

proto.m4

The proto.m4 file is the source of most of the content found in the sendmail.cf file.

The cf subdirectory

The cf/cf directory is the working directory of sendmail configuration. It contains all of the master configuration files, and it is where you will put your own master configuration file when you build a custom configuration. The directory contains more than 40 files.

$ ls sendmail-8.12.9/cf/cf
Build             generic-hpux10.cf      generic-solaris.cf  python.cs.mc
chez.cs.mc        generic-hpux10.mc      generic-solaris.mc  README
clientproto.mc    generic-hpux9.cf       generic-sunos4.1.cf s2k-osf1.mc
cs-hpux10.mc      generic-hpux9.mc       generic-sunos4.1.mc s2k-ultrix4.mc
cs-hpux9.mc       generic-linux.cf       generic-ultrix4.cf  submit.cf
cs-osf1.mc        generic-linux.mc       generic-ultrix4.mc  submit.mc
cs-solaris2.mc    generic-mpeix.cf       huginn.cs.mc        tcpproto.mc
cs-sunos4.1.mc    generic-mpeix.mc       knecht.mc           ucbarpa.mc
cs-ultrix4.mc     generic-nextstep3.3.cf mail.cs.mc          ucbvax.mc
cyrusproto.mc     generic-nextstep3.3.mc mail.eecs.mc        uucpproto.mc
generic-bsd4.4.cf generic-osf1.cf        mailspool.cs.mc     vangogh.cs.mc
generic-bsd4.4.mc generic-osf1.mc        Makefile

Most of these files—more than 30 of them—are sample master configuration files. You can identify a master configuration file by the .mc extension. Some are examples meant as educational tools, but most are prototypes or generic files meant to be used as the basis of your own configuration. The generic files designed for specific operating systems are particularly interesting, such as Solaris, HPUX, BSD, Linux, and several others. We use the generic-linux.mc file in Recipe 1.8.

Several of the files are identified by the .cf extension. These files are the result of processing master configuration files through m4; they are already in the proper format to be used as the sendmail.cf file. It is unlikely, however, that you will use one of these files directly. Unless the generic master configuration file is exactly to your liking, the sendmail configuration file produced from that .mc file will not be what you want. We start with a generic configuration in Recipe 1.8, but the subsequent recipes in this book modify that generic configuration to create the custom configurations we need.

1.1. Downloading the Latest Release

Problem

You must keep your sendmail software up-to-date.

Solution

Sticking with the standard software management method used on your system is the easiest way to upgrade sendmail. If you use a package manager, go to your Unix vendor’s web site, download the appropriately packaged sendmail update, and install it using the package manager. If the vendor cannot provide a critical sendmail update or does not provide the compiled-in features you need, and you decide to use the sendmail source code distribution, gracefully transition from the package manager to the source code distribution by following the Unix vendor’s advice on how to remove a package that was installed by the package manager. Recipe 1.1.3 shows an example of using the Red Hat Package Manager to remove the sendmail RPM before the sendmail source code distribution is installed.

If you need to use the sendmail source code distribution, download the latest version of sendmail from ftp://ftp.sendmail.org/, from http://www.sendmail.org/current-release.html, or from one of a large number of mirror sites. A link to the mirror sites is found on the http://www.sendmail.org/ home page. The Discussion section provides an example of downloading the sendmail source code distribution via ftp.

Get the signature file associated with the version of sendmail you downloaded. For example, the signature file for the sendmail.8.12.9.tar.gz tarball downloaded in the Discussion section is sendmail.8.12.9.tar.gz.sig.

Download the PGP keys needed to verify the signature, and add them to your key ring (you only need to do this approximately once a year). After the PGP keys are added to your key ring, they can be used to verify the signature file of any further downloads made during that calendar year.

Use the pgp or gpg programs to verify the signature of the downloaded file (the Discussion section shows an example using gpg). If you accept the signature, restore the sendmail distribution tarball file.

Discussion

sendmail changes frequently. When the first draft of this chapter was written, the latest release of sendmail was about 3 weeks old, and the previous release was only 11 weeks old! Does this mean you must upgrade sendmail every few months? Not at all. Yet you should keep track of new sendmail releases in order to determine when upgrading is important to you. Three reasons that system administrators choose to upgrade are:

Security

sendmail is a popular target for network intruders. They attack sendmail because it is a large, complex program that runs on many systems; sendmail is even run on desktop workstations that sometimes have less than adequate system administration. The weaknesses exposed by these attacks are quickly fixed in new sendmail releases. Stay informed by subscribing to the sendmail-announce mailing list to receive notices of new sendmail releases and by monitoring the http://www.sendmail.org/ site. It is important to upgrade to a new sendmail release when the release fixes a security problem.

Spammers

Security attacks usually involve unauthorized access or denial of service. A related problem is the unauthorized use and theft of service that occurs when a spammer misuses your email system. Current sendmail releases do a much better job of preventing mail abuse than old releases did. Watch for new releases that add anti-spam features. If you can reduce spam, the world will thank you.

New features

Anti-spam features are not the only new features added to sendmail releases. Sometimes you may find a feature that is important enough to warrant an upgrade. For example, sendmail 8.11 added support for Transport Layer Security (TLS), which might be important to your organization.

Of these three reasons for upgrading, security is the most important. If you know of a security problem, you can bet that the bad guys also know and are doing their best to exploit it. Close security holes as quickly as possible. Chapter 10 shows how sendmail can be patched to close security holes.

Once you have decided to upgrade the sendmail software, you need to decide how you will do it. The easiest way to upgrade software is to use the software management tool provided with your version of Unix. A classic example of such a tool is the RPM Package Manager (RPM) that was developed by Red Hat and is used in many different Linux distributions. Tools like RPM install software packages that have already been customized for a particular Unix variant, placing the files in the proper directories and relieving the administrator of the burden of compiling the software. These tools also provide security features, such as the --verify option of the rpm command, that check the software and files for tampering during and after the installation. When you want to upgrade to a new version of sendmail, check your Unix vendor’s web site to see if it is available in their package format.[4]

Despite the benefits of software management tools, sometimes you need to compile your own software to enable special features, and sometimes the latest version of software is not available in a package format. If you must switch to the sendmail tarball on a system where the previous sendmail installation was done by a package manager, backup the current configuration and then uninstall the current version of sendmail using the package manager before you upgrade. The example shows how to uninstall sendmail using RPM:

# service sendmail stop
Shutting down sendmail:                                    [  OK  ]
# rpm -qa | grep sendmail
sendmail-8.11.6-15
sendmail-cf-8.11.6-15
sendmail-devel-8.11.6-15
# rpm --erase sendmail-devel-8.11.6-15
# rpm --erase sendmail-cf-8.11.6-15
# rpm --erase --nodeps sendmail-8.11.6-15
warning: /etc/mail/statistics saved as /etc/mail/statistics.rpmsave

This example is from a Red Hat 7.3 system. Start by shutting down the current sendmail daemon. Then use rpm -qa to find out which sendmail RPM packages are installed, and rpm --erase to remove each of the packages. Notice that the --nodeps option is used with the final rpm command. The --nodeps option forces rpm to erase the package, even if doing so breaks the dependencies of other packages. Removing the sendmail daemon, which is what the final rpm command does, breaks other packages that depend on the sendmail daemon. Once you install the new sendmail daemon, those packages should function again. However, the negative impact on dependencies, caused by switching from an RPM based installation to a tarball installation, is one reason why you should always try to upgrade an RPM installation with another RPM, if possible.

Perform these steps to remove the currently installed sendmail after successfully compiling the new version of sendmail and before installing the newly created sendmail binaries. This uninstall step is necessary to prevent the package manager from falsely reporting errors when the package manager is used to scan the software for possible tampering.

Caution should also be exercised when installing a vendor’s sendmail package on a system that already has a custom sendmail configuration. As Recipe 1.2 to Recipe 1.7 show, sendmail can be compiled with special options; however, the vendor might not provide the options you need, and the vendor package might overwrite the specially compiled sendmail binary. Bottom line: take care whenever you transition from one installation technique to another. If you’re not changing installation techniques, and you don’t use a package manager, you don’t need to be concerned with any of this before you proceed with installing the sendmail source code distribution—you can just follow the steps that are discussed below.

Begin by downloading the sendmail source code distribution from http://www.sendmail.org/current-release.html, from any of the mirror sites, or from ftp://ftp.sendmail.org/pub/sendmail/. Here is an example using ftp:

$ ftp ftp.sendmail.org
Connected to ftp.sendmail.org (209.246.26.22).
220 services.sendmail.org FTP server (Version 6.00LS) ready.
Name (ftp.sendmail.org:alana): anonymous
331 Guest login ok, send your email address as password.
Password: alana@rodent.wrotethebook.com
230 Guest login ok, access restrictions apply.
Remote system type is UNIX.
Using binary mode to transfer files.
ftp> cd pub/sendmail
250 CWD command successful.
ftp> get sendmail.8.12.9.tar.gz
local: sendmail.8.12.9.tar.gz remote: sendmail.8.12.9.tar.gz
227 Entering Passive Mode (209,246,26,22,207,236)
150 Opening BINARY mode data connection for 'sendmail.8.12.9.tar.gz' (1886008 bytes).
226 Transfer complete.
1886008 bytes received in 10.1 secs (1.8e+02 Kbytes/sec)

The new release is stored in the pub/sendmail directory as a compressed tarball under the name sendmail.release.tar.gz for those who use gzip and sendmail.release.tar.Z for those who use compress. In either case, release is the current numeric release number. For example, the release number at this writing is 8.12.9, so the gzipped tarball is named sendmail.8.12.9.tar.gz and the compressed tarball is named sendmail.8.12.9.tar.Z.

Next, get the signature file associated with the version of sendmail you downloaded. For example, the signature file for sendmail.8.12.9.tar.gz is sendmail.8.12.9.tar.gz.sig. Here we download it during the same ftp session:

ftp> get sendmail.8.12.9.tar.gz.sig
local: sendmail.8.12.9.tar.gz.sig remote: sendmail.8.12.9.tar.gz.sig
227 Entering Passive Mode (209,246,26,22,207,238)
150 Opening BINARY mode data connection for 'sendmail.8.12.9.tar.gz.sig' (152 bytes).
226 Transfer complete.
152 bytes received in 0.00221 secs (67 Kbytes/sec)

If you do not have the current sendmail PGP keys on your key ring, download the PGP keys needed to verify the signature. Here we add the following step to the ftp session to download the keys for the current year:

ftp> get PGPKEYS
local: PGPKEYS remote: PGPKEYS
227 Entering Passive Mode (209,246,26,22,207,239)
150 Opening BINARY mode data connection for 'PGPKEYS' (57704 bytes).
226 Transfer complete.
57704 bytes received in 0.491 secs (1.1e+02 Kbytes/sec)
ftp> quit
221 Goodbye.

Add the PGP keys to your key ring. In the following example, gpg (Gnu Privacy Guard) is used:

$ gpg --import PGPKEYS
gpg: key 16F4CCE9: not changed
gpg: key 396F0789: public key imported
gpg: key 678C0A03: not changed
gpg: key CC374F2D: not changed
gpg: key E35C5635: not changed
gpg: key A39BA655: not changed
gpg: key D432E19D: not changed
gpg: key 12D3461D: not changed 
gpg: key BF7BA421: not changed
gpg: key A00E1563: non exportable signature (class 10) - skipped
gpg: key A00E1563: not changed
gpg: key 22327A01: not changed
gpg: Total number processed: 11
gpg:               imported: 1  (RSA: 1)
gpg:              unchanged: 10

gpg is used in this example because it is included as part of the Red Hat Linux distribution used on our sample sendmail system. Of the 11 exportable keys in the PGPKEYS file, only one is imported to our key ring. The not changed comment for the other 10 keys shows that they were already installed on the key ring. The first time you import PGPKEYS, all 11 keys will be added to the key ring.

Before using the new key, verify its fingerprint, as shown here:

$ gpg --fingerprint 396F0789
pub  1024R/396F0789 2003-01-15 Sendmail Signing Key/2003 <sendmail@Sendmail.ORG>
     Key fingerprint = C4 73 DF 4A 97 9C 27 A9  EE 4F B2 BD 55 B5 E0 0F

Compare the displayed fingerprint against Table 1-1 that shows sendmail’s signing key fingerprints.

Table 1-1. sendmail signing key fingerprints

Year

Fingerprint

1997

CA AE F2 94 3B 1D 41 3C 94 7B 72 5F AE 0B 6A 11

1998

F9 32 40 A1 3B 3A B6 DE B2 98 6A 70 AF 54 9D 26

1999

25 73 4C 8E 94 B1 E8 EA EA 9B A4 D6 00 51 C3 71

2000

81 8C 58 EA 7A 9D 7C 1B 09 78 AC 5E EB 99 08 5D

2001

59 AF DC 3E A2 7D 29 56 89 FA 25 70 90 0D 7E C1

2002

7B 02 F4 AA FC C0 22 DA 47 3E 2A 9A 9B 35 22 45

2003

C4 73 DF 4A 97 9C 27 A9 EE 4F B2 BD 55 B5 E0 0F

If the fingerprint is correct, you can sign, and thus validate, the key. In this gpg example, we sign the newly imported sendmail key:

$ gpg --edit-key 396F0789
gpg (GnuPG) 1.0.7; Copyright (C) 2002 Free Software Foundation, Inc.
This program comes with ABSOLUTELY NO WARRANTY.
This is free software, and you are welcome to redistribute it
under certain conditions. See the file COPYING for details.

gpg: checking the trustdb
gpg: checking at depth 0 signed=0 ot(-/q/n/m/f/u)=0/0/0/0/0/1
pub  1024R/396F0789  created: 2003-01-15 expires: never      trust: -/-
(1). Sendmail Signing Key/2003 <sendmail@Sendmail.ORG>

Command> sign

pub  1024R/396F0789  created: 2003-01-15 expires: never      trust: -/-
             Fingerprint: C4 73 DF 4A 97 9C 27 A9  EE 4F B2 BD 55 B5 E0 0F
     Sendmail Signing Key/2003 <sendmail@Sendmail.ORG>

How carefully have you verified the key you are about to sign actually belongs to the 
person named above?  If you don't know what to answer, enter "0".

   (0) I will not answer. (default)
   (1) I have not checked at all.
   (2) I have done casual checking.
   (3) I have done very careful checking.

Your selection? 3
Are you really sure that you want to sign this key
with your key: "Craig Hunt <craig.hunt@wrotethebook.com>"

I have checked this key very carefully.

Really sign? y

You need a passphrase to unlock the secret key for
user: "Craig Hunt <craig.hunt@wrotethebook.com>"
1024-bit DSA key, ID 34C9B515, created 2003-07-23


Command> quit
Save changes? y

Remember, it is not necessary to download and import the PGPKEYS file every time you download a new sendmail release. New keys are only added to the PGPKEYS file about once a year.

After the sendmail keys have been added to the key ring and signed, you can verify the sendmail distribution tarball. Here we use the sendmail.8.12.9.tar.gz.sig signature file to verify the sendmail.8.12.9.tar.gz compressed tarball:[5]

$ gpg --verify sendmail.8.12.9.tar.gz.sig sendmail.8.12.9.tar.gz
gpg: Signature made Sat 29 Mar 2003 09:12:38 AM EST using RSA key ID 396F0789
gpg: Good signature from "Sendmail Signing Key/2003 <sendmail@Sendmail.ORG>"
gpg: checking the trustdb
gpg: checking at depth 0 signed=1 ot(-/q/n/m/f/u)=0/0/0/0/0/1
gpg: checking at depth 1 signed=0 ot(-/q/n/m/f/u)=1/0/0/0/0/0

Based on this, the distribution can be safely restored, compiled, and installed. Use tar to restore the tarball. The tarball creates a directory with a name derived from the sendmail release number. Therefore the following commands create a directory named sendmail-8.12.9 in /usr/local/src:

# cd /usr/local/src
# tar -zxvf /home/craig/sendmail.8.12.9.tar.gz

The path /usr/local/src/sendmail-8.12.9 is used throughout this book. When implementing the recipes, adjust this path as appropriate for your system.

See Also

Recipe 10.4 provides a detailed example of downloading and installing sendmail patches, which are sometimes used as an alternative to downloading a full distribution. sendmail, Third Edition, by Bryan Costales with Eric Allman (O’Reilly), covers downloading the sendmail source distribution in Section 2.2. PGP: Pretty Good Privacy, by Simson Garfinkel (O’Reilly), is a full book about PGP. The GNU Privacy Handbook (GPH), which is available at http://www.gnupg.org/(en)/documentation/guides.html, provides detailed information about GPG.

1.2. Installing sendmail

Problem

The sendmail tarball is a source code distribution that must be compiled. Additionally, adding a special user ID and group ID may be necessary before the new sendmail software can be installed and used.

Solution

Compile sendmail using the Build utility provided by the sendmail developers. For most systems, only a few commands are needed to compile sendmail:

# cd sendmail-8.12.9
# ./Build

The next installation step is to create the smmsp user and group for sendmail to use when it runs as a mail submission program. Do this by using the tools appropriate to your system. Here are the /etc/passwd and /etc/group entries added to the example Red Hat system used throughout this book:

# grep smmsp /etc/passwd
smmsp:x:25:25:Mail Submission:/var/spool/clientmqueue:/sbin/nologin
# grep smmsp /etc/group
smmsp:x:25:

Next, backup the current sendmail binary, the sendmail utilities, and the current sendmail configuration files. After the system is backed up, install the new sendmail and utilities as follows:

# ./Build install

Discussion

Build detects the architecture of the system and builds a Makefile customized to that system. It then uses make to compile sendmail. Build does an excellent job of correctly detecting the system architecture.

A basic Build command should work for most situations. If it doesn’t work for you, either because of your unique hardware and software, or because you have unique requirements, create a custom configuration for Build to use. sendmail calls these custom configurations site configurations and looks for them in the devtools/Site directory, where it expects to find the local custom configuration stored under the name site.config.m4. By default, Build looks for files named site.OS .m4, where OS is the name of the computer’s operating system, site.config.m4, and site.post.m4. If you use another filename, use the -f argument on the Build command line to identify the file.[6] For example:

$ ./Build -f ourconfig.m4

As the file extension .m4 file implies, the Build configuration is created with m4 commands. Three commands are used to set the variables used by Build. These commands are:

define

The define command is a built-in m4 command. When it is used, any current value stored in the variable is replaced by the new value.

APPENDDEF

The APPENDDEF macro is an m4 macro used to append a value to an existing list of values stored in a variable. It does not replace the current value in the variable; it adds values to the end of a list of values.

PREPENDDEF

The PREPENDDEF macro is an m4 macro used to prepend a value to an existing list of values stored in a variable. It does not replace the current value in the variable; it adds values to the beginning of a list of values.

Here is an example of when a site.config.m4 file might be needed. While the sendmail software compiles without error on our sample Red Hat system, we encounter a problem when installing the manpages. The devtools/OS/Linux file that comes with sendmail 8.12.9 contains the following command, which puts the manpages in /usr/man:

define(`confMANROOT', `/usr/man/man')

Our sample Red Hat Linux system stores manpages in /usr/share/man. Therefore, we create the following devtools/Site/site.config.m4 file to set the manpage path to /usr/share/man:

$ cat devtools/Site/site.config.m4
define(`confMANROOT', `/usr/share/man/man')

m4 quoted strings are enclosed in unbalanced single quotes. The same unbalanced single quotes used with any m4 command are used in the site.config.m4 file.

Most custom Build configurations are no more complicated than this example. The next few recipes show additional examples of Build configurations. Those examples were chosen because the options they compile into sendmail are required by recipes later in this book. However, there are more than 100 variables that can be set for the Build configuration—far too many to cover with individual recipes. See the devtools/README file for a complete list.

It has always been necessary to compile sendmail before installing it. Starting with sendmail 8.12, a new step has been added to the installation procedure. sendmail 8.12 expects to find a user ID and a group ID named smmsp. If this user ID and group ID do not exist on your system, create them before installing sendmail because the sendmail binary is no longer installed as set-user-ID root. Traditionally, the sendmail binary was set-user-ID root so that any user could submit mail via the command line and have it written to the queue directory. However, this does not really require a set-user-ID root binary. With the proper directory permissions, a set-group-ID binary will work fine.

Before installing the freshly compiled sendmail, back up the current sendmail binary, the sendmail utilities, and your current sendmail configuration files. (You never know; you might need to drop back to the old sendmail configuration if the new one doesn’t work as anticipated.) Remember: if the previous version of sendmail was installed with a package manager, it should be removed using that package manager before the new sendmail software is installed.

Running Build install on the sample Red Hat system installs sendmail and the utilities, and it produces more than 100 lines of output. It should run without error. On our sample system, the install commands that place the manpages clearly show the path defined earlier in the devtools/Site/site.config.m4 file. Also notice that Build uses the smmsp user and group when it creates the clientmqueue directory and when it installs the sendmail binary. A quick check of the ownership and permissions for the queue directory and the sendmail binary shows this:

drwxrwx---    2 smmsp    smmsp        4096 Aug  7 16:22 clientmqueue
-r-xr-sr-x    1 root     smmsp      568701 Aug  7 16:51 /usr/sbin/sendmail

After sendmail is installed, it must be configured. Most of this book discusses how to configure sendmail to do what you want it to do.

See Also

The sendmail book covers compiling and installing sendmail in Chapter 2.

1.3. Compiling sendmail to Use LDAP

Problem

sendmail must be compiled with the correct options in order to read data from an LDAP server. The LDAP server must also be properly configured to understand queries from sendmail.

Solution

Use the command sendmail -bt -d0.1 to check the sendmail compiler options. If the string LDAPMAP appears in the “Compiled with:” list, there is no need to recompile sendmail. If LDAPMAP does not appear in the “Compiled with:” list, recompile sendmail to add LDAP support.

To add LDAP support, set LDAP values in the site.config.m4 file and recompile sendmail as shown below:

# cd /usr/local/src/sendmail-8.12.9/devtools/Site
# cat >> site.config.m4
               APPENDDEF(`confMAPDEF', `-DLDAPMAP')
               APPENDDEF(`confLIBS', `-lldap -llber')
               Ctrl-D
# cd /usr/local/src/sendmail-8.12.9
# ./Build -c

After recompiling sendmail, reinstall it:

# ./Build install

The LDAP server must also be configured to work with sendmail. Give the LDAP administrator a copy of the sendmail.schema file, which is found in the cf directory of the sendmail distribution. The LDAP administrator must store the sendmail.schema file in the appropriate directory on the LDAP server. For example, an LDAP server running OpenLDAP often stores schema files in the /etc/openldap/schema directory.

Next, the LDAP administrator must add the sendmail.schema file to the LDAP configuration. On a system running OpenLDAP, add the following include to the /etc/openldap/slapd.conf file:

include         /etc/openldap/schema/sendmail.schema

Restart LDAP on the LDAP server to ensure that the sendmail schema are included in the LDAP configuration. Here is an example from an LDAP server running OpenLDAP:

# ps -ax | grep slapd
 1426 ?        S      0:00 /usr/sbin/slapd -u ldap
# kill -TERM 1426
# /usr/sbin/slapd -u ldap

Discussion

In this recipe, two APPENDDEF commands are added to the site.config.m4 file. The first APPENDDEF command adds -DLDAPMAP to the list of supported map types stored in the confMAPDEF define. The second APPENDDEF command adds -lldap and -llber to the list of libraries stored in the confLIBS define. -llber is required because this sample system uses OpenLDAP.

Build is then used to recompile sendmail. The -c option on the Build command line is needed to make sure that Build detects the changes made to the site.config.m4 file. After recompiling, sendmail is reinstalled.

Now, rerunning sendmail with the -d0.1 option would show LDAPMAP included in the “Compiled with:” list. sendmail is now ready to be configured to use LDAP. Of course, this doesn’t mean that LDAP is ready to work with sendmail.

The sendmail distribution comes with schema designed to work with LDAP. The LDAP server must be configured to include these schema in order to understand and properly process queries from sendmail. For OpenLDAP, this is done by adding an include command to the slapd.conf file that points to the sendmail schema, as shown in the Solution section. Once this is done, LDAP is ready to work with sendmail’s standard schema.

See Also

Recipe 1.2 and Recipe 1.4 through Recipe 1.7 provide other examples of compiling sendmail. Refer to other recipes in this book for specific examples of reading sendmail data from an LDAP server. For information on LDAP, see Understanding and Deploying LDAP Directory Services by Howes, Smith, and Good (Macmillan) and LDAP System Administration by Gerald Carter (O’Reilly). The cf/README file covers this topic in the Using LDAP for Aliases, Maps, and Classes section. The sendmail book covers compiling sendmail in Section 2.2.

1.4. Adding the regex Map Type to sendmail

Problem

Support for the regex map type must be compiled into sendmail if the error message “class regex not available” is displayed when sendmail is run.

Solution

To add support for the regular expression map type, add MAP_REGEX to the confMAPDEF compiler variable in the site.config.m4 file and then recompile sendmail. Here is an example:

# cd /usr/local/src/sendmail-8.12.9/devtools/Site
# cat >> site.config.m4
               APPENDDEF(`confMAPDEF', `-DMAP_REGEX')
               Ctrl-D
# cd /usr/local/src/sendmail-8.12.9
# ./Build -c

After recompiling sendmail, reinstall it:

# ./Build install

Discussion

Attempting to run a configuration that specifies a regex map type on a sendmail system without regex support compiled in produces an error, as this test shows:

# sendmail -bt
sendmail.cf: line 115: readcf: map dottedquad: class regex not available
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> /quit

The first line after the sendmail -bt command is an error message. It tells us that line 115 in the sendmail.cf file contains a K command that defines a map using the regex map type, which results in an error because regex is not supported on this system.

The fix for this requires defining a local compiler variable in the site.config.m4 file in the devtools/Site directory. The APPENDDEF command used in the Solution section appends the -DMAP_REGEX command-line argument to any values that already exist in the confMAPDEF variable. The Build command that is used to recompile sendmail uses the -c flag to ensure that Build incorporates the new data from the site.config.m4 file.

After compiling sendmail, run it with the -bt and the -d0.1 command-line arguments to check the compiler options:

# sendmail -bt -d0.1
Version 8.12.9
 Compiled with: DNSMAP LOG MAP_REGEX MATCHGECOS MIME7TO8 MIME8TO7 NEWDB
                NAMED_BIND NETINET NETUNIX PIPELINING SCANF USERDB XDEBUG

============ SYSTEM IDENTITY (after readcf) ============
      (short domain name) $w = chef
  (canonical domain name) $j = chef.wrotethebook.com
         (subdomain name) $m = wrotethebook.com
              (node name) $k = chef
========================================================

ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> /quit

The “Compiled with:” line output by the -d0.1 argument displays the compiler options. This line should contain MAP_REGEX. If it does, configurations using the regex map type should now run successfully.

See Also

Recipe 1.2, Recipe 1.3, Recipe 1.5, Recipe 1.6, and Recipe 1.7 provide other examples of compiling sendmail. Recipe 6.10 uses the regex map type. The sendmail book covers compiling sendmail in Section 2.2.

1.5. Compiling sendmail with SASL Support

Problem

sendmail must be compiled with SASL support before it can be configured to offer the AUTH protocol extension.

Solution

Check the sendmail compiler options. If sendmail was compiled with the SASL flag, it does not need to be recompiled. If sendmail was not compiled with SASL support, add SASL to the -D flags used to specify compiler environment information, add sasl to the -l flags used to select libraries for linking, and recompile sendmail. After recompiling sendmail, reinstall and restart it.

Discussion

Use the -d0.1 flag to check the compiler options of the sendmail binary. The SASL flag should be clearly shown in the “Complied with:” list, as in this example:

# sendmail -bt -d0.1
Version 8.12.9
 Compiled with: DNSMAP LOG MAP_REGEX MATCHGECOS MIME7TO8 MIME8TO7
                NAMED_BIND NETINET NETUNIX NEWDB PIPELINING SASL
                SCANF USERDB XDEBUG

============ SYSTEM IDENTITY (after readcf) ============
      (short domain name) $w = chef
  (canonical domain name) $j = chef.wrotethebook.com
         (subdomain name) $m = wrotethebook.com
              (node name) $k = chef
========================================================

ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> /quit

If the flag is not displayed, create a site.config.m4 file in the devtools/Site directory that contains the following commands:

               APPENDDEF(`conf_sendmail_ENVDEF', `-DSASL')
               APPENDDEF(`conf_sendmail_LIBS', `-lsasl')

Recompile, reinstall, and restart sendmail, as in this example:

# cd /usr/local/src/sendmail-8.12.9
# ./Build -c
               ...many lines of output deleted...
# cd /usr/local/src/sendmail-8.12.9/sendmail
# ./Build install
               ...many lines of output deleted...
# kill -HUP `head -1 /var/run/sendmail.pid`

See Also

Recipe 1.2, Recipe 1.3, Recipe 1.4, Recipe 1.6, and Recipe 1.7 provide additional examples of compiling sendmail. Chapter 7 covers SASL and AUTH configuration. The sendmail book covers AUTH configuration in Section 10.9 and compiling sendmail in Section 2.2. See the sysadmin.html file in the SASL documentation directory for additional information about SASL configuration.

1.6. Compiling sendmail with STARTTLS Support

Problem

sendmail must be specially compiled to support the STARTTLS extension.

Solution

Use the command sendmail -bt -d0.1 to check the sendmail compiler options. If the string STARTTLS appears in the “Compiled with:” list, there is no need to recompile sendmail. If sendmail was not compiled with STARTTLS support, edit the devtools/Site/site.config.m4 file to add STARTTLS to the compiler’s -D flags and to add ssl and crypto to the -l flags used to select libraries for linking. See the following example:

# cd /usr/local/src/sendmail-8.12.9/devtools/Site
# cat >> site.config.m4
               APPENDDEF(`conf_sendmail_ENVDEF', `-DSTARTTLS')
               APPENDDEF(`conf_sendmail_LIBS', `-lssl -lcrypto')
               Ctrl-D

Recompile, reinstall, and restart sendmail:

# cd /usr/local/src/sendmail-8.12.9
# ./Build -c
               ...many lines of output deleted...
# ./Build install
               ...many lines of output deleted...
# kill -HUP `head -1 /var/run/sendmail.pid`

Discussion

In the sample site.config.m4 file, the first APPENDDEF command adds -DSTARTTLS to the list of compiler options stored in the conf_sendmail_ENVDEF define. The second APPENDDEF command adds -lssl and -lcrypto to the list of libraries stored in the conf_sendmail_LIBS define.

Build is then used to recompile sendmail. The -c option on the Build command line ensures that Build detects the changes made to the site.config.m4 file. Build install is run to install the freshly compiled sendmail binary. The HUP signal is used to restart sendmail with the new binary.

After recompiling sendmail, rerunning sendmail with the -d0.1 option shows that STARTTLS is included in the “Compiled with:” list. sendmail can now be configured to offer STARTTLS as described in Chapter 8.

See Also

Recipe 1.2 to Recipe 1.5 provide further information on compiling sendmail. Additionally, Recipe 1.7 provides information on fixing a problem that may appear when recompiling sendmail to support STARTTLS. Chapter 8 covers STARTTLS configuration. The sendmail book covers compiling sendmail in Section 2.2 and STARTTLS in Section 10.10.

1.7. Compiling in STARTTLS File Paths

Problem

When compiling sendmail to support the STARTTLS extension, “No such file or directory” errors are displayed in regard to OpenSSL files.

Solution

Set the correct path values in conf_sendmail_INCDIRS and conf_sendmail_LIBDIRS to tell sendmail where the OpenSSL files are located. Add the defines to the site.config.m4 configuration file, as in this example:

# cd /usr/local/src/sendmail-8.12.9/devtools/Site
# cat >> site.config.m4
               APPENDDEF(`conf_sendmail_INCDIRS', `-I/usr/share/ssl/include')
               APPENDDEF(`conf_sendmail_LIBDIRS', `-L/usr/share/ssl/lib')
               Ctrl-D

Recompile, reinstall, and restart sendmail:

# cd /usr/local/src/sendmail-8.12.9
# ./Build -c
               ...many lines of output deleted...
# ./Build install
               ...many lines of output deleted...
# kill -HUP `head -1 /var/run/sendmail.pid`

Discussion

The sendmail configuration assumes that OpenSSL is installed in the standard location. If it is not, “No such file or directory” errors are displayed during the sendmail build when the system attempts to use the OpenSSL files. Use APPENDDEF commands to add the correct location of the OpenSSL include file to the conf_sendmail_INCDIRS variable and the correct location of the OpenSSL library to the conf_sendmail_LIBDIRS variable. The APPENDDEF commands are added to the site.config.m4 file.

After defining the correct values in site.config.m4, recompile sendmail with the Build -c command. If the path values are correctly defined, the build should run without errors.

See Also

Recipe 1.2 to Recipe 1.6 provide additional information on compiling sendmail. In particular, Recipe 1.6 provides an example of compiling sendmail with STARTTLS support. Chapter 8 covers STARTTLS configuration. The sendmail book covers compiling sendmail in Section 2.2 and STARTTLS in Section 10.10.

1.8. Building a sendmail Configuration

Problem

sendmail configurations are written using m4 macros. The configuration must be processed by m4 to produce the sendmail.cf configuration file that is read by sendmail.

Solution

Change to the configuration directory.

Create the m4 master configuration file. For this example, we name the master configuration file sendmail.mc.

Build the sendmail.cf file, copy it to the standard directory, and restart the sendmail daemon:

# ./Build sendmail.cf
Using M4=/usr/bin/m4
rm -f sendmail.cf
/usr/bin/m4 ../m4/cf.m4 sendmail.mc > sendmail.cf || ( rm -f sendmail.cf && exit 1 )
chmod 444 sendmail.cf
# cp /etc/mail/sendmail.cf /etc/mail/sendmail.cf.bak
# cp sendmail.cf /etc/mail/sendmail.cf
# kill -HUP `head -1 /var/run/sendmail.pid`

Notice, in this example, that sendmail is restarted with a HUP signal. This assumes that sendmail is already running with some current configuration, which is a good assumption for the majority of recipes in this book. If, however, sendmail has just been installed, is not running, and has not been previously configured, use Build install-cf to properly install both the sendmail.cf file and the submit.cf file. See Recipe 1.8.3.3 of the following discussion for an example of the Build install-cf command.

Discussion

New sendmail configurations are generally built inside the cf/cf directory. Of course, cf/cf is a relative path, so where this directory is located can vary from system to system. For example, the Red Hat RPM places the configuration files in /usr/share/sendmail-cf/cf. If you’re using the sendmail distribution, the cf/cf directory is relative to where you installed the distribution. All of the examples in this book assume you’re using the sendmail 8.12.9 distribution and that you installed it in /usr/local/src. Given these assumptions, the following cd command would put you in the correct directory:

# cd /usr/local/src/sendmail-8.12.4/cf/cf

Next, create a master configuration file and make any necessary edits to that file. You can create a configuration file from scratch, start with a generic configuration provided by the sendmail developers, or start with a configuration provided by your vendor. Typing in your own configuration file from scratch is easy because sendmail master configuration files are very short. However, the sendmail developers provide a full set of generic and prototype files that are generally a good place to start.

The examples in this book are modifications to the generic-linux.mc configuration file that comes with the sendmail distribution. Therefore, we copy the generic-linux.mc file, which is the best match for our sample Linux system, to sendmail.mc, which we use as a working file. The generic-linux.mc file contains the following lines:

divert(-1)
#
# Copyright (c) 1998, 1999 Sendmail, Inc. and its suppliers.
#       All rights reserved.
# Copyright (c) 1983 Eric P. Allman.  All rights reserved.
# Copyright (c) 1988, 1993
#       The Regents of the University of California.  All rights reserved.
#
# By using this file, you agree to the terms and conditions set
# forth in the LICENSE file which can be found at the top level of
# the sendmail distribution.
#
#

#
#  This is a generic configuration file for Linux.
#  It has support for local and SMTP mail only.  If you want to
#  customize it, copy it to a name appropriate for your environment
#  and do the modifications there.
#

divert(0)dnl
VERSIONID(`$Id: ch01.xml,v 1.7 2004/08/05 20:57:13 becki Exp $')
OSTYPE(linux)dnl
DOMAIN(generic)dnl
MAILER(local)dnl
MAILER(smtp)dnl

The divert(-1) command starts a section of comments that ends with a divert(0) command. Therefore, only the last five lines of the generic file are active lines—the rest of the file consists of comments.

The VERSIONID macro specifies version information that is formatted in any way you choose. If you use a version control system, you should probably format the information to be compatible with that system. In any case, you should change this information when you edit the file to indicate when the file was changed and by whom.

The OSTYPE macro loads the configuration required for the operating system. In this case, the file being loaded is /ostype/linux.m4 as you would expect with the generic Linux configuration. We will return to the linux.m4 file shortly to look at its contents.

The DOMAIN macro loads a configuration file designed specifically for your domain. The generic-linux.mc file is a sample file, and the domain/generic.m4 file that it loads with the DOMAIN macro is also a sample file. Although it is not specifically designed for your domain, the generic.m4 file is designed to be harmless. The contents of the domain/generic.m4 file are covered later.

If you do create a custom domain file, note that there is an interesting side effect when all of the configuration changes happen in the domain file and the master configuration file is unchanged. Rebuilding the sendmail.cf file with the Build script may generate the following error:

# ./Build sendmail.cf
Using M4=/usr/bin/m4
make: `sendmail.cf' is up to date.

Build does not check for changes in the domain file. It sees that sendmail.mc is unchanged since the last build and it refuses to create a new sendmail.cf file. Bypass this problem by removing the old sendmail.cf file, by running touch sendmail.mc before running Build, or by using m4 instead of Build to rebuild the sendmail.cf file.

The last two macros in the generic-linux.mc file are MAILER macros. The first MAILER macro loads mailer/local.m4, which defines the following mailers:

local

The local mailer delivers mail to user accounts located on this system.

prog

The prog mailer is used by sendmail to route mail to other processes running on the local system.

Both the local and prog mailers are used in most sendmail configurations.

The second MAILER macro loads mailer/smtp.m4, which defines these mailers:

esmtp

The Extended SMTP (ESMTP) mailer handles the standard TCP/IP mail protocol, including complex message bodies and MIME content types. This is the default mailer used by sendmail for SMTP mail.

relay

The relay mailer is used to relay SMTP mail through another mail host. Relaying and mail relay hosts are used in Chapter 3.

smtp

The smtp mailer handles only old-fashioned, 7-bit ASCII SMTP mail. sendmail only uses this mailer when specially configured to do so; for example, if directed to do so by an entry in the mailertable database. The mailertable is used in recipes in Chapter 5.

smtp8

The smtp8 mailer is designed to work with remote systems that can handle 8-bit mail but do not understand the standard ESMTP protocol. sendmail only uses this mailer when specially configured to do so; for example, if it is directed to do so by an entry in the mailertable database.

dsmtp

The dsmtp mailer allows the destination host to retrieve mail queued on the mail server. Normally, mail is “pushed” from the source to the destination; the source initiates the connection. This mailer allows the destination host to “pull” mail from the source when it is ready to receive mail by using the optional ETRN SMTP command. sendmail only uses this mailer when specially configured to do so.

The two MAILER macros add the essential mailers to the configuration. The DOMAIN macro, which loads the domain/generic.m4 file, and the OSTYPE macro, which loads the ostype/linux.m4 file, also add settings to the configuration. Examine the generic.m4 and linux.m4 files to see exactly what those settings are.

The linux.m4 file

Every master configuration file contains an OSTYPE macro.[7] To fully understand a configuration, you must know exactly what parameters are set by this file. This book uses Linux as a sample operating system and linux.m4 as a sample ostype file. You, however, should examine the ostype file specific to your operating systems before using the recipes that follow in later chapters.

After an opening block of comments, the linux.m4 file contains the following active lines:

VERSIONID(`$Id: ch01.xml,v 1.7 2004/08/05 20:57:13 becki Exp $')
define(`confEBINDIR', `/usr/sbin')
ifdef(`PROCMAIL_MAILER_PATH',,
        define(`PROCMAIL_MAILER_PATH', `/usr/bin/procmail'))
FEATURE(local_procmail)

We have already discussed VERSIONID, so there is no need to go over it again.

The define command defines the path to the directory where certain executables, particularly the sendmail Restricted Shell (smrsh), are stored. The default for confEBINDIR is /usr/libexec. This define sets it to /usr/sbin, which is correct for Linux systems.

Notice that different single quote marks are used to open and close a quoted string in an m4 command. The open quote mark is ` and the close quote mark is ‘. These quote marks are only required when the string contains a blank, a special character, or a keyword. However, the quote marks are frequently used, and when they are used, the quotes must appear exactly as shown.

The ifdef command is a built-in m4 command. It contains three comma-separated fields:

  • First, the name of the variable being tested, which is PROCMAIL_MAILER_PATH in this example.

  • Second, the action taken if the variable has been set. In this case, no action is taken because the second field is empty, as indicated by the two commas in a row.

  • Third, the action taken if the variable has not been set. In the linux.m4 file, the define command that sets PROCMAIL_MAILER_PATH to /usr/bin/procmail is executed only if the variable has not been set previously. PROCMAIL_MAILER_PATH is not set anywhere else in this configuration, so this define executes and sets the variable.

The last line in the linux.m4 file is a FEATURE macro that adds the local_procmail feature to the configuration. The local_procmail feature causes sendmail to use procmail as the local mailer. procmail is a program with very powerful mail filtering features. procmail is used in Chapter 6.

The generic.m4 file

After the OSTYPE macro adds the linux.m4 file to the configuration, the DOMAIN macro adds the domain/generic.m4 file. It contains the following active lines:

VERSIONID(`$Id: ch01.xml,v 1.7 2004/08/05 20:57:13 becki Exp $')
define(`confFORWARD_PATH', `$z/.forward.$w+$h:$z/.forward+$h:$z/.forward.$w:$z/.
forward')dnl
define(`confMAX_HEADERS_LENGTH', `32768')dnl
FEATURE(`redirect')dnl
FEATURE(`use_cw_file')dnl
EXPOSED_USER(`root')

We know what the VERSIONID macro does, so there is no need to cover it again.

The first define command sets a value for the confFORWARD_PATH variable, which tells sendmail where to search for .forward files. The confFORWARD_PATH variable is discussed in more detail in Introduction to Chapter 2 and in Recipe 10.8.

The second define command sets the value of the confMAX_HEADERS_LENGTH variable. In turn, this m4 variable sets the value for the sendmail.cf MaxHeadersLength option. This value is the maximum number of header bytes sendmail will allow for a message. The define sets this value to 32,768, which is the default used when no value is defined.

The first FEATURE macro enables the redirect feature. This is a useful feature that can be used to return a message to the sender telling him the correct address of a recipient whose address has changed. The redirect feature is used in Recipe 2.8, where it is explained in detail.

The second FEATURE macro enables the use_cw_file feature. This feature causes sendmail to load class $=w from the file local-host-names. When and how to use this feature are covered in Recipe 2.1

Finally, the EXPOSED_USER macro is used to add the username root to class $=E. Values in class $=E are exempted from masquerading when masquerading is used to hide hostnames or usernames. The EXPOSED_USER macro is used repeatedly in Chapter 4.

The generic-linux.mc file, the linux.m4 file, and the generic.m4 domain file are combined to create a configuration that:

  • Sets the confBINDIR directory path to /usr/sbin

  • Sets the path of procmail to /usr/bin/procmail

  • Uses procmail as the local mailer

  • Defines a search path for .forward files

  • Sets the maximum length of the headers on a message to 32,768 bytes

  • Enables the redirect feature

  • Loads class $=w from the local-host-names file

  • Exempts the root user from masquerading

  • Defines the complete set of local and SMTP mailers

Because the generic-linux.mc file incorporates both the linux.m4 file and the generic.m4 file, all of the configuration settings just listed have been made part of the sendmail.mc file simply by copying the generic-linux.mc file. It is this sendmail.mc file that is the basic configuration modified in subsequent recipes to create custom configurations.

Building and installing sendmail.cf

Run Build to create the sendmail.cf file from the sendmail.mc file. The Build script is easy to use. Provide the name of the output file you want to create as an argument on the Build command line. The script replaces the .cf extension of the output file with the extension .mc and uses the macro configuration file with that name to create the output file. Thus, putting sendmail.cf on the Build command line means that sendmail.mc is used to create sendmail.cf.

Despite the simplicity of Build, many administrators never use it to build a sendmail configuration because the m4 command line used to build a sendmail configuration is also very simple:

$ m4 ../m4/cf.m4 sendmail.mc > sendmail.cf

For the average sendmail administrator, the Build script doesn’t offer any critical advantages. For most of us, deciding to use Build or m4 is primarily a matter of personal preference. It is even possible to invoke the Makefile directly with a basic make command. In this book, we use both Build and m4 to build the sendmail configuration file. Use whichever method you prefer.

The Build script makes it simple for the people who maintain the sendmail distribution to build a .cf file for each .mc file in the cf/cf directory with a single Build all command. If you need to build multiple configurations, it is possible to edit the Makefile, changing the $OTHER variable so that it contains the names of all of the configurations you wish to build, and to then use Build other to create all of those configurations at one time. However, most administrators do not have enough different configurations to bother with this.

After building the new sendmail.cf file, copy that file to the location where sendmail expects to find its configuration file. On our sample Red Hat system, that location is /etc/mail/sendmail.cf. In most cases, this is simply done with a cp command. However, it can also be done with Build, as follows:

# cd cf/cf
# ./Build install-cf
Using M4=/usr/bin/m4
../../devtools/bin/install.sh -c -o root -g bin -m 0444 sendmail.cf /etc/mail/
sendmail.cf
../../devtools/bin/install.sh -c -o root -g bin -m 0444 submit.cf /etc/mail/submit.cf

The Build install-cf command used above installs two configuration files: the sendmail.cf file that is the primary focus of this book and a second file named submit.cf. This file doesn’t exist unless you create it, but a full submit.cf is delivered with the sendmail distribution. The submit.cf file is a special configuration used when sendmail is invoked by a user from the command line to submit a piece of mail. sendmail.cf is the configuration file used by the sendmail daemon. The Build install-cf command is generally used when a new sendmail distribution is first installed to ensure that both the sendmail.cf and submit.cf files are installed. Other than the initial installation, however, there is generally no need to copy both files at the same time because it is not usually necessary to create a new submit.cf file when you create a new sendmail.cf file.

Once the configuration is installed, start sendmail to force it to read the new configuration. In this recipe’s Solution section, sendmail is restarted by sending it the HUP signal with a kill command. This method of restarting sendmail uses standard sendmail signal processing that is available on any system, which makes the kill command technique vendor neutral. Many readers will be familiar with embedding a cat command inside a kill command to retrieve the process ID stored in a PID file. An interesting aspect of the kill command used to restart sendmail is the manner in which the sendmail process ID is retrieved from the sendmail.pid file. Here is the example again:

# kill -HUP `head -1 /var/run/sendmail.pid`

Using cat instead of head in this command would not work because sendmail writes a multiline PID file. A cat of /var/run/sendmail.pid on our sample system shows this:

# cat /var/run/sendmail.pid
1076
/usr/sbin/sendmail -bd -q15m

The content of this file is of more than just passing interest to someone planning to restart sendmail with a HUP signal. The first line is the process ID you expect to find in a PID file. The second line of this file is the command that was used to start sendmail. The command must contain the full pathname of the sendmail program in order for the HUP signal to successfully restart sendmail. If the second line of this file shows a partial (or relative) pathname, HUP terminates the currently running sendmail, but it does not start a new copy of sendmail. In effect, sending a HUP signal to sendmail, when the current version of sendmail was not executed using its full pathname, kills sendmail, which, of course, is not what you intended. To be safe, always start sendmail using the full pathname.

Of course, the HUP signal is only used to restart sendmail, which implies that sendmail is already running. The first time sendmail is installed on a system, it is started from the command line using a sendmail command. Here is an example:

# /usr/sbin/sendmail -bd -q15m
# /usr/sbin/sendmail -L sm-msp -Ac -q15m

The -bd option used on the first command line causes sendmail to run as a daemon and listen for incoming mail on ports 25 and 587. This first command creates the sendmail daemon that reads the sendmail.cf configuration file and runs in the traditional role of a mail transfer agent (MTA). The second command starts sendmail as a mail submission program. The -Ac option on this command line directs sendmail to read the submit.cf configuration file. The -L option tells this copy of sendmail to use the name sm-msp when it logs messages. Without the -L option, both copies of sendmail would log messages using the name sendmail making it difficult to determine which copy of sendmail logged the message. The -q15m option on both command lines direct each copy of sendmail to process its mail queue every 15 minutes. See Chapter 9 for more information on mail queues.

Some systems provide their own tools for starting daemons. For example, a Red Hat system using an RPM version of sendmail can start sendmail with the service command:

# service sendmail start
Starting sendmail: [  OK  ]

Regardless of how sendmail is started or restarted, when the daemon starts, it reads in the configuration file /etc/mail/sendmail.cf, which now contains the new configuration.

This recipe is the basic configuration recipe upon which most of the recipes in this book are built. Subsequent chapters describe solutions to specific problems. These solutions are often shown in the context of this basic recipe. You will need to take those solutions and place them in the basic configuration that you build for your server. We use a basic foundation recipe for subsequent solutions for two reasons:

  • First, covering the basic configuration here eliminates the need to repeat this long description over and over again for every recipe, which, in turn, allows us to focus on the unique aspects of those recipes. We explain the basic recipe once and then assume you understand the basic configuration statements as we move forward. Recipes naturally have lots of repetition; this reduces some of it.

  • Second, the basic recipe provides a consistent reference point for subsequent recipes. By creating a baseline configuration that you can use as a starting point for most recipes in this book, we ensure that you can duplicate our test results on your system.

See Also

The sendmail book covers the VERSIONID macro in Section 4.2.3.1, the OSTYPE macro in Section 4.2.2.1, the DOMAIN macro in 4.2.2.3, and the MAILER macro in Section 4.2.2.2. All of the m4 macros and configuration commands are covered in the cf/README file delivered with the sendmail distribution.

1.9. Testing a New Configuration

Problem

You need to test the sendmail configuration before it is deployed.

Solution

Use the sendmail command-line options -bt, -bv, and -v.

Discussion

At the end of Recipe 1.8, the newly created sendmail.cf is copied over the old configuration. Do not copy a customized configuration into the /etc/mail directory until it is thoroughly tested. sendmail provides excellent test tools that are used extensively in this book.

The single most important tool for testing sendmail is sendmail itself. When started with the -bt command-line option, sendmail enters test mode . While in test mode, sendmail accepts a variety of commands that examine the configuration, check settings, and observe how email addresses are processed by sendmail. Table 1-2 lists the commands that are available in test mode.

Table 1-2. sendmail test mode commands

Command

Usage

rulesets address

Process the address through the comma-separated list of rulesets.

=S ruleset

Display the contents of the ruleset.

=M

Display all of the mailer definitions.

$ v

Display the value of macro v.

$= c

Display the values in class c.

.D vvalue

Set the macro v to value.

.C cvalue

Add value to class c.

-d value

Set the debug level to value.

/tryflags flags

Set the flags used for address processing by /try.

/try mailer address

Process the address for the mailer.

/parse address

Return the mailer/host/user delivery triple for the address.

/canon hostname

Canonify hostname.

/mx hostname

Lookup the MX records for hostname.

/map mapname key

Look up key in the database identified by mapname.

/quit

Exit address test mode.

Several commands (=S, =M, $ v, and $= c) display current sendmail configuration values defined in the sendmail.cf file, and the /map command displays values set in the sendmail database files. The -d command can be used to change the amount of information displayed. A great many debug levels can be set by -d, but only a few are useful to the sendmail administrator. All of the debug values are covered in the sendmail book, and a few of the most useful values are discussed in this book.

Two commands, .D and .C , are used to set macro and class values in real time. Use these commands to try alternate configuration settings before rebuilding the entire configuration.

Two commands display the interaction between sendmail and DNS. /canon displays the canonical name returned by DNS for a given hostname. /mx shows the list of mail exchangers returned by DNS for a given host.

Most of the remaining commands process an email address through sendmail’s rewrite rules. /parse displays the processing of a delivery address and shows which mailer is used to deliver mail sent to the address. /try displays the processing of addresses for a specific mailer. (The /tryflags command specifies whether the sender or the recipient address should be processed by the /try command.) Use the ruleset address command to display the processing of an address through any arbitrary list of rulesets that you wish to test.

The following example uses sendmail test mode to check the configuration created in Recipe 1.8. Invoke the sendmail command with the -bt option to enter test mode and the -C option to specify the configuration file to be tested. If the -C option is not used, the current configuration file (/etc/mail/sendmail.cf) is the configuration that is tested.

The following test displays the mailer configuration in the form of a list of sendmail.cf M commands:

# sendmail -bt -C/usr/local/src/sendmail-8.12.9/cf/cf/sendmail.cf
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter <ruleset> <address>
> =M
mailer 0 (prog): P=/bin/sh S=EnvFromL/HdrFromL R=EnvToL/HdrToL M=0 U=0:0
                 F=9DFMeloqsu L=0 E=\n T=X-Unix/X-Unix/X-Unix r=100
                 A=sh -c $u
mailer 1 (*file*): P=[FILE] S=parse/parse R=parse/parse M=0 U=0:0
                   F=9DEFMPloqsu L=0 E=\n T=X-Unix/X-Unix/X-Unix r=100
                   A=FILE $u
mailer 2 (*include*): P=/dev/null S=parse/parse R=parse/parse M=0 U=0:0
                      F=su L=0 E=\n T=<undefined>/<undefined>/<undefined>
                      r=100 A=INCLUDE $u
mailer 3 (local): P=/usr/bin/procmail S=EnvFromL/HdrFromL R=EnvToL/HdrToL
                  M=0 U=0:0 F=/59:@ADFMPSfhlnqsw| L=0 E=\n
                  T=DNS/RFC822/X-Unix r=100 A=procmail -Y -a $h -d $u
mailer 4 (smtp): P=[IPC] S=EnvFromSMTP/HdrFromSMTP R=EnvToSMTP/EnvToSMTP
                 M=0 U=0:0 F=DFMXmu L=990 E=\r\n T=DNS/RFC822/SMTP r=100
                 A=TCP $h
mailer 5 (esmtp): P=[IPC] S=EnvFromSMTP/HdrFromSMTP R=EnvToSMTP/EnvToSMTP
                  M=0 U=0:0 F=DFMXamu L=990 E=\r\n T=DNS/RFC822/SMTP r=100
                  A=TCP $h
mailer 6 (smtp8): P=[IPC] S=EnvFromSMTP/HdrFromSMTP R=EnvToSMTP/EnvToSMTP
                  M=0 U=0:0 F=8DFMXmu L=990 E=\r\n T=DNS/RFC822/SMTP r=100
                  A=TCP $h
mailer 7 (dsmtp): P=[IPC] S=EnvFromSMTP/HdrFromSMTP R=EnvToSMTP/EnvToSMTP
                  M=0 U=0:0 F=%DFMXamu L=990 E=\r\n T=DNS/RFC822/SMTP
                  r=100 A=TCP $h
mailer 8 (relay): P=[IPC] S=EnvFromSMTP/HdrFromSMTP R=MasqSMTP/MasqSMTP
                  M=0 U=0:0 F=8DFMXamu L=2040 E=\r\n T=DNS/RFC822/SMTP
                  r=100 A=TCP $h 
> /quit

The output shows that all of the SMTP mailers are configured, and so are the prog and local mailers. An examination of the P parameter in the Mlocal line also shows that procmail is being used as the local mailer, which verifies the effect of the local_procmail feature. Additionally, the P parameter shows that the path to this program matches the one configured by the PROCMAIL_MAILER_PATH define.

sendmail can also be tested by using the -bv command-line option. The -bv option processes an address through sendmail and displays the mail delivery triple for that address. For example:

# sendmail -bv tyler@example.com
tyler@example.com... deliverable: mailer esmtp, host example.com, user 
tyler@example.com

This example clearly shows the mailer, host, and user address of the mail delivery triple. In this case, the mail will be addressed to tyler@example.com, sent to the host example.com for delivery, and sent to that host using the esmtp mailer.

When a -bv test is run with an address that is directly delivered by the local host, it has the added benefit of applying aliasing to that address and of verifying if the address is deliverable. Here are some examples:

# sendmail -bv craig
craig... deliverable: mailer local, user craig
# sendmail -bv fred
fred... User unknown
# sendmail -bv admin
anna@crab.wrotethebook.com... deliverable: mailer esmtp, host crab.wrotethebook.com., 
user anna@crab.wrotethebook.com
andy@rodent.wrotethebook.com... deliverable: mailer esmtp, host rodent.wrotethebook.
com., user andy@rodent.wrotethebook.com
jane@rodent.wrotethebook.com... deliverable: mailer esmtp, host rodent.wrotethebook.
com., user jane@rodent.wrotethebook.com

The first test shows that craig is a local username deliverable through the local mailer. The second test shows that fred is not a valid local username. The final test shows that admin is expanded by aliasing into three addresses that are forwarded via the esmtp mailer to remote systems for delivery. There are other commands, such as praliases, which allow you to examine the aliases file, but sendmail -bv is the best for seeing exactly how aliasing affects a local delivery address.

Both the -bt and -bv arguments show how the local copy of sendmail handles mail. To examine the interaction with a remote system, sendmail can be used to deliver mail with the verbose (-v) option set. For example:

$ sendmail -v craig@wrotethebook.com < test.msg
craig@wrotethebook.com... Connecting to chef.wrotethebook.com. via esmtp...
220 chef.wrotethebook.com ESMTP Sendmail 8.12.4/8.12.4; Sat, 2 Aug 2003 16:57:35 -
0400
>>> EHLO rodent.wrotethebook.com
250-chef.wrotethebook.com Hello rodent.wrotethebook.com [192.168.0.3], pleased to 
meet you
250-ENHANCEDSTATUSCODES
250-PIPELINING
250-EXPN
250-VERB
250-8BITMIME
250-SIZE
250-DSN
250-ETRN
250-DELIVERBY
250 HELP
>>> MAIL From:<craig@rodent.wrotethebook.com> SIZE=26
250 2.1.0 <craig@rodent.wrotethebook.com>... Sender ok
>>> RCPT To:<craig@wrotethebook.com>
550 5.7.1 <craig@wrotethebook.com>... Relaying denied
>>> RSET
250 2.0.0 Reset state
/home/craig/dead.letter... Saved message in /home/craig/dead.letter
Closing connection to chef.wrotethebook.com.
>>> QUIT
221 2.0.0 chef.wrotethebook.com closing connection

Testing sendmail with the -v argument is useful when you want to see the entire protocol interaction. Notice, however, that in the test above there is a “Relaying denied” error message in the line that begins with the code 550. If the real point of this test was to check the recipient address against the remote host, you might not want to see the entire protocol interaction. In that case, using telnet to connect to the SMTP port of the remote system might be a better test tool. For example:

$ telnet chef.wrotethebook.com smtp
Trying 192.168.0.8...
Connected to chef.wrotethebook.com.
Escape character is '^]'.
220 chef.wrotethebook.com ESMTP Sendmail 8.12.9/8.12.9; Sat, 2 Aug 2003 16:57:35 -
0400
HELO rodent.wrotethebook.com
250-chef.wrotethebook.com Hello rodent.wrotethebook.com [192.168.0.3], pleased to 
meet you
MAIL From:<craig@rodent.wrotethebook.com>
250 2.1.0 <craig@rodent.wrotethebook.com>... Sender ok
RCPT To:<craig@wrotethebook.com>
550 5.7.1 <craig@wrotethebook.com>... Relaying denied
QUIT
221 2.0.0 chef.wrotethebook.com closing connection
Connection closed by foreign host.

Using telnet, you can go directly to the specific protocol interaction that you wish to test.

It is important to test sendmail thoroughly before deploying a new configuration. In this book, we use all of the test methods described here.

See Also

The sendmail book covers the -bt option in Chapter 8, the -bv option in Section 15.7.15, and the -v option in Section 15.7.45.

1.10. Logging sendmail

Problem

Debugging a problem in the sendmail configuration may require more detailed information than sendmail logs by default.

Solution

Use the LogLevel option, either on the sendmail command line using the -O flag or in the sendmail configuration using the confLOG_LEVEL define, to increase the LogLevel above the default level of 9.

If the confLOG_LEVEL define is used, rebuild and reinstall sendmail.cf, and restart sendmail, as described in Recipe 1.8.

Discussion

sendmail logs messages through syslog using the mail facility. Where the messages are logged is determined by the syslog.conf file. A grep of syslog.conf shows where the sendmail messages are logged on our sample Linux system:

$ grep mail /etc/syslog.conf
# Log anything (except mail) of level info or higher.
*.info;mail.none;authpriv.none;cron.none            /var/log/messages
# Log all the mail messages in one place.
mail.*                                              /var/log/maillog

Disregarding the comments, there are two lines in this particular syslog.conf file that mention the mail facility. The first line has a wildcard character in the facility field, meaning that it applies to every syslog facility. At first glance, you might think this applies to sendmail messages until you notice mail.none, which means that no messages from the mail facility will be logged in /var/log/messages. /var/log/maillog is the place to look for sendmail log entries on this sample Linux system. The mail.* entry means that, no matter what the level, all messages from the mail facility are logged in /var/log/maillog. Of course, this syslog.conf file is specific to our sample system. Your file might look different and, even if it looks exactly like this one, you can change it in anyway that you wish. You completely control where sendmail logs messages.

The syslog.conf file controls where sendmail messages are logged. The sendmail LogLevel option controls what is logged. The default sendmail LogLevel is 9, which is roughly equivalent to the syslog level info. Increasing the value of LogLevel increases the amount of data that sendmail logs. The meaningful LogLevel values are:

0

Log a limited number of severe problems, such as failing to find the system’s hostname or qualified domain name.

1

Log serious system failures using syslog crit and alert levels.

2

Log networking failures at crit level.

3

Log connection timeouts, malformed addresses, and forward and include errors using notice and error syslog levels.

4

Log connection rejections, bad qf filenames, and outdated aliases databases using info and notice levels.

5

Log envelope cloning, and log an entry for each message received. These log entries are made at the syslog info level.

6

Log a record of each message returned to the original sender, and log incoming SMTP VRFY, EXPN, and ETRN commands using the info level.

7

Log delivery failures at the info level.

8

Log successful deliveries and alias database rebuilds at the syslog notice level.

9

Log mail deferred because of lack of system resources at the info level.

10

Log inbound SMTP connections and MILTER connects and replies. Log each database lookup. Log AUTH and STARTTLS errors. All of these messages are logged at info level. Also log TLS errors at syslog warning level.

11

Log end of processing, and log NIS errors. Log both types of messages at info level.

12

Log outbound SMTP connections at info level.

13

Log questionable file security, such as world-writable files and bad user shells.

14

Log connection refusals. Log additional STARTTLS information. Log both types of messages at info level.

15

Log all incoming SMTP commands at info level.

16-98

Log debugging information at debug level. This data is mostly suitable for code developers.

Setting LogLevel causes all levels below the specified number to also be logged. Thus the default LogLevel of 9 also logs all of the messages described for levels 1 through 8. Each LogLevel adds more detail while continuing to log the messages of the lower LogLevel settings.

LogLevel can be set inside the sendmail configuration using the confLOG_LEVEL define. For example:

define(`confLOG_Level', `14')

However, it is often only necessary to increase LogLevel for a short time or for a single test run. This can be done by defining LogLevel on the sendmail command line using the -O argument. Here is an example:

# sendmail -O LogLevel=14 -bs -Am

This example runs sendmail from the command line. The -Am argument, which does not apply to sendmail versions before 8.12, ensures that sendmail runs as an MTA—this argument is the opposite of the -Ac option discussed earlier in this chapter. The -bs argument allows you to manually input the SMTP commands in a manner similar to the telnet tests used in the previous recipe. The -O argument allows you to set the LogLevel from the command line. A command such as this might be used to log the effect of specific SMTP interactions.

Both techniques for setting LogLevel work well. The technique you use depends on the circumstances and your preference.

See Also

The sendmail book covers logging in Section 14.3 and LogLevel in Section 24.9.56.



[1] Most of the ls command output in this book is generated on a Red Hat Linux system. Other versions of Unix and Linux may sort ls output in a different way. The listing order may be different, but the files and directories will be the same.

[2] Recipe 10.10 shows a trick that is used to create a configuration without using an OSTYPE macro, but the trick is not recommended for general use.

[3] The sendmail version number is not the same as the sendmail.cf version level. In our examples, the sendmail version number is 8.12.9, but the sendmail.cf version level is 10. Furthermore, neither one of these has anything to do with the m4 VERSIONID macro, which is used to place version control information in the master configuration file.

[4] If you use RPM, the rpmfind.net web site can help you search for RPM compatible packages.

[5] In this example, the signature is used to verify the gzipped tar file. Signing the compressed files started with Version 8.12.7. Earlier versions of sendmail signed the uncompressed tar file. In those cases, the tar file is first decompressed and then verified.

[6] If you make changes to the siteconfig.m4 file and rerun Build, use the -c command-line argument to alert Build of the changes.

[7] Recipe 10.1 shows a trick to get around this requirement.

Get sendmail Cookbook now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.