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 src/Makefile

These parameters are intended to describe the compilation environment, not site policy, and should normally be defined in src/Makefile.

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 Hesiod.
The pathname of the sendmail.cf file.
The pathname of the sendmail.pid file.

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

Parameters in src/conf.h

Parameters and compilation options are defined in conf.h. Most of these need not normally be tweaked; common parameters are all in sendmail.cf. 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 src/READ_ME or src/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 [40]
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 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.
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 sendmail.cf).
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 alias databases that can be open at any time. Note that there may also be an open file limit.
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).

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 ISO protocol networking is compiled in (it may be appropriate to #define this in the Makefile instead of conf.h).
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.
This flag should be set to compile in the queueing code. If this is not set, mailers must accept the mail immediately or it will be returned to the sender.
If set, the code to handle user and server SMTP will be compiled in. This is only necessary if your machine has some mailer that speaks SMTP (this means most machines everywhere).
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.
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 src/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 sendmail.cf, 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[22]; 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.

Load Average Computation

The routine getla should return an approximation of the current system load average as an integer. There are several versions included on compilation flags as described above.

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 *mapname, char *args)
The map is an internal data structure. The mapname is the name of the map (used for error messages). The args is a pointer to the rest of the configuration file line; 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[], int bufsize, char **av, int *statp)
The map defines the map internally. The parameters buf and bufsize have 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 (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.[23]

Configuration in src/daemon.c

The file src/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.

[Contents] [Previous] [Next]
This document was translated by troff2html v0.21 on May 31, 1996.
Claus Aßmann Please send comments to: <ca@informatik.uni-kiel.de>