There are some configuration changes that can be made by recompiling sendmail. This section describes what changes can be made and what has to be modified to make them. In most cases this should be unnecessary unless you are porting sendmail to a new environment.

Parameters in devtools/OS/$oscf

These parameters are intended to describe the compilation environment, not site policy, and should normally be defined in the operating system configuration file. This section needs a complete rewrite.

If set, the new version of the DBM library that allows multiple databases will be used. If neither NDBM nor NEWDB are set, a much less efficient method of alias lookup is used.
If set, use the new database package from Berkeley (from 4.4BSD). This package is substantially faster than DBM or NDBM. If NEWDB and NDBM are both set, sendmail will read DBM files, but will create and use NEWDB files.
Include support for NIS. If set together with both NEWDB and NDBM, sendmail will create both DBM and NEWDB files if and only if an alias file includes the substring /yp/ in the name. This is intended for compatibility with Sun Microsystems' mkalias program used on YP masters.
Compile in support for NIS+.
Compile in support for NetInfo (NeXT stations).
Compile in support for LDAP X500 queries. Requires libldap and liblber from the Umich LDAP 3.2 or 3.3 release or equivalent libraries for other LDAP libraries such as OpenLDAP.
Compile in support for Hesiod.
Compile in support for IRIX NSD lookups.
Compile in support for regular expression matching.
Compile in support for DNS map lookups in the file.
Compile in support for ph lookups.
Compile in support for SASL, a required component for SMTP Authentication support.
Compile in support for STARTTLS.
Compile in support for the "Entropy Gathering Daemon" to provide better random data for TLS.
Compile in support for TCP Wrappers.
The pathname of the file.
The pathname of the file.
Compile in support for shared memory, see section about "/var/spool/mqueue".
Compile in support for contacting external mail filters built with the Milter API.

There are also several compilation flags to indicate the environment such as _AIX3 and _SCO_unix_. See the sendmail/README file for the latest scoop on these flags.

Parameters in sendmail/conf.h

Parameters and compilation options are defined in conf.h. Most of these need not normally be tweaked; common parameters are all in However, the sizes of certain primitive vectors, etc., are included in this file. The numbers following the parameters are their default value.

This document is not the best source of information for compilation flags in conf.h -- see sendmail/README or sendmail/conf.h itself.

MAXLINE [2048]
The maximum line length of any input line. If message lines exceed this length they will still be processed correctly; however, header lines, configuration file lines, alias lines, etc., must fit within this limit.
The maximum length of any name, such as a host or a user name.
MAXPV [256]
The maximum number of parameters to any mailer. This limits the number of recipients that may be passed in one transaction. It can be set to any arbitrary number above about 10, since sendmail will break up a delivery into smaller batches as needed. A higher number may reduce load on your system, however.
The maximum number of queue groups.
MAXATOM [1000]
The maximum number of atoms (tokens) in a single address. For example, the address eric@CS.Berkeley.EDU is seven atoms.
The maximum number of mailers that may be defined in the configuration file. This value is defined in include/sendmail/sendmail.h.
The maximum number of rewriting sets that may be defined. The first half of these are reserved for numeric specification (e.g., ``S92''), while the upper half are reserved for auto-numbering (e.g., ``Sfoo''). Thus, with a value of 200 an attempt to use ``S99'' will succeed, but ``S100'' will fail.
The maximum number of values for the Precedence: field that may be defined (using the P line in
The maximum number of items in the user environment that will be passed to subordinate mailers.
The maximum number of MX records we will accept for any single host.
The maximum number of maps that may be "stacked" in a sequence class map.
The maximum number of arguments in a MIME Content-Type: header; additional arguments will be ignored.
The maximum depth to which MIME messages may be nested (that is, nested Message or Multipart documents; this does not limit the number of components in a single Multipart document).
The maximum number of sockets sendmail will open for accepting connections on different ports.
The maximum length of a macro name.

A number of other compilation options exist. These specify whether or not specific code should be compiled in. Ones marked with * are 0/1 valued.

If set, support for Internet protocol networking is compiled in. Previous versions of sendmail referred to this as DAEMON; this old usage is now incorrect. Defaults on; turn it off in the Makefile if your system doesn't support the Internet protocols.
If set, support for IPv6 networking is compiled in. It must be separately enabled by adding DaemonPortOptions settings.
If set, support for ISO protocol networking is compiled in (it may be appropriate to #define this in the Makefile instead of conf.h).
If set, support for UNIX domain sockets is compiled in. This is used for control socket support.
If set, the syslog routine in use at some sites is used. This makes an informational log record for each message processed, and makes a higher priority log record for internal system errors. STRONGLY RECOMMENDED -- if you want no logging, turn it off in the configuration file.
Compile in the code to do ``fuzzy matching'' on the GECOS field in /etc/passwd. This also requires that the MatchGECOS option be turned on.
Compile in code to use the Berkeley Internet Name Domain (BIND) server to resolve TCP/IP host names.
If you are using a non-UNIX mail format, you can set this flag to turn off special processing of UNIX-style From lines.
Include the experimental Berkeley user information database package. This adds a new level of local name expansion between aliasing and forwarding. It also uses the NEWDB package. This may change in future releases.

The following options are normally turned on in per-operating-system clauses in conf.h.

Compile in the IDENT protocol as defined in RFC 1413. This defaults on for all systems except Ultrix, which apparently has the interesting feature that when it receives a host unreachable message it closes all open connections to that host. Since some firewall gateways send this error code when you access an unauthorized port (such as 113, used by IDENT), Ultrix cannot receive email from such hosts.
Set all of the compilation parameters appropriate for System V.
Use Berkeley-style flock instead of System V lockf to do file locking. Due to the highly unusual semantics of locks across forks in lockf, this should always be used if at all possible.
Set this if your system has the initgroups() call (if you have multiple group support). This is the default if SYSTEM5 is not defined or if you are on HPUX.
Set this if you have the uname(2) system call (or corresponding library routine). Set by default if SYSTEM5 is set.
Set this if you have the getdtablesize(2) system call.
Set this if you have the haswaitpid(2) system call.
Set this if your system can possibly reuse the same pid in the same second of time.
The mechanism that can be used to get file system capacity information. The values can be one of SFS_USTAT (use the ustat(2) syscall), SFS_4ARGS (use the four argument statfs(2) syscall), SFS_VFS (use the two argument statfs(2) syscall including <sys/vfs.h>), SFS_MOUNT (use the two argument statfs(2) syscall including <sys/mount.h>), SFS_STATFS (use the two argument statfs(2) syscall including <sys/statfs.h>), SFS_STATVFS (use the two argument statfs(2) syscall including <sys/statvfs.h>), or SFS_NONE (no way to get this information).
The load average type. Details are described below.

The are several built-in ways of computing the load average. Sendmail tries to auto-configure them based on imperfect guesses; you can select one using the cc option -DLA_TYPE= type, where type is:

The kernel stores the load average in the kernel as an array of long integers. The actual values are scaled by a factor FSCALE (default 256).
The kernel stores the load average in the kernel as an array of short integers. The actual values are scaled by a factor FSCALE (default 256).
The kernel stores the load average in the kernel as an array of double precision floats.
Use MACH-style load averages.
Call the getloadavg routine to get the load average as an array of doubles.
Always return zero as the load average. This is the fallback case.

If type LA_INT, LA_SHORT, or LA_FLOAT is specified, you may also need to specify _PATH_UNIX (the path to your system binary) and LA_AVENRUN (the name of the variable containing the load average in the kernel; usually _avenrun or avenrun).

Configuration in sendmail/conf.c

The following changes can be made in conf.c.

Built-in Header Semantics

Not all header semantics are defined in the configuration file. Header lines that should only be included by certain mailers (as well as other more obscure semantics) must be specified in the HdrInfo table in conf.c. This table contains the header name (which should be in all lower case) and a set of header control flags (described below), The flags are:

Normally when the check is made to see if a header line is compatible with a mailer, sendmail will not delete an existing line. If this flag is set, sendmail will delete even existing header lines. That is, if this bit is set and the mailer does not have flag bits set that intersect with the required mailer flags in the header definition in, the header line is always deleted.
If this header field is set, treat it like a blank line, i.e., it will signal the end of the header and the beginning of the message text.
Add this header entry even if one existed in the message before. If a header entry does not have this bit set, sendmail will not add another header line if a header line of this name already existed. This would normally be used to stamp the message by everyone who handled it.
If set, this is a timestamp (trace) field. If the number of trace fields in a message exceeds a preset amount the message is returned on the assumption that it has an aliasing loop.
If set, this field contains recipient addresses. This is used by the -t flag to determine who to send to when it is collecting recipients from the message.
This flag indicates that this field specifies a sender. The order of these fields in the HdrInfo table specifies sendmail's preference for which field to return error messages to.
Addresses in this header should receive error messages.
This header is a Content-Transfer-Encoding header.
This header is a Content-Type header.
Strip the value from the header (for Bcc:).

Let's look at a sample HdrInfo specification:

struct hdrinfo HdrInfo[] =
/* originator fields, most to least significant */
"resent-sender", H_FROM,
"resent-from", H_FROM,
"sender", H_FROM,
"from", H_FROM,
"full-name", H_ACHECK,
"errors-to", H_FROM|H_ERRORSTO,
/* destination fields */
"to", H_RCPT,
"resent-to", H_RCPT,
"cc", H_RCPT,
/* message identification and control */
"message", H_EOH,
"text", H_EOH,
/* trace fields */
"received", H_TRACE|H_FORCE,
/* miscellaneous fields */
"content-transfer-encoding", H_CTE,
"content-type", H_CTYPE,

NULL, 0,

This structure indicates that the To:, Resent-To:, and Cc: fields all specify recipient addresses. Any Full-Name: field will be deleted unless the required mailer flag (indicated in the configuration file) is specified. The Message: and Text: fields will terminate the header; these are used by random dissenters around the network world. The Received: field will always be added, and can be used to trace messages.

There are a number of important points here. First, header fields are not added automatically just because they are in the HdrInfo structure; they must be specified in the configuration file in order to be added to the message. Any header fields mentioned in the configuration file but not mentioned in the HdrInfo structure have default processing performed; that is, they are added unless they were in the message already. Second, the HdrInfo structure only specifies cliched processing; certain headers are processed specially by ad hoc code regardless of the status specified in HdrInfo. For example, the Sender: and From: fields are always scanned on ARPANET mail to determine the sender[26]; this is used to perform the return to sender function. The From: and Full-Name: fields are used to determine the full name of the sender if possible; this is stored in the macro $x and used in a number of ways.

Restricting Use of Email

If it is necessary to restrict mail through a relay, the checkcompat routine can be modified. This routine is called for every recipient address. It returns an exit status indicating the status of the message. The status EX_OK accepts the address, EX_TEMPFAIL queues the message for a later try, and other values (commonly EX_UNAVAILABLE) reject the message. It is up to checkcompat to print an error message (using usrerr) if the message is rejected. For example, checkcompat could read:

checkcompat(to, e)
register ADDRESS *to;
register ENVELOPE *e;
register STAB *s;

s = stab("private", ST_MAILER, ST_FIND);
if (s != NULL && e->e_from.q_mailer != LocalMailer &&
to->q_mailer == s->s_mailer)
usrerr("No private net mail allowed through this machine");
if (MsgSize > 50000 && bitnset(M_LOCALMAILER, to->q_mailer))
usrerr("Message too large for non-local delivery");
e->e_flags |= EF_NORETURN;
return (EX_OK);

This would reject messages greater than 50000 bytes unless they were local. The EF_NORETURN flag can be set in e->e_flags to suppress the return of the actual body of the message in the error return. The actual use of this routine is highly dependent on the implementation, and use should be limited.

New Database Map Classes

New key maps can be added by creating a class initialization function and a lookup function. These are then added to the routine setupmaps.

The initialization function is called as

xxx_map_init(MAP *map, char *args)
The map is an internal data structure. The args is a pointer to the portion of the configuration file line following the map class name; flags and filenames can be extracted from this line. The initialization function must return true if it successfully opened the map, false otherwise.

The lookup function is called as

xxx_map_lookup(MAP *map, char buf[], char **av, int *statp)
The map defines the map internally. The buf has the input key. This may be (and often is) used destructively. The av is a list of arguments passed in from the rewrite line. The lookup function should return a pointer to the new value. If the map lookup fails, *statp should be set to an exit status code; in particular, it should be set to EX_TEMPFAIL if recovery is to be attempted by the higher level code.

Queueing Function

The routine shouldqueue is called to decide if a message should be queued or processed immediately. Typically this compares the message priority to the current load average. The default definition is:

shouldqueue(pri, ctime)
long pri;
time_t ctime;
if (CurrentLA < QueueLA)
return false;
return (pri > (QueueFactor / (CurrentLA - QueueLA + 1)));
If the current load average (global variable CurrentLA, which is set before this function is called) is less than the low threshold load average (option x, variable QueueLA), shouldqueue returns false immediately (that is, it should not queue). If the current load average exceeds the high threshold load average (option X, variable RefuseLA), shouldqueue returns true immediately. Otherwise, it computes the function based on the message priority, the queue factor (option q, global variable QueueFactor), and the current and threshold load averages.

An implementation wishing to take the actual age of the message into account can also use the ctime parameter, which is the time that the message was first submitted to sendmail. Note that the pri parameter is already weighted by the number of times the message has been tried (although this tends to lower the priority of the message with time); the expectation is that the ctime would be used as an escape clause to ensure that messages are eventually processed.

Refusing Incoming SMTP Connections

The function refuseconnections returns true if incoming SMTP connections should be refused. The current implementation is based exclusively on the current load average and the refuse load average option (option X, global variable RefuseLA):

return (RefuseLA > 0 && CurrentLA >= RefuseLA);
A more clever implementation could look at more system resources.

Load Average Computation

The routine getla returns the current load average (as a rounded integer). The distribution includes several possible implementations. If you are porting to a new environment you may need to add some new tweaks.[27]

Configuration in sendmail/daemon.c

The file sendmail/daemon.c contains a number of routines that are dependent on the local networking environment. The version supplied assumes you have BSD style sockets.

In previous releases, we recommended that you modify the routine maphostname if you wanted to generalize $[ ... $] lookups. We now recommend that you create a new keyed map instead.


In this section we assume that sendmail has been compiled with support for STARTTLS. To properly understand the use of STARTTLS in sendmail, it is necessary to understand at least some basics about X.509 certificates and public key cryptography. This information can be found in books about SSL/TLS or on WWW sites, e.g.,

Certificates for STARTTLS

When acting as a server, sendmail requires X.509 certificates to support STARTTLS: one as certificate for the server (ServerCertFile and corresponding private ServerKeyFile) at least one root CA (CACERTFile), i.e., a certificate that is used to sign other certificates, and a path to a directory which contains other CAs (CACERTPath). The file specified via CACERTFile can contain several certificates of CAs. The DNs of these certificates are sent to the client during the TLS handshake (as part of the CertificateRequest) as the list of acceptable CAs. The CACERTPath directory must contain the hashes of each CA certificate as filenames (or as links to them). Symbolic links can be generated with the following two (Bourne) shell commands:

ln -s $C `openssl x509 -noout -hash < $C`.0
An X.509 certificate is also required for authentication in client mode (ClientCertFile and corresponding private ClientKeyFile), however, sendmail will always use STARTTLS when offered by a server. The client and server certificates can be identical. Certificates can be obtained from a certificate authority or created with the help of OpenSSL. The required format for certificates and private keys is PEM. To allow for automatic startup of sendmail, private keys (ServerKeyFile, ClientKeyFile) must be stored unencrypted. The keys are only protected by the permissions of the file system. Never make a private key available to a third party.


STARTTLS requires a strong pseudo random number generator (PRNG) to operate properly. Depending on the TLS library you use, it may be required to explicitly initialize the PRNG with random data. OpenSSL makes use of /dev/urandom(4) if available (this corresponds to the compile flag HASURANDOMDEV). On systems which lack this support, a random file must be specified in the file using the option RandFile. It is strongly advised to use the "Entropy Gathering Daemon" EGD from Brian Warner on those systems to provide useful random data. In this case, sendmail must be compiled with the flag EGD, and the RandFile option must point to the EGD socket. If neither /dev/urandom(4) nor EGD are available, you have to make sure that useful random data is available all the time in RandFile. If the file hasn't been modified in the last 10 minutes before it is supposed to be used by sendmail the content is considered obsolete. One method for generating this file is:

openssl rand -out /etc/mail/randfile -rand
/path/to/file:... 256
See the OpenSSL documentation for more information. In this case, the PRNG for TLS is only seeded with other random data if the DontBlameSendmail option InsufficientEntropy is set. This is most likely not sufficient for certain actions, e.g., generation of (temporary) keys.

Please see the OpenSSL documentation or other sources for further information about certificates, their creation and their usage, the importance of a good PRNG, and other aspects of TLS.

[Contents] [Previous] [Next]
This document was translated by troff2html v0.21 on October 10, 2001.

Claus Aßmann Please send comments to: <ca at>