V8 sendmail provides an easy way to create a custom configuration file for your site. In the cf subdirectory of the V8 sendmail source distribution you will find a file named README. It contains easy-to-understand, step-by-step instructions that allow you to create a custom configuration file for your site. This chapter supplements that file.
Creating a configuration file with m4(1) is simplicity itself. The m4(1) program is a macro preprocessor that produces a sendmail configuration file by processing a file of m4 commands. Files of m4 commands traditionally have names that end in the characters .m4 (the same as files used for building the sendmail binary). For building a configuration file, the convention is to name a file of m4 commands with an ending of .mc (for macro configuration). The m4 process reads that file and gathers definitions of macros, then replaces those macros with their values and outputs a sendmail configuration file.
With m4, macros are defined (given values) like this:
define(macro, value)Here, the macro is a symbolic name
that you will use later. Legal names must begin with an
underscore or letter and can contain letters, digits, and
underscores. The value can be any
arbitrary text. A comma separates the two, and that comma
can be followed by optional whitespace.
There must be no space between the define and the left parenthesis. The
definition ends with the right parenthesis.
To illustrate, consider this one-line m4 source file named /tmp/x:
input text to be converted ↑ define(A,B)A ↑ the m4 definition
When m4 is run to process this file, the
output produced shows that A (the input) is
redefined to become B:
% m4 /tmp/x
BThe m4 program is greedy. That is, if a macro is already defined, its value will replace its name in the second declaration. Consider this input file:
define(A,B) define(A,C) A B
Here, the first line assigns the value B to the macro named
A. The second
line notices that A is a defined macro, so
m4 replaces that A with B and then defines
B as having the
value C. The
output of this file, after processing with
m4, will be:
C C
To prevent this kind of greedy behavior (and to prevent the confusion it can create), you can quote an item to prevent m4 from interpreting it. You quote with m4 by surrounding each item with left and right single quotes:
define(A,B) define(`A',C) A B
Here, the first line defines A as B like before. But the second line no
longer sees A as
a macro. Instead, the single quotes allow A to be redefined as
C. So, the
output is now:
C B
Although it is not strictly necessary, we recommend that all macro and value pairs be quoted. The preceding line should generally be expressed like this:
define(`A',`B') define(`A',`C') A B
This is the form we use when illustrating m4 throughout this book, including in the previous two chapters.
Another problem with m4 is that
it replaces its commands with empty lines. The
earlier define
commands, for example, will actually print like
this:
← a blank line ← a blank line C B
To suppress this insertion of blank lines, you can use
the special m4 command dnl (for Delete through
New Line). That command looks like this:
define(`A',`B')dnldefine(`A',`C')dnlA B
You can use dnl to
remove blank lines where they might prove
inconvenient or unsightly in a configuration
file.
The dnl command can
also be used to put comments into an
mc file. Just be sure to put
a blank line after the last dnl because each dnl gobbles both the
text and the newline:
dnl This is a comment.
← note the extra blank lineWhen an m4 macro name is
immediately followed by a left parenthesis, it is
treated like a function call. Arguments given to it
in that role are used to replace $digit
expressions in the original definition. For example,
suppose the m4 macro CONCAT is
defined like this:
define(`CONCAT',`$1$2$3')dnl
and then later used like this:
CONCAT(`host', `.', `domain')
The result will be that the host will replace $1, the dot will replace
$2, and the
domain will
replace $3, all
jammed tightly together just as `$1$2$3' were:
host.domain
Macro arguments are used to create such techniques as FEATURE( ) and OSTYPE( ), which are described later in this chapter.
Ordinarily, the $
character is interpreted by m4
as a special character when found inside its
define
expressions:
define(`A', `$2')
↑
the $ makes $2 an m4 positional variableThere might be times, however, when you might want to
put a literal $
character into a definition—perhaps when designing
your own DOMAIN, FEATURE, or HACK files.
You place a literal $ into a definition with the DOL
m4 macro. For example:
define(`DOWN', `R DOL(*) < @ $1 > DOL(*) DOL(1) < @ $2 > DOL(2)')
Here, we define the m4 macro
named DOWN, which takes two arguments ($1 and $2). Notice how the
$ character has
meaning to m4. This newly
created DOWN macro can then be used in one of your
.m4 files, perhaps like
this:
DOWN(badhost, outhost)DOWN creates a rule by substituting the argument
(badhost for the
$1 in its
definition, and outhost)
for the corresponding $2. The substitution looks like
this:
R DOL(*) becomes ← R $* < @ $1 > becomes ← < @ badhost > DOL(*) becomes ← $* DOL(1) becomes ← $1 < @ $2 > becomes ← < @ outhost > DOL(2) becomes ← $2
After substitution, the following new rule is the result:
R $* < @badhost> $* $1 < @outhost> $2
The DOL m4 macro allowed the
insertion of $
characters (such as $*) and protects you from having the
literal use of $
characters being wrongly interpreted by
m4.
Needless to say, you should never redefine the DOL m4 macro.
The process of building a sendmail
configuration file begins by creating a file of
m4 statements. Traditionally,
the suffix for such files is .mc. The cf/cf
directory contains examples of many .mc files. Of special
interest are those that begin with generic, for these can serve as
boilerplates in developing your own .mc files:
generic-bsd4.4.mc generic-mpeix.mc generic-sunos4.1.mc generic-hpux10.mc generic-nextstep3.3.mc generic-ultrix4.mc generic-hpux9.mc generic-osf1.mc generic-linux.mc generic-solaris.mc
All .mc files require
specific minimal statements. For a SunOS 4.1.4 site on the
Internet, for example, the following are minimal:
OSTYPE(sunos4.1)dnl ← see §17.2.2.1 on page 590 MAILER(local)dnl ← see §17.2.2.2 on page 590 MAILER(smtp)dnl ← see §17.2.2.2 on page 590
To build a configuration file from these statements, you would place them into a file—say, localsun.mc—and then run the following command:
% ./Build localsun.cf
Using M4=/usr/5bin/m4
rm -f localsun.cf
/usr/5bin/m4 ../m4/cf.m4 localsun.mc > localsun.cf || ( rm -f localsun.cf && exit 1 )
chmod 444 localsun.cfHere, you run the Build[235] script found in the cf/cf directory. You pass it the name of your mc file with the “.mc” suffix changed to a “.cf” suffix. The Build script uses m4 to expand your mc file into a full-fledged configuration file.
Another way to build a configuration file is by running m4 by hand:
% m4 ../m4/cf.m4 localsun.mc > sendmail.cfHere, the ../m4/cf.m4 tells
m4 where to look for its
default configuration file information.
If you are using an old version of m4, the following error message will be printed:
You need a newer version of M4, at least as new as System V or GNU m4: file not found: NoSuchFile
Just as the message says, you need a newer version of m4. (The third line is just a result of forcing m4 to fail and can be safely ignored.) Thus, we would need to rerun our second localsun.mc example (earlier) as:
% /usr/5bin/m4 ../m4/cf.m4 localsun.mc > sendmail.cf
↑
System V version of m4Another cause of failure could be that the ../m4/cf.m4 file was not
where you thought it was. Various versions of
m4 print this error in
different ways:
/usr/5bin/m4:-:1 can't open file ← SysV m4 m4: ../m4/cf.m4: No such file or directory ← GNU m4 m4: file not found: ../m4/cf.m4 ← BSD m4
One possible reason for this error might be that you are
developing your .mc file
somewhere other than in the cf/cf
directory.[236] The solution is to use a full pathname to
cf.m4 or to replace that
expression on the command line with a shell variable.
After you have successfully produced a “first draft” of your configuration file, you can edit localsun.mc and add features as you need them. Many possibilities are described in the rest of this chapter.
It can be advantageous to maintain all the files that make up your local m4 configuration separately from the sendmail distribution. This prevents new releases of sendmail from clobbering your source files. It also allows you to maintain configuration information more conveniently (perhaps under rcs(1) control) and to use programs such as make(1) to simplify configuration and installation.
Most modern versions of m4 allow you to define m4 macros on the command line, and one such m4 macro is recognized internally by the m4 technique:
_CF_DIR_
This command-line m4 macro tells m4 where the m4/cf.m4 file described earlier is located. It needs to have its value set to be the cf directory under the sendmail source distribution, and it needs to end in a slash character. For example, GNU m4 version 1.2 allows this:
%setenv CFDIR /usr/local/src/mail/sendmail/cf/%/usr/local/gnu/bin/m4 -D_CF_DIR_=${CFDIR} ${CFDIR}m4/cf.m4 localsun.mc \> sendmail.cf
Notice that we store the value for _CF_DIR_ in an
environment variable. Note that GNU
m4 can figure out the
_CF_DIR_ path
itself from the path of the
cf.m4 file. We include
_CF_DIR_ here
merely as an example. If your version of
m4 lacks this ability, you
should consider upgrading.
With the _CF_DIR_
m4 macro, we can further
simplify configuration and installation by using
make(1). To illustrate,
consider the following few lines from a
Makefile on a SunOS
system:
M4=/usr/local/gnu/bin/m4
CFDIR=/usr/local/src/mail/sendmail/cf/
localsun: localsun.mc
$(M4) -D_CF_DIR_=$(CFDIR) $(CFDIR)/m4/cf.m4 localsun.mc > sendmail.cfWith this Makefile the two complex command lines shown earlier are reduced to a single, simple command line:
% makeEvery mc file requires minimal information. Table 17-1 shows which m4 items are required and lists two that are recommended. We show them in the order that they should be declared (OSTYPE first and MAILER last), and then describe the mandatory and recommended information.
|
Item |
Section |
Description | |
|
OSTYPE( ) |
OSTYPE( ) m4 macro on page 590 |
Required |
Support for your operating system |
|
DOMAIN( ) |
DOMAIN( ) m4 macro on page 591 |
Recommended |
Common domain-wide information |
|
FEATURE( ) |
FEATURE( ) m4 macro on page 592 |
Recommended |
Solutions to special needs |
|
MAILER( ) |
MAILER( ) m4 macro on page 590 |
Required |
Necessary delivery agents |
Note that what is minimally required for a workstation differs from what is minimally required for a central mail server. We suggest that you use these recommendations as a jumping-off point and then investigate all the m4 macros and features that are available.
Support for various operating systems is
supplied with the OSTYPE m4
command. Every .mc file must
declare the operating system with this command,
and this command must be the first in your
mc file.[237] The available support is supplied by
files in the _CF_DIR_/ostype
directory. A listing of those files looks
something like this:
a-ux.m4 bsdi2.0.m4 hpux9.m4 openbsd.m4 solaris2.ml.m4 aix3.m4 darwin.m4 irix4.m4 osf1.m4 solaris2.pre5.m4 aix4.m4 dgux.m4 irix5.m4 powerux.m4 solaris8.m4 aix5.m4 domainos.m4 irix6.m4 ptx2.m4 sunos3.5.m4 altos.m4 dynix3.2.m4 isc4.1.m4 qnx.m4 sunos4.1.m4 amdahl-uts.m4 freebsd4.m4 linux.m4 riscos4.5.m4 svr4.m4 bsd4.3.m4 freebsd5.m4 maxion.m4 sco-uw-2.1.m4 ultrix4.m4 bsd4.4.m4 gnu.m4 mklinux.m4 sco3.2.m4 unixware7.m4 bsdi.m4 hpux10.m4 mpeix.m4 sinix.m4 unknown.m4 bsdi1.0.m4 hpux11.m4 nextstep.m4 solaris2.m4 uxpds.m4
To include support, select the file that best describes your operating system, delete the .m4 suffix from its name, and include the resulting name in an OSTYPE declaration:
OSTYPE(`ultrix4')
Here, support for the DEC Ultrix operating
system is defined. Note that some of these are not
entirely accurate. For example, ultrix4.m4 includes
support for Ultrix versions 4.2 and 4.3, and
sunos4.1.m4
includes support for SunOS versions 4.1.2, 4.1.3,
and 4.1.4.
If you pick a name for which no file exists, or if you misspell the name of the file, an error similar to the following will print:
m4: Can't open ../ostype/ultrux4.1.m4: No such file or directory
If you omit the OSTYPE declaration entirely, you will get the following error:
*** ERROR: No system type defined (use OSTYPE macro)
Delivery agents are not automatically declared. Instead, you must specify which ones you want to support and which ones you want to ignore. Support is included by using the MAILER definition:
MAILER(`local')
This causes support for both the local and the prog delivery agents to
be included. This is the minimal declaration (even
if you don’t intend to perform local or program
delivery).
The MAILER definition must always be last in
your mc configuration
file.[238] If you include MAILER definitions for
procmail(1),
maildrop(1), or
uucp, those
definitions must always follow the definition for
smtp. Any
modification of a MAILER definition (as, for
example, with LOCAL_MAILER_MAX) must precede that
MAILER definition:
define(`LOCAL_MAILER_MAX', `1000000') ← here MAILER(`local') define(`LOCAL_MAILER_MAX', `1000000') ← not here
A minimal mc file for an average machine on the Internet would contain two MAILER definitions:
MAILER(`local') MAILER(`smtp')
The first you have already seen. The second includes support for sending email to other hosts on the Internet. If this minimal mc is all you think you’ll need, you can continue on to the rest of this chapter. If, on the other hand, you expect to support any variations on mail receipt and delivery beyond the basics, you should leap ahead to Chapter 20, study that chapter, and then return here. (See Table 20-1 on page 717 for a list of all the available delivery agents.)
All delivery agent equates, such as F= and M=, can be modified with
the .m4
configuration technique. Table 20-18 on page 736
lists all the equates and shows where to find
further information about each of them. By
investigating those sections, you can discover how
to tune particular equates with the
m4 technique. For example,
the following mc lines define
the program used for local delivery to be
mail.local:
FEATURE(`local_lmtp') define(`LOCAL_MAILER_PATH', `/usr/local/bin/mail.local') MAILER(local)
Note that all modifications to equates must precede the corresponding MAILER( ) definition.
For large sites it can be advantageous to gather into a single file all configuration decisions that are common to the entire domain. The directory to hold domain information files is called domain. The configuration information in those files is accessed by using the DOMAIN( ) m4 technique. For example:
DOMAIN(`uofa.edu')
This line in any of your mc files causes the file domain/uofa.edu.m4 to be included at that point. Examples that come with the distribution illustrate subdomains under Berkeley.EDU. One boilerplate file, named generic.m4, can be used as a starting point for your own domain-wide file. For example, if all hosts at your site masquerade behind one email name, you might want to put MASQUERADE_AS (MASQUERADE_AS mc Macro on page 600) in your domain file. Domain files also form a natural location for the definition of site-specific relays (Relays on page 602).
If the domain that is specified does not exist or is misspelled, an error similar to the following will be printed:
m4: Can't open ../domain/generik.m4: No such file or directory
The use of DOMAIN( ) is not mandatory but is recommended. Note that problems can arise because the items inside your domain file will determine where the DOMAIN( ) declaration must go in the mc file. If, for example, the domain file contains MAILER( ) definitions, DOMAIN( ) should appear near the end of the mc file with the MAILER( ) definitions. If the domain file contains rules and rule sets, the DOMAIN( ) must be last in the mc file, but if the domain file contains OSTYPE( ), DOMAIN( ) must be first in the mc file. So, consider well what you place in your domain file. Avoid defining anything in your domain file that restricts where the DOMAIN( ) definition must go in your mc file.
In the event that your domain file contains many position-dependent commands, such as rule sets and an OSTYPE( ) command, you might need to split that file into pieces. You can split it something like this:
DOMAIN(`our.domain.sun') DOMAIN(`our.domain.rules')
Here, the first line causes the file our.domain.sun.m4 to be read. That file contains the OSTYPE( ) declaration for all your Sun workstations. This DOMAIN( ) entry would appear at the top of your mc file.
The second line causes the file our.domain.rules.m4 to be read. That file might contain antispam rule sets. This second DOMAIN( ) entry would appear near the end of your mc file, perhaps under LOCAL_RULESETS.
V8 sendmail offers a number of features that you might find very useful. To use a feature, include an m4 command such as one of the following in your mc file:
FEATURE(keyword) FEATURE(keyword, argument) FEATURE(keyword, argument, argument, ... etc.)
These declarations cause a file of the name feature/keyword.m4 to be read at that place in your mc file. The available keyword files are summarized in Table 17-7 on page 612, and each is explained in the section at the end of this chapter. Note that some keywords require additional arguments.
As you have seen, some mc lines must precede others. This is necessary partly because m4(1) is a one-pass program, and partly because the order of items in the final sendmail.cf file is also critical. The recommended order is:
VERSIONID( ) ← see §17.2.3.1 on page 593 OSTYPE( ) ← see §17.2.2.1 on page 590 DOMAIN( ) ← see §17.2.2.3 on page 591 option definitions ← see §24.4 on page 953 FEATURE( ) ← see §17.8 on page 611 macro definitions ← see §21.7 on page 796 MAILER( ) ← see §17.2.2.2 on page 590 ruleset definitions ← see §19.1.7 on page 688
If in doubt about where some particular item should go, look in the many example files in cf/cf. Some of them (especially the file knecht.mc) will also give you good ideas about how you can improve your own mc file.
The VERSIONID m4 macro is used to insert an identifier into each mc and m4 file that becomes a part of your final .cf file. Each file that is supplied with sendmail already has such an identifier. You should include a similar identifier in each of your mc files:
VERSIONID(`$Id$')
Here, the VERSIONID m4
macro is used to insert an RCS-style revision
number. The $Id$
becomes an actual version number when the file is
checked in with ci(1).
Arbitrary text can appear between the single
quotes. You can use RCS, SCCS, or any other kind
of revision identification system. The text cannot
contain a newline because the text appears in the
.cf file as a comment:
##### $Id$ #####Use of VERSIONID and revision control in general is recommended.
Some things just can’t be called features. To make this clear, they go in the hack directory and are referenced using the HACK m4 macro. They tend to be site-dependent:
HACK(`cssubdomain')
This illustrates use of the Berkeley-dependent
cssubdomain
hack (that makes sendmail
accept local names in either
Berkeley.EDU or
CS.Berkeley.EDU).
Another way to think of a hack is as a transient feature. Create and use HACK as a temporary solution to a temporary problem. If a solution becomes permanent, move it to the FEATURE directory and reference it there.
The m4 technique uses a huge number of macros to accomplish the complex task of creating configuration files for all possible circumstances. Many are detailed in the reference section at the end of this chapter. Many others are documented in chapters dedicated to particular subjects. Here, we summarize many of the m4 macros by classification or function. Note that a comprehensive list of all m4 macros is available in Appendix A on page 1227.
Options can be set, unset, and changed in your
mc file with simple define statements. For
example, the following line sets the location of the
aliases file and thus the
AliasFile
option:
define(`ALIAS_FILE', `nis:-N mail.aliases')
Configuring options with the m4 technique is described in Options in the mc File on page 953 (with the individual m4 option names listed in Table 24-3 on page 953). Options are described in general in Chapter 24 on page 947. We recommend that you leap ahead to that chapter, learn about options that will make your use of sendmail more valuable, and then return here.
Defined sendmail macros can be declared in your mc file. Those that are useful are listed in Table 21-5 on page 796. That section also describes the general technique of defining sendmail macros via m4. To illustrate, for example:
define(`BITNET_RELAY', `host.domain')causes the value
host.domain to be
assigned to an internal
sendmail macro (currently
$B).
Non-m4-specific defined
macros can be declared with the LOCAL_CONFIG
technique (LOCAL_CONFIG mc macro on
page 595).
Rules are used to rewrite mail addresses and to select delivery agents, among other things. They are organized in rule sets, which can be thought of as subroutines. We deal with rules and rule sets more deeply in Chapter 18 on page 648 and Chapter 19 on page 683. Here we only illustrate how the mc configuration method is used to insert custom rules and rule sets in a variety of convenient ways. We list all the mc keywords that affect rules and rule sets in Table 17-2. For completeness, we also list one keyword for adding delivery agents.
|
§ |
Versions |
Description | |
|
LOCAL_CONFIG |
LOCAL_CONFIG mc macro on page 595 |
V8.1 and later |
Add general information. |
|
LOCAL_NET_CONFIG |
LOCAL_NET_CONFIG mc macro on page 598 |
V8.6 and later |
Add custom rules for SMART_HOST. |
|
LOCAL_RULE_0 |
LOCAL_RULE_0 mc macro on page 596 |
V8.1 and later |
Add custom rules to the |
|
LOCAL_RULE_1 |
LOCAL_RULE_1 and LOCAL_RULE_2 mc macros on page 596 |
V8.1 and later |
Add custom rules to rule set 1. |
|
LOCAL_RULE_2 |
LOCAL_RULE_1 and LOCAL_RULE_2 mc macros on page 596 |
V8.1 and later |
Add custom rules to rule set 2. |
|
LOCAL_RULE_3 |
LOCAL_RULE_3 mc macro on page 596 |
V8.1 and later |
Add custom rules to the |
|
LOCAL_RULESETS |
LOCAL_RULESETS mc macro on page 597 |
V8.8 and later |
Group local rules with others. |
|
LOCAL_SRV_FEATURES |
srv_features on page 708 |
V8.12 and later |
Add/create rules for the |
|
LOCAL_TRY_TLS |
Disable STARTTLS with the try_tls rule set on page 217 |
V8.12 and later |
Add custom rules to the |
|
LOCAL_TLS_CLIENT |
The access database with tls_server and tls_client on page 214 |
V8.12 and later |
Add custom rules to the |
|
LOCAL_TLS_RCPT |
The tls_rcpt rule set on page 215 |
V8.12 and later |
Add custom rules to the |
|
LOCAL_TLS_SERVER |
The access database with tls_server and tls_client on page 214 |
V8.12 and later |
Add custom rules to the |
|
MAILER_DEFINITIONS |
MAILER_DEFINITIONS on page 716 |
V8.12 and later |
Define delivery agents. |
To illustrate, consider the following technique for
adding a rule to the parse rule set 0:
LOCAL_RULE_0 R$* <@ $=w . $=m> $* $#local $: $1 @here.ourdomain
Here, we add a rule to the parse rule set 0 that accepts any
address with a host part in the class $=w ($=w on page 876) that is
also in one of the local domains listed in the class
$=m ($=m on page 872) as a
local address.
The LOCAL_CONFIG mc macro allows custom configuration lines to be inserted in the configuration file by using the mc file. The inserted lines are carried literally into the output and appear in the resulting configuration file just before the options. The LOCAL_CONFIG mc macro should be used for sendmail macro, class, and map definitions, but not for rule set declarations. For rule sets, use the LOCAL_RULESETS mc macro (LOCAL_RULESETS mc macro on page 597):
LOCAL_CONFIG FE/usr/local/mail/visible.users Khostmap hash /etc/hostmap
In this example, the class $=E has additional names
read from the file
visible.users, and the
hostmap database is
declared.
If you wrongly include rule sets and rules with this LOCAL_CONFIG mc macro you might see the following warning:
Warning: OperatorChars is being redefined.
It should only be set before rule set definitions.The parse
rule set 0 first checks to see whether the mail
should be delivered locally. It then checks for
other addresses, such as uucp and smtp. You can insert custom delivery
agent selections of your own in the parse rule set 0, after
the local
delivery selection, but before the uucp, smtp, and the like. To
do this, use the LOCAL_RULE_0
mc macro:
LOCAL_RULE_0 # We service lady via an mx record. R$+ < @ lady.Berkeley.EDU. > $#uucp $@ lady $: $1
Here, we introduce a new rule to select a delivery agent. The host lady is a UUCP host for which we accept mail via an MX record.
In The parse Rule Set 0 on
page 696, we deal with the flow of rules through
the parse rule
set 0. For now, merely note that LOCAL_RULE_0 fits
into the flow of rules through the parse rule set 0 like
this:
Basic canonicalization (list syntax, delete local host, etc.)
LOCAL_RULE_0
FEATURE(ldap_routing) (FEATURE(ldap_routing) on page 922)
FEATURE(virtusertable) (FEATURE(virtusertable) on page 645)
Addresses of the form “user@$=w” passed to local delivery agent
FEATURE(mailertable) (FEATURE(mailertable) on page 629)
UUCP, BITNET_RELAY ($B on page 808), etc.
LOCAL_NET_CONFIG (LOCAL_NET_CONFIG mc macro on page 598)
SMART_HOST (SMART_HOST mc macro on page 597)
SMTP, local, etc. delivery agents
Rule sets 1 and 2 are normally empty and are not included in the configuration file that is created from your mc file. Rule set 1 processes all sender addresses (Rule Set 1 on page 702). Rule set 2 processes all recipient addresses (Rule Set 2 on page 702). These two mc macros are used just like LOCAL_RULE_0, as shown earlier, but they introduce rules that would otherwise be omitted, rather than adding rules to an existing rule set.
Note that any modifications made to addresses in LOCAL_RULE_1 and LOCAL_RULE_2 are reflected in the headers of mail messages.
All addresses are first rewritten by the
canonify rule
set 3 (The canonify Rule Set 3
on page 690). Thus, for complex configuration
needs, it is handy to define special rules and add
them to the canonify rule set 3. Note that new
rules are added to the end of the canonify rule set 3 by
way of rule set 96. That is, each final decision
in the canonify
rule set 3 calls rule set 96 (with $>96) before
returning.
The LOCAL_RULE_3 mc macro is most often used to introduce new rules that can be used in canonicalizing the hostnames.
One suggested use for LOCAL_RULE_3 is to convert old UUCP hostnames into domain addresses using the UUCPSMTP mc macro. For example:
LOCAL_RULE_3 UUCPSMTP(decvax, decvax.dec.com) UUCPSMTP(research, research.att.com)
This causes the following address transformations:
decvax!user becomes → user@decvax.dec.com research!user becomes → user@research.att.com
Another suggested use for LOCAL_RULE_3 is to introduce a new rule to look up hostnames in a locally customized database:
LOCAL_RULE_3 R$*<@$+>$* $:$1<@ $(hostmap $2 $) >$3
The declaration and definition of local
database maps with the K configuration command (The K Configuration Command on page
882) should appear in the LOCAL_CONFIG
section.
Prior to V8.8 sendmail,
you had to use the divert
mc directive to force your
new rule set declarations to be emitted alongside
the normal mc-generated rule
sets. Beginning with V8.8, that bit of “black
magic” has been removed.
The LOCAL_RULESETS mc command causes all the rule sets and rules that follow it to be emitted into your configuration file along with all the rules that are automatically generated. You use it like this:
LOCAL_RULESETS
your new rule sets and rules hereSome sites can deliver local mail to the local network but cannot look up hosts on the Internet with DNS. Usually, such sites are connected to the outside world through a firewall, or with UUCP. To ensure delivery of all mail, such sites need to forward all nonlocal mail to a smart (or well-connected) gateway host.
You can enable this behavior by defining SMART_HOST. In a firewall situation, all nonlocal mail should be forwarded to a gateway machine for handling:
define(`SMART_HOST', `gateway.your.domain')
In the case of a site that is only UUCP-connected, all nonlocal mail will need to be forwarded to an Internet-connected host over UUCP:
define(`SMART_HOST', `uucp-dom:supporthost')
Here, Internet mail will be forwarded to the
host supporthost using the
uucp-dom
delivery agent.
For information about other ways to use SMART_HOST, see the file cf/README.
LOCAL_NET_CONFIG is chiefly intended as a place to override settings of the SMART_HOST mc macro (SMART_HOST mc macro on page 597). To illustrate, consider one possible setup for mail. The idea is to allow hosts on the local network to deliver directly to each other but to have all other mail sent to a “smart host” that forwards that mail offsite. Commonly, such arrangements are used by sites with in-house networks that have access to the outside world only through a UUCP link. For such sites you can use LOCAL_NET_CONFIG:
define(`SMART_HOST', `relay:uucp-gateway') LOCAL_NET_CONFIG R $* < @ $+ .$m. > $* $#smtp $@ $2.$m $: $1 < @ $2.$m > $3
Here, SMART_HOST is defined as relay:uucp-gateway
(meaning send to the host
uucp-gateway with the
relay delivery
agent). The LOCAL_NET_CONFIG then introduces a
rule that causes all names that end in your domain
name ($m) to be
delivered via the smtp delivery agent. Any other
addresses fall through and are handled by the
SMART_HOST rules.
In The parse Rule Set 0 on
page 696, we deal with the flow of rules through
the parse rule
set 0. For now, merely note that LOCAL_NET_CONFIG
fits into the flow of rules through the parse rule set 0 like
this:
Basic canonicalization (list syntax, delete local host, etc.)
LOCAL_RULE_0 (LOCAL_RULE_0 mc macro on page 596)
FEATURE(ldap_routing) (FEATURE(ldap_routing) on page 922)
FEATURE(virtusertable) (FEATURE(virtusertable) on page 645)
Addresses of the form “user@$=w” passed to local delivery agent
FEATURE(mailertable) (FEATURE(mailertable) on page 629)
UUCP, BITNET_RELAY ($B on page 808), etc.
LOCAL_NET_CONFIG
SMART_HOST (SMART_HOST mc macro on page 597)
SMTP, local, etc. delivery agents
Masquerading is the process of transforming the local hostname in addresses into that of another domain. This results in the mail message appearing to come from that other domain rather than from the local host. Masquerading is most often used in domains where email is addressed to the domain rather than to individual hosts inside the domain.
Masquerading usually rewrites header-sender addresses. Some mc features allow you also to rewrite envelope addresses and recipient headers. The complete list of all definitions and features that affect masquerading is shown in Table 17-3.
|
What |
§ |
Version |
Masquerade |
|
EXPOSED_USER |
EXPOSED_USER mc Macro on page 599 |
V8.6 and later |
All but these hosts |
|
EXPOSED_USER_FILE |
EXPOSED_USER_FILE mc macro on page 600 |
V8.12 and later |
All but these |
|
FEATURE(allmasquerade) |
FEATURE(allmasquerade) on page 615 |
V8.2 and later |
The recipient too |
|
FEATURE(domaintable) |
FEATURE(domaintable) on page 621 |
V8.2 and later |
Rewrite old domain as equivalent to new domain |
|
FEATURE(generics_entire_domain) |
FEATURE(generics_entire_domain) on page 622 |
V8.10 and later |
Transform sender addresses |
|
FEATURE(genericstable) |
FEATURE(genericstable) on page 622 |
V8.8 and later |
Transform sender addresses |
|
FEATURE(limited_masquerade) |
FEATURE(limited_masquerade) on page 625 |
V8.8 and later |
Only MASQUERADE_DOMAIN hosts |
|
FEATURE(local_no_masquerade) |
FEATURE(local_no_masquerade) on page 626 |
V8.12 and later |
Don’t masquerade local mail |
|
FEATURE(masquerade_entire_domain) |
FEATURE(masquerade_entire_domain) on page 631 |
V8.8 and later |
All of a domain |
|
FEATURE(masquerade_envelope) |
FEATURE(masquerade_envelope) on page 632 |
V8.7 and later |
The envelope too |
|
GENERICS_DOMAIN |
GENERICS_DOMAIN mc macro on page 624 |
V8.8 and later |
List domains for genericstable |
|
GENERICS_DOMAIN_FILE |
GENERICS_DOMAIN_FILE mc macro on page 624 |
V8.8 and later |
List domains for genericstable |
|
MASQUERADE_AS |
MASQUERADE_AS mc Macro on page 600 |
V8.6 and later |
As another host |
|
MASQUERADE_DOMAIN |
MASQUERADE_DOMAIN mc Macro on page 600 |
V8.6 and later |
Other domains |
|
MASQUERADE_DOMAIN_FILE |
MASQUERADE_DOMAIN_FILE mc Macro on page 601 |
V8.6 and later |
Other domains |
|
MASQUERADE_EXCEPTION |
MASQUERADE_EXCEPTION mc Macro on page 601 |
V8.10 and later |
But not these domains |
|
MASQUERADE_EXCEPTION_FILE |
MASQUERADE_EXCEPTION_FILE mc Macro on page 602 |
V8.12 and later |
But not these domains |
An internal sendmail class is used by the V8 configuration file to hold a list of usernames that should never be masqueraded (even if masquerading is enabled with the MASQUERADE_AS mc macro). Prior to V8.10 sendmail, the user root was always in that class. With V8.10 and later, that class is now always empty unless you add usernames into it.
You can add users individually with the EXPOSED_USER mc macro like this:
EXPOSED_USER(`user')Here, user is either one
user or a list of users separated by spaces.
The EXPOSED_USER_FILE macro, like the EXPOSED_USER macro, allows you to list names that should never be masqueraded (even if masquerading is enabled with the MASQUERADE_AS mc macro). It lists usernames in an external file, one name per line, and is declared like this:
EXPOSED_USER_FILE(`/etc/mail/exposedusers')
This declaration causes a list of users to be
read from the file
/etc/mail/exposedusers.
Because EXPOSED_USER_FILE is implemented with an
F configuration
command (The F Class Command on
page 857), you can add whatever F command arguments you
desire. For example:
EXPOSED_USER_FILE(`-o /etc/mail/exposedusers')
Here the -o
switch makes the presence of the
/etc/mail/exposedusers file
optional.
If you are currently reading exposed users
from a file declared with the F configuration command,
you are encouraged to convert to this new macro.
Use of it will insulate you from change in the
future if a different class name is ever
used.
At sites with one central mail server (see MAIL_HUB, MAIL_HUB mc Macro on page 605), it can be advantageous for mail to appear as though it is from the hub. This simplifies mail administration in that all users have the same machine address no matter which workstations they use. You can cause a workstation to masquerade as the server (or as another host) by using the MASQUERADE_AS mc macro:
MASQUERADE_AS(`server')This causes outgoing mail to be labeled as coming from
the server (rather than from the value in $j, $j on page 830). The new address
appears in the sender headers (such as From:) but specifically
does not appear in the Received: (Received: on page 1162) and
Message-ID:
(Message-ID: on page 1159)
headers.
Some users (such as root) should never be masqueraded because one always needs to know their machine of origin. Such users are declared by using the EXPOSED_USER mc macro. Note that prior to V8.10 sendmail, root was always exposed.
If you wish to have recipient addresses also masqueraded, cautiously use the allmasquerade feature (FEATURE(allmasquerade) on page 615).
Ordinarily, MASQUERADE_AS enables hosts in the local
domains (as defined in the $=w class, $=w on page 876) to be
transformed into the masquerading host. It also
masquerades a list of additional hosts, but that
list is normally empty.
If you wish to masquerade a domain other than your local one, you can use the MASQUERADE_DOMAIN mc macro:
MASQUERADE_DOMAIN(`other.domain')Essentially, all that MASQUERADE_DOMAIN does is assign its argument to an internal sendmail class, so you can list multiple domains in a single MASQUERADE_DOMAIN statement:
MASQUERADE_DOMAIN(`domain1 domain2 domain3')Note that MASQUERADE_DOMAIN masquerades only the
domain and not any hosts under
that domain. If you wish to masquerade all hosts
under a domain (including the domain itself), see
the masquerade_entire_domain feature (FEATURE(masquerade_entire_domain) on page 631).
Also note that MASQUERADE_DOMAIN has special meaning
for the limited_masquerade feature (FEATURE(limited_masquerade) on page 625). When that feature is declared, only
the domains listed under MASQUERADE_DOMAIN will be
masqueraded.
In masquerading other domains, as with MASQUERADE_DOMAIN, it can prove advantageous to store the list of masqueraded domains in an external file. The MASQUERADE_DOMAIN_FILE mc macro allows you to do just that:
MASQUERADE_DOMAIN_FILE(`/etc/mail/domains')
Essentially, all that MASQUERADE_DOMAIN_FILE does is
read the external file using the F configuration command.
As a consequence, you can add an F-style argument to its
declaration:
MASQUERADE_DOMAIN_FILE(`-o /etc/mail/domains')
Here, we added a -o
to make the existence of the file optional.
Note that the file specified with MASQUERADE_DOMAIN_FILE is read only once, when sendmail first starts.
Normally, when you masquerade a site, you masquerade all the machines at that site. But in some instances that might not be desirable. Beginning with V8.10 sendmail, it is now possible to omit selected hosts from masquerading.
Consider, for example, a university that hosts a few subdomains within it. If bigcampus.edu provided mail services for cs.bigcampus.edu, it might set up its main mail server’s mc file like this:
MASQUERADE_AS('bigcampus.edu')
FEATURE(`masquerade_entire_domain')
MASQUERADE_EXCEPTION(`cs.bigcampus.edu')The argument to MASQUERADE_EXCEPTION can be one or more hosts, separated from each other by spaces. Each excepted host is assigned to an internal sendmail class.
Note that you cannot exempt all hosts in a domain with this MASQUERADE_EXCEPTION mc macro. You must specify each host individually.
If you have many exceptions defined with the MASQUERADE_EXCEPTION mc configuration macro, you can store them in a single file—say, donotmasq—and read that file using the MASQUERADE_EXCEPTION_FILE mc macro:
MASQUERADE_EXCEPTION_FILE(`/etc/mail/donotmasq') ← V8.12 and laterEssentially, all that MASQUERADE_EXCEPTION_FILE does
is read the external file using the F configuration command.
As a consequence, you can add an F-style argument to its
declaration:
MASQUERADE_EXCEPTION_FILE(`-o /etc/mail/donotmasq') ← V8.12 and laterHere, we added a -o
to make the existence of the file optional.
Note that the file specified with MASQUERADE_EXCEPTION_FILE is read only once, when sendmail first starts.
A relay is a rule that sends all of one type of mail to a specific destination. One example is email fax transmissions. Clearly, even though local mail should be delivered locally, mail to the pseudouser fax should always be sent to a special fax-handling machine.
The complete list of relays supported by the V8 sendmail mc technique is shown in Table 17-4.
|
Relay |
§ |
Versions |
Description |
|
BITNET_RELAY |
BITNET_RELAY mc Macro on page 603 |
V8.1 and later |
The BITNET relay |
|
DECNET_RELAY |
DECNET_RELAY mc Macro on page 604 |
V8.7 and later |
The DECnet relay |
|
FAX_RELAY |
FAX_RELAY mc Macro on page 604 |
V8.6 and later |
The FAX relay |
|
LOCAL_RELAY |
LOCAL_RELAY mc Macro on page 604 |
V8.1 and later |
Relay for unqualified users |
|
LUSER_RELAY |
LUSER_RELAY mc Macro on page 605 |
V8.7 and later |
Relay for unknown local users |
|
MAIL_HUB |
MAIL_HUB mc Macro on page 605 |
V8.6 and later |
All local delivery on a central server |
|
SMART_HOST |
SMART_HOST mc macro on page 597 |
V8.6 and later |
The ultimate relay |
|
UUCP_RELAY |
UUCP_RELAY mc Macro on page 606 |
V8.1 and later |
The UUCP relay |
All relays are declared in the same fashion. For example:
define(`LOCAL_RELAY',`agent:host')
Here, agent is the name of a
delivery agent to use, and host
is the name of the machine to which all such mail will be
relayed. If agent: is missing, it
defaults to a literal relay:.
If the host is listed under a
domain that uses wildcard MX records (Wildcard MX Records on page 335), you
should specify it with a trailing dot, as, for
example:
define(`LOCAL_RELAY', `smtp:relay.sub.domain.')
↑
trailing dotIn The parse Rule Set 0 on page 696, we deal
with the flow of rules through the parse rule set 0. For now, merely note
that relays fit into the flow of rules through the parse rule set 0 like
this:
Basic canonicalization (list syntax, delete local host, etc.)
LOCAL_RULE_0 (LOCAL_RULE_0 mc macro on page 596)
FEATURE(ldap_routing) (FEATURE(ldap_routing) on page 922)
FEATURE(virtusertable) (FEATURE(virtusertable) on page 645)
Addresses of the form “user@$=w” passed to local delivery agent
FEATURE(mailertable) (FEATURE(mailertable) on page 629)
UUCP_RELAY, BITNET_RELAY, FAX_RELAY, DECNET_RELAY
LOCAL_NET_CONFIG
SMART_HOST (SMART_HOST mc macro on page 597)
SMTP, local, etc. delivery agents
When configuring with the mc
method, you can specify a host that will transfer
mail between the Internet and BITNET. Mail to BITNET
can then be sent by appending the pseudodomain
.BITNET to an
address. For example:
user@ucbicsi.BITNET
Here, ucbicsi is a
BITNET host.
To allow your configuration file to handle this form of address, you need to declare the name of your BITNET relay using the BITNET_RELAY keyword:
define(`BITNET_RELAY', `relay_host')dnlThis statement causes the rule for BITNET to be
included in your configuration file and causes
relay_host to become
the host to which BITNET mail is sent.
See Relays on page 602 for a
description of how to include a delivery agent
specification with
relay_host. See also,
bitdomain
feature (FEATURE(bitdomain) on page 617) for a way to convert BITNET
addresses to Internet addresses for hosts that have
both.
DECnet addresses are of the form node::user. They can be handled by defining a host that will relay them into your DECnet network. Using the mc configuration method, you enable DECnet like this:
define(`DECNET_RELAY', `relay_host')dnlMail addressed to node::user will
then be forwarded to
relay_host, as will any
Internet-style addresses that end in the
pseudodomain .DECNET, such as
user@domain.DECNET.
At many sites, faxes can be sent via email. When the host that dispatches those faxes is not the local host, you need to relay fax mail to the host that can dispatch faxes. This ability is enabled by defining that relay host with the FAX_RELAY mc configuration macro:
define(`FAX_RELAY', `relay_host')dnlThis causes all mail that ends with the pseudodomain
.FAX to be
forwarded to
relay_host.
On the fax relay machine, you will also have to declare the fax delivery agent with the MAILER( ) mc command (MAILER( ) m4 macro on page 590).
Unless you specify otherwise, any address that is a
username without any @host part
is delivered using the local delivery agent. If you prefer to
have all such mail handled by a different machine,
you can define that other machine with the
LOCAL_RELAY mc macro.
Note that a relay is different from the knowledgeable hub defined with MAIL_HUB. (See later in this chapter for an illustration of how MAIL_HUB and LOCAL_RELAY interact.)
This mc macro is deprecated because it doesn’t work well with some MUAs—for example, mh( ). This is because some MUAs put a host part on all addresses even if only the user part was specified.
Some unqualified usernames (names without an @host part) need to be delivered on the local machine even if LOCAL_RELAY is defined. The user root is one such example. By remaining local, aliasing is allowed to take place.
The LOCAL_USER mc macro is used to add additional usernames to the list of local users. Note that prior to V8.12, root was always a member of that list:
LOCAL_USER(`operator') LOCAL_USER_FILE(`path') ← V8.12 and later
Here, the first line causes the name
operator to be appended to
the list of local users. The second line causes the
list of local users to be read from the file named
path. The disposition
of local usernames, which include the domain of the
local host is determined by the stickyhost feature
(FEATURE(stickyhost) on page 642).
A local user is one who evaluates to delivery on the local machine, even after aliasing. By defining LUSER_RELAY:
define(`LUSER_RELAY', `relay_host')dnlany username that is not found in the
passwd(5) file will be
forwarded to relay_host.
This check is made after aliasing but before
processing of the ~/.forward
file.
The mc method adds rules to the
localaddr rule
set 5 that cause the user to be looked up with the
user database
type (see the name field lookup for that type in
user on page 945). If the user’s
name is not found, the message is forwarded to
relay_host.
See Relays on page 602 for a
description of how to include a delivery agent
specification with
relay_host. Also see
the V8.12 FEATURE(preserve_luser_host) (FEATURE(preserve_luser_host) on page 638) for a way to preserve the
recipient’s hostname when using this LUSER_RELAY
m4 configuration
macro.
One scheme for handling mail is to maintain one mail spool directory centrally and to mount that directory remotely on all clients. To avoid file-locking problems, delivery to such a spool should be performed only on the central server. The MAIL_HUB mc macro allows you to specify that all local mail be forwarded to the central server for delivery. The point is to let unqualified names be forwarded through a machine with a large aliases file.
If you define both LOCAL_RELAY and MAIL_HUB,
unqualified names and names in the class $=L are sent to
LOCAL_RELAY and other local names are sent to
MAIL_HUB. To illustrate, consider the result of
various combinations for the user
you on the machine
here.our.site.
If LOCAL_RELAY is defined as relay.our.site and MAIL_HUB is not defined, mail addressed to you is forwarded to relay.our.site, but mail addressed to you@here.our.site is delivered locally.
If MAIL_HUB is defined as hub.our.site and LOCAL_RELAY is not defined, mail addressed to you and mail addressed to you@here.our.site is forwarded to hub.our.site for delivery.
If both LOCAL_RELAY and MAIL_HUB are defined as shown earlier, mail addressed to you is sent to relay.our.site for delivery, and mail addressed to you@here.our.site is forwarded to hub.our.site.
If you want all outgoing mail to go to a central machine, use SMART_HOST too.
Note that LOCAL_RELAY is considered most useful when
combined with the FEATURE(stickyhost) (FEATURE(stickyhost) on page 642). Also note that the FEATURE(nullclient)
(FEATURE(nullclient) on page 637) can be used if you want all mail to
be forwarded to a central machine no matter
what.
UUCP is usually modem-based and typically connects two individual machines together. Unlike domain-based delivery, UUCP delivery is from one machine to the next, and then from that next machine to yet another (using addresses such as fbi!wash!gw).
If your site handles UUCP traffic, that handling can be in one of two forms. Either a given host has direct UUCP connections or it does not. If it does not, you might wish to have all UUCP mail forwarded to a host that can handle UUCP. This is done by defining a UUCP_RELAY, which is defined just as you would define any other relay (as described in Relays on page 602).
If your machine or site does not support UUCP, we
recommend disabling all UUCP with the FEATURE(nouucp) (FEATURE(nouucp)
on page 636).
If your machine has directly connected UUCP hosts, you
might wish to use one or more of the UUCP
techniques. But before doing so, be sure to declare
the uucp delivery
agent (MAILER( ) m4 macro on page 590).
The mc configuration technique includes four UUCP options to choose from. They are listed in Table 17-5.
|
Relay |
§ |
Versions |
Description |
|
LOCAL_UUCP |
The LOCAL_UUCP mc Macro on page 609 |
V8.13 and later |
Add new rules and rule sets to select a UUCP delivery agent |
|
SITE |
SITE mc Macro (Obsolete) on page 609 |
V8.1 and later |
Declare sites for SITECONFIG (obsolete) |
|
SITECONFIG |
SITECONFIG mc Macro (Obsolete) on page 609 |
V8.1 and later |
Local UUCP connections (obsolete) |
|
UUCP_RELAY |
UUCP_RELAY mc Macro on page 606 |
V8.1 and later |
The UUCP relay |
|
UUCPSMTP |
UUCPSMTP mc Macro on page 610 |
V8.1 and later |
Individual UUCP-to-network translations |
Note that two items in the table are marked as obsolete. This
is because all their functions have been moved into the
FEATURE(mailertable) (FEATURE(mailertable)
on page 629). They are included for backward compatibility
with early configuration file versions.
Support for UUCP can be included in your mc file with the MAILER command:
MAILER(`uucp')
This declares six[239] delivery agents and the rules to support them. They are listed in Table 17-6.
|
Agent |
§ |
Versions |
Description |
|
|
uucp-old (a.k.a. uucp) on page 608 |
V8.6 and later |
Old-style, all ! form of UUCP |
|
|
uucp-old (a.k.a. uucp) on page 608 |
V8.1 and later |
Synonym for the above (obsolete) |
|
|
uucp-new (a.k.a. suucp) on page 608 |
V8.6 and later |
Old-style with multiple recipients |
|
|
uucp-new (a.k.a. suucp) on page 608 |
V8.1 and later |
Synonym for the above (obsolete) |
|
|
uucp-uudom on page 608 |
V8.6 and later |
Domain-form headers, old-form envelope |
|
|
uucp-dom on page 608 |
V8.6 and later |
Domain-form headers and envelope |
If support for SMTP delivery agents is also included prior to
UUCP, the last two additional delivery agents are included
(uucp-dom and
uucp-uudom). Note
that smtp must be first
for this to happen:
MAILER(`smtp') MAILER(`uucp')
If uucp is first, uucp-dom and uucp-uudom are
excluded.
When processing UUCP mail (addresses that contain a ! and those that end in a
.UUCP suffix), sendmail routes to those
hosts on the basis of the class in which they were found.
Hosts that are found in $=U are delivered via uucp-old, hosts in
$=Y are delivered
via uucp-new, and hosts
in $=Z are delivered via
uucp-uudom.
The choice of which delivery agent to use for UUCP delivery is
under the control of the SITECONFIG mc
macro (SITECONFIG mc Macro (Obsolete)
on page 609). Which you choose depends on what version of
UUCP you are running locally and what version is being run
at the other end of the connection. There are far too many
variations on UUCP to allow specific recommendations here.
In general, you need to choose between a domain form of
address (gw@wash.dc.gov) and a UUCP form
(wash!gw) and then go with the
delivery agent that makes the most sense for you. We
recommend that you start with the most domain-correct agent,
uucp-dom, and see
if it works for you. If not, scale back to uucp-uudom, then to
uucp-new, and
finally to uucp-old as a
last resort.
If you are running an old version of UUCP, you might
have to use this delivery agent. All addresses are
turned into the !
form even if they were in domain form:
user becomes → yourhost!user user@host.domain becomes → yourhost!host.domain!user
This delivery agent can deliver to only one recipient at a time, so it can spend a lot of time transmitting duplicate messages. If at all possible, avoid using this delivery agent.
Newer releases of UUCP can send to multiple recipients
at once. If yours is such a release, you can use the
uucp-new
delivery agent. It is just like uucp-old except that it
can perform multiple deliveries.
More modern implementations of UUCP can understand and
correctly handle domain-style addresses in headers
(although they still require the ! form in the envelope).
If yours is such an implementation, you can use the
uucp-uudom
delivery agent.
At the receiving end, the message mail arrives with
the five-character "From" line showing the sender address
in the ! form.
The "From" line
reflects the envelope address.
The uucp-dom is the
most domain-correct form of the available UUCP
delivery agents. All addresses, envelopes, and
headers, regardless of whether they began in the
! form, are
sent out in domain form. Essentially, this uses UUCP
as a transport mechanism, but in all other respects
it adheres to the Internet standards.
If you enable UUCP, the parse rule set 0 normally adds rules
that select UUCP delivery agents. First, locally
connected UUCP addresses are detected and the
appropriate UUCP delivery agent is selected based on
each such address found. Addresses in the class
$=Z select the
uucp-uudom
delivery agent. Addresses in the class $=Y select the uucp-new delivery agent.
And addresses in the class $=U select the uucp-old delivery agent.
Finally, the parse
rule set 0 adds rules that detect remotely connected
UUCP addresses.
Beginning with V8.13, if you need to add rules between
these two phases (between the detection of local
UUCP addresses and remote UUCP addresses), you may
do so by utilizing this new LOCAL_UUCP
mc macro. For
example, the following mc file entry:
LOCAL_UUCPR$* < @ $={ServerUUCP} . UUCP. > $* $#uucp-uudom $@ $2 $: $1 < @ $2 .UUCP. >$3
causes the preceding new rule to be added to the
parse rule set
0 in the location shown here:
# resolve locally connected UUCP links...← New rules added here# resolve remotely connected UUCP links (if any)
Note that the LOCAL_UUCP
mc macro is not
intended for casual use. It should be used only to
solve special UUCP needs that cannot be solved using
more conventional methods.
UUCP connections are declared inside the SITECONFIG file with the SITE mc macro. That mc macro just takes a list of one or more UUCP hostnames:
SITE(lady) SITE(sonya grimble)
Each listed host is added to the class that was defined as the third argument to the SITECONFIG declaration.
The SITECONFIG mc macro is
obsolete but has been retained for backward
compatibility. It has been replaced by the FEATURE(mailertable)
(FEATURE(mailertable) on page 629).
The SITECONFIG mc macro is useful for maintaining lists of UUCP connections. There are two types of connections: those connected to the local host and those connected to another host. The first type is declared with SITECONFIG like this:
SITECONFIG(`file',` host',`class')
Here, file is the name of a
file (without the .m4 suffix)
that is in the directory
cf/siteconfig. That file
contains a list of SITE declarations (described
earlier). The host is the
UUCP node name of the local host. The
class is the name (one
letter, or multicharacter) of a class that holds the
list of UUCP connections. For example:
SITECONFIG(`uucp.arpa',`arpa',`U')
SITECONFIG(`uucp.arpa',`arpa',`{MyUUCPclass}')Here, the file
cf/siteconfig/uucp.arpa.m4
contains a list of UUCP hosts directly connected to
the machine arpa. This
declaration would be used only in the machine
arpa’s
mc file. The list of UUCP
hosts is added to the sendmail
class-macro $=U
in the first example, and $={MyUUCPclass} in the second.
Some single-character letters are special. The special
letters available for local connections are U (for uucp-old), Y (for uucp-new), and Z (for uucp-uudom).
A second form of the SITECONFIG mc macro is used by hosts other than the host with the direct UUCP connections. It is just like the earlier form but with the full canonical name of the host:
SITECONFIG(`uucp.arpa',`arpa.Berkeley.EDU',`W')
This also reads the file uucp.arpa.m4, but instead of causing UUCP connections to be made locally, it forwards them to the host arpa.Berkeley.EDU.
The hostname that is the second argument is assigned
to the $W
sendmail macro. The class
$=W is set
aside to hold lists of hosts that appear locally
connected. This class is also used with the SITE
mc macro. The letters that
are available for remote sites are V, W, and X.
If nothing is specified, the class becomes Y. If class U is specified in the
third parameter, the second parameter is assumed to
be the UUCP name of the local site, rather than the
name of a remote site. In this latter case, the
specified local name has a .UUCP appended, and the result is added
to class w.
Note that SITECONFIG won’t work if you disable UUCP
with FEATURE(nouucp) (FEATURE(nouucp)
on page 636).
If your site has a host that used to be a UUCP site but is now on the network, you can intercept and rewrite the old address of that host into the new network address. For example, mail to the machine wash used to be addressed as wash!user. Now, however, wash is on the network, and the mail should be addressed as user@wash.dc.gov.
The UUCPSMTP mc macro provides the means to specify a UUCP-to-network translation for specific hosts. The earlier example would be declared like this:
LOCAL_RULE_3 UUCPSMTP(`wash',`wash.dc.gov')
The UUCPSMTP mc macro should be used only under LOCAL_RULE_3.
The use of the # to place comments into a .mc file for eventual
transfer to your configuration file might not work
as expected. The # is not special to the
m4 processor, so
m4 continues to process a
line even though that line is intended to be a
comment. So, instead of:
# Here we define $m as our domain
(which would see define as an m4
keyword), use single quotes to insulate all such
comments from m4
interpretation:
# `Here we define $m as our domain'
Never blindly overwrite your sendmail.cf file with a new one. Always compare the new version to the old first:
% diff /etc/mail/sendmail.cf oursite.cf
19c19
< ##### built by you@oursite.com on Sat Nov 3 11:26:39 PDT 2007
---
> ##### built by you@oursite.com on Fri Dec 14 04:14:25 PDT 2007Here, the only change was the date the files were built, but if you had expected some other change, this would tell you the change had failed.
Never edit your sendmail.cf file directly. If you do, you will never be able to generate a duplicate or update from your mc file. This is an especially serious problem when upgrading from one release of sendmail to a newer release. Should you make this mistake, reread the appropriate sections in this book and the documentation supplied with the sendmail source.
Don’t assume that UUCP support and UUCP
relaying are turned off by default. Always use
FEATURE(nouucp)
(FEATURE(nouucp)
on page 636) to disable UUCP unless you actually
support UUCP:
FEATURE(`nouucp') ← recommended through V8.9 FEATURE(`nouucp',`reject') ← recommended with V8.10 and later
In this section, we detail each feature available when configuring with the mc configuration method. We list them briefly in Table 17-7, and explain them in greater detail in the text that follows. Note that a comprehensive list of all mc configuration macros and features is available in Appendix A.
|
FEATURE( ) |
§ |
Description |
|
|
FEATURE(accept_unqualified_senders) on page 614 |
Allow unqualified |
|
|
FEATURE(accept_unresolvable_domains) on page 614 |
Accept unresolvable domains. |
|
|
The access Database on page 277 |
A database for mail policy. |
|
|
FEATURE(allmasquerade) on page 615 |
Masquerade recipient as well as sender. |
|
|
FEATURE(always_add_domain) on page 616 |
Add the local domain even on local mail. |
|
|
FEATURE(authinfo) on page 616 |
Use a separate database for authentication information. |
|
|
FEATURE(badmx)—V8.14 and Later on page 291 |
Rejects a client host name, the domain part of which resolves to a bad MX record (V8.14 and later). |
|
|
FEATURE(bestmx_is_local) on page 617 |
Accept best MX record as local if in
|
|
|
FEATURE(bitdomain) on page 617 |
Convert BITNET addresses into Internet addresses (deprecated). |
|
|
Reject per Recipient on page 284 |
Look up recipients in access database. |
|
|
FEATURE(block_bad_helo)—V8.14 and Later on page 292 |
Rejects clients who provide a HELO/EHLO argument that is either unqualified or one of the server’s names (V8.14 and later). |
|
|
FEATURE(compat_check) on page 619 |
Screen sender/recipient pairs. |
|
|
FEATURE(conncontrol) on page 619 |
Limit simultaneous connections to your machine from another machine (V8.13 and later). |
|
|
Accept and Reject per Recipient on page 284 |
Check SMTP |
|
|
FEATURE(dnsbl) on page 261 |
Reject based on various DNS blacklists. |
|
|
FEATURE(domaintable) on page 621 |
Rewrite old domain as equivalent to new domain. |
|
|
FEATURE(enhdnsbl) on page 263 |
Enhanced |
|
|
FEATURE(generics_entire_domain) on page 622 |
Match subdomains in |
|
|
FEATURE(genericstable) on page 622 |
Transform sender addresses. |
|
|
FEATURE(greet_pause)—V8.13 and Later on page 293 |
Suppress slamming by detecting advance writes (V8.13 and later). |
|
|
ldap (was ldapx) on page 912 |
Reroute recipients based on LDAP lookups. |
|
|
FEATURE(limited_masquerade) on page 625 |
Only masquerade MASQUERADE_DOMAIN hosts. |
|
|
FEATURE(local_lmtp) on page 625 |
Deliver locally with LMTP and mail.local. |
|
|
FEATURE(local_no_masquerade) on page 626 |
Don’t masquerade local mail. |
|
|
FEATURE(local_procmail) on page 627 |
Use procmail(1), etc. as local delivery agent. |
|
|
FEATURE(lookupdotdomain) on page 628 |
Enable .domain secondary access.db lookups. |
|
|
FEATURE(loose_relay_check) on page 270 |
Allow %-hack relaying. |
|
|
FEATURE(mailertable) on page 629 |
Database selects new delivery agents. |
|
|
FEATURE(masquerade_entire_domain) on page 631 |
Masquerade all hosts under a domain. |
|
|
FEATURE(masquerade_envelope) on page 632 |
Masquerade the envelope as well as headers. |
|
|
FEATURE(mtamark)—V8.13 and Later, Experimental on page 295 |
Experimental support for the MTA Mark approach (V8.13 and later). |
|
|
FEATURE(msp) on page 633 |
Create a mail submission cf file. |
|
|
FEATURE(nocanonify) on page 634 |
Don’t canonify with |
|
|
FEATURE(nodns) on page 635 |
Omit DNS support from configuration file (deprecated V8.7 through V8.12, removed as of V8.13). |
|
|
FEATURE(no_default_msa) on page 635 |
Disable automatic listening on MSA port 587. |
|
|
FEATURE(notsticky) on page 636 |
Don’t differ unqualified versus qualified addresses. |
|
|
FEATURE(nouucp) on page 636 |
Eliminate all UUCP support. |
|
|
FEATURE(nullclient) on page 637 |
Relay all mail through a mail host. |
|
|
FEATURE(preserve_local_plus_detail) on page 637 |
Retain plussed addresses for delivery. |
|
|
FEATURE(preserve_luser_host) on page 638 |
Preserve recipient host with LUSER_RELAY. |
|
|
FEATURE(promiscuous_relay) on page 271 |
Allow unbridled relaying. |
|
|
FEATURE(queuegroup) on page 638 |
Select queue groups via the |
|
|
FEATURE(ratecontrol) on page 638 |
Limit the rate at which other MTAs may connect to yours (V8.13 and later). |
|
|
FEATURE(rbl) on page 640 |
Reject connections based on rbl.maps.vix.com (V8.9 through V8.11). |
|
|
FEATURE(redirect) on page 640 |
Add support for address.REDIRECT aliases. |
|
|
FEATURE(relay_based_on_MX) on page 271 |
Relay based on MX records. |
|
|
FEATURE(relay_entire_domain) on page 272 |
Relay based on |
|
|
FEATURE(relay_hosts_only) on page 273 |
Relay individual hosts, not domains. |
|
|
FEATURE(relay_local_from) on page 273 |
Relay based on |
|
|
FEATURE(relay_mail_from) on page 274 |
Relay based on |
|
|
FEATURE(require_rdns)—V8.14 and Later on page 296 |
Rejects clients whose IP address cannot be properly resolved (V8.14 and later). |
|
|
Configure to Use smrsh on page 380 |
Use smrsh (sendmail restricted shell). |
|
|
FEATURE(stickyhost) on page 642 |
Differ unqualified from qualified addresses. |
|
|
FEATURE(use_client_ptr)—V8.13 and Later on page 297 |
Replace IP address with |
|
|
FEATURE(use_ct_file) on page 643 |
Use /etc/mail/trusted-users for trusted users. |
|
|
FEATURE(use_cw_file) on page 643 |
Use /etc/mail/local-host-names for local hosts. |
|
|
FEATURE(uucpdomain) on page 644 |
Convert UUCP hosts via a database (deprecated). |
|
|
FEATURE(virtuser_entire_domain) on page 645 |
Match subdomains in the virtual user table. |
|
|
FEATURE(virtusertable) on page 645 |
Support for virtual domains. |
Note that this reference is not comprehensive. Options, sendmail macros, and delivery agents, for example, are described in chapters dedicated to those topics.
Allow unqualified MAIL From: V8.9 and later
The MAIL From:
command of the SMTP transaction is used to convey
the address of the envelope sender. RFC821 requires
that the envelope sender address always be fully
qualified. That is, it must always have a user part,
an @ character,
and a domain part, in that order.
The normal behavior of sendmail is to reject the envelope sender if it is not fully qualified. For example:
MAIL From: <you> 553 5.5.4 <you>... Domain name required
This rejection is done for network connections only.
When reading the envelope sender via the standard
input under the -bs command-line switch (-bs on page 236) a missing
@domain part is OK:
%/usr/sbin/sendmail -bs220 yourhost.domain ESMTP Sendmail 8.14.1/8.14.1; Fri, 14 Dec 2007 14:13:09 −0700HELO yourhost250 yourhost.domain Hello your@yourhost.domain, pleased to meet youMAIL From: <bob>250 2.1.0 <bob>... Sender ok
If machines at your site routinely send unqualified envelope sender addresses (addresses without the @domain part), you will find that mail is being rejected.
Your first attempt at a solution should be to fix the
broken software that is sending unqualified
addresses. If that fails, or if you lack the
permission or authority, you can use this accept_unqualified_senders feature to
force sendmail to accept
unqualified envelope sender addresses:
FEATURE(`accept_unqualified_senders')
Another way to handle this problem is with the (V8.10
and later) DaemonPortOptions option’s Modifier key value
(DaemonPortOptions=Modify=
on page 996). If that value includes a u character, unqualified
envelope sender addresses are accepted even if this
feature is omitted. Even if this feature is
included, the presence of an f in the DaemonPortOptions
option’s Modifier
key value causes the normal behavior of enforcing
fully qualified addresses.
Accept unresolvable domains V8.9 and later
The MAIL From:
command of the SMTP transaction is used to convey
the address of the envelope sender. RFC821 requires
that the envelope sender address always be fully
qualified. That is, it must always have a user part,
an @ character,
and a domain part, in that order.
Ordinarily, sendmail looks up the domain part of the address using DNS, and, if not found, rejects that SMTP transaction. For example:
MAIL From: <you@nosuch.host> 501 5.1.8 <you@nosuch.host>... Sender domain must exist
This is useful in blocking spam and fraudulent mail. However, if your machine is behind a firewall, it is possible that it cannot look up any outside addresses. In that situation, all mail from the outside will fail.
If you need to allow all mail to be received when the
domain part of the envelope sender address cannot be
looked up, you can do so by declaring FEATURE(accept_unresolvable_domains):
FEATURE(`accept_unresolvable_domains')
You can also declare this feature on a machine that is dedicated to a special purpose. A machine dedicated to receiving and processing survey reply mail might be a good candidate for this feature. If you don’t care about the spam protection offered without this feature, go ahead and declare it.
A database for mail policy V8.9 and later
Prior to V8.9, the only way to accept or reject mail from selected sites was to use tcpwrappers, or to write your own custom rule sets and rules. Beginning with V8.9, sendmail offers a database which provides that same service, and more (such as feature selection and policy control), in a much more easily configurable way. See The access Database on page 277 for a detailed description of this feature.
Masquerade recipient as well as sender V8.2 and later
If a MASQUERADE_AS domain is defined, that name
replaces any sender addresses, the domain part of
which is listed either by MASQUERADE_DOMAIN (MASQUERADE_DOMAIN mc Macro
on page 600) or in the $=w class ($=w on page 876). FEATURE(allmasquerade)
causes header recipient addresses to also have that
treatment.
But note that this feature can be extremely risky and
that it should be used only if the MASQUERADE_AS
host has an aliases file that
is a superset of all aliases
files and a passwd file that is
a superset of all passwd files
at your site. To illustrate the risk, consider a
situation in which the masquerade host is named
hub.domain and mail is being
sent from the local workstation. If a local alias
exists on the local workstation—say,
thishost-users—that does not
also exist on the masquerade host, FEATURE(allmasquerade)
will cause the To: header to go out as:
To: thishost-users@hub.domain
Here, the address thishost-users does not exist on the masquerade host (or worse, might show up as a user part with a host part from an arbitrary Internet site), and as a consequence, replies to messages containing this header will bounce.
The form for FEATURE(allmasquerade) is:
MASQUERADE_AS(`your.hub.domain') FEATURE(`allmasquerade')
Note that MASQUERADE_AS (MASQUERADE_AS mc Macro on page 600) must also be defined and must contain a fully qualified hostname.
Add the local domain even on local mail V8.1 and later
Normally, header recipient addresses and header and
envelope sender addresses that are local are left as
is. If FEATURE(always_add_domain) is defined,
local addresses that lack a host part have an
@ and the
MASQUERADE_AS host appended (if it is defined). If
MASQUERADE_AS is not defined, an @ and the value of the
$j
sendmail macro ($j on page 830) are
appended.
The form for the always_add_domain feature is:
FEATURE(`always_add_domain')
The always_add_domain feature is safe and
recommended. It ensures that all addresses that are
locally delivered will be fully qualified. See
FEATURE(allmasquerade) (FEATURE(allmasquerade)
on page 615) for a description of the risks
surrounding masquerading addresses.
Use a separate database for authentication information V8.12 and later
Beginning with V8.12, FEATURE(authinfo) tells
sendmail to look in a special
database file called authinfo
for authentication information, rather than in the
access database. This means
you can have more secure permissions for the
authinfo database than for
the access database. FEATURE(authinfo) is
declared like this:
FEATURE(`authinfo')
This creates a default configuration declaration that looks like this:
Kauthinfo hash /etc/mail/authinfo
Here the hash is
derived from the setting of the DATABASE_MAP_TYPE
mc configuration macro (Set a Default Database-Map Type for Features on page 897) and the /etc/mail is derived from the setting
of the MAIL_SETTINGS_DIR mc
macro (The MAIL_SETTINGS_DIR mc Macro on page 68). If you wish to change the defaults
without having to change these two
mc configuration macros, you
can simply define that new default by adding a
second argument to the feature declaration:
FEATURE(`authinfo', `hash /etc/private/authinfo')
If you provide a second argument and the second argument is a literal LDAP:
FEATURE(`authinfo', `LDAP')
the default becomes the following (we have wrapped the lines to fit the page):
Kauthinfo ldap −1 -v sendmailMTAMapValue -k (&(objectClass=sendmailMTAMapObject)
(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))
(sendmailMTAMapName=authinfo)(sendmailMTAKey=%0))See ldap (was ldapx) on page 912 for a description of the ldap database type and
its −1, -v, and -k switches. See Authinfo and the access database (V8.12 and
later) on page 195 for a description of the authinfo database’s
contents and how to create that database.
Reject a domain with bad MX record V8.14 and later
This feature rejects a client hostname, whose domain part resolves to a bad MX record. See FEATURE(badmx)—V8.14 and Later on page 291 for a full description of this feature.
Accept best MX record as local if in $=w V8.6 and later
The class $=w
($=w on page 876)
defines which hostnames will be treated as being
equivalent to the local hostname. That method,
however, requires that the mail administrator
manually keep the class up-to-date.
As an alternative, for low- to medium-volume sites,
use FEATURE(bestmx_is_local). When enabled,
this feature looks up each hostname that it finds in
the bestmx
internal database map (bestmx on
page 902). That map returns the best MX record (if
it is known) for that name. That returned record is
then compared to the list of hostnames in class
$=w to see
whether it is equivalent to the local host. If so,
the address is accepted for local delivery.
The form for FEATURE(bestmx_is_local) is:
FEATURE(`bestmx_is_local')
If you wish to limit lookups to a small list of domains, you can add them as a second argument:
FEATURE(`bestmx_is_local', `domain1 domain2 etc.')Only the hosts listed are allowed to list your site as the best MX record for use with this feature.
Use of this feature is best limited to low-volume
sites. Looking up every address in the bestmx map can cause
numerous DNS enquiries. At high-volume sites, the
magnitude of extra DNS enquiries can adversely tax
the system and network.
There is also a risk to this feature. Someone could create an MX record for your site without your knowledge. Bogus mail might then be accepted at your site without your permission:
bogus.site.com. IN MX 0 your.real.domain
Here, mail to bogus.site.com
would be sent to your site, where the name
bogus.site.com would be
looked up with FEATURE(bestmx_is_local). Your
sendmail would find itself
listed as the MX for
bogus.site.com and so would
accept the bogus mail and attempt to deliver it
locally. If the bogus name were designed to
discredit you, it could be set to
sex.bogus.site.com, for
example, and mail to root@sex would
be delivered to you without you knowing the
reason.
Convert BITNET addresses into Internet addresses Deprecated
This FEATURE(bitdomain) is deprecated
because its functionality can be handled by the
newer FEATURE(domaintable) (FEATURE(domaintable) on page 621). In case you still need to use
FEATURE(bitdomain), we continue to
describe it here.
Many Internet hosts have BITNET addresses that are separate from their Internet addresses. For example, the host icsi.berkeley.edu has the registered BITNET name ucbicsi. If a user tried to reply to an address such as:
user@ucbicsi.bitnet
that mail would fail. To help with translating registered BITNET names into Internet addresses, John Gardiner Myers has supplied the bitdomain program in the contrib subdirectory. It produces output in the form:
ucbicsi icsi.berkeley.edu
that can be put into database form for use with the
K configuration
command. FEATURE(bitdomain) causes rules to be
included in the configuration file that perform the
necessary translation:
R$* < @ $+ .BITNET > $* $: $1 < @ $(bitdomain $2 $: $2.BITNET $) > $3
Note that this rule requires BITNET addresses to be so
identified with a .BITNET suffix. If the address, without
the suffix, is found in the bitdomain database, the Internet
equivalent address is used in its place. See also
the UUCPSMTP mc configuration
macro and FEATURE(domaintable).
The form of FEATURE(bitdomain) is:
FEATURE(`bitdomain')
This declaration causes the following K configuration command
to be included in addition to the aforementioned
rule:
Kbitdomain hash /etc/mail/bitdomain
FEATURE(bitdomain)
is one of those that can take an argument to specify
a different form of, or name for, the
database:
FEATURE(`bitdomain',`dbm -o /opt/sendmail/bitdomain')
The extra argument causes the aforementioned K command to be replaced
with the following one:
Kbitdomain dbm -o /opt/sendmail/bitdomain
The earlier bitdomain setting is safe. You can
routinely include it in all configuration files. The
database lookup is performed only if the .BITNET suffix is
present and the database file exists. (See -o on page 889 for a description of
the K command’s
-o
switch.)
You can also provide an extra argument, where that second argument is a literal LDAP:
FEATURE(`bitdomain', `LDAP')
The default in this instance becomes the following (we have wrapped the lines to fit the page):
Kbitdomain ldap −1 -v sendmailMTAMapValue -k (&(objectClass=sendmailMTAMapObject)
(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))
(sendmailMTAMapName=bitdomain)(sendmailMTAKey=%0))See ldap (was ldapx) on page 912 for a description of the ldap database type and
its −1, -v, and -k switches.
Note that you must also define BITNET_RELAY ($B on page 808) if you want
.BITNET-suffixed mail that is not found
in the database to be routed to a relay machine. If
BITNET_RELAY is not defined, .BITNET-suffixed mail
that is not found in the database is bounced.
Look up recipients in access database V8.9 and later
FEATURE(access_db)
(The access Database on page
277) provides a way to selectively reject envelope
sender addresses (and much more). By declaring this
FEATURE(blacklist_recipients), you
enable the access database to also selectively
reject envelope recipient addresses. This feature is
fully described in Reject per Recipient on page
284.
Reject clients with a bad HELO/EHLO hostname V8.14 and later
This feature rejects clients who provide a HELO/EHLO argument that is either unqualified or one of the server’s names. See FEATURE(block_bad_helo)—V8.14 and Later on page 292 for a full description of this feature.
Screen sender/recipient pairs V8.12 and later
Beginning with V8.12 sendmail, it is possible to screen email based on sender and recipient address pairs stored in the access database. One use for such a method might be to prevent one employee from receiving mail from another employee. Another use might be to prevent a pseudouser, such as admin, from receiving spurious reports from another user, such as bin. Yet another use might be to reject spam mail to a mailing list.
FEATURE(compat_check) is described in
full in FEATURE(compat_check)—V8.12 and Later on page 288.
Check SMTP RCPT TO: first V8.13 and later
FEATURE(conncontrol) allows you to use
the access
database to control the number of simultaneous
connections another machine may have to your
server.[240] The number of simultaneous connections
allowed each interval is based on the setting of the
ConnectionRateWindowSize option (ConnectionRateWindowSize on page 989),
which defaults to 60 seconds. So, for example, if
you want to reject a host that has more than 10
simultaneous connections to your server (sometime in
the past 60 seconds), where that host has the IP
address 192.168.23.45, you would put the
following into your access database source file:
ClientRate:192.168.23.45 10
Here, if the host with the IP address 192.168.23.45 tries to
set up an 11th simultaneous connection to your
server, that connection will be denied.
You enable FEATURE(conncontrol) like this:
FEATURE(`conncontrol')
But note, if you have not already declared the access database (The access Database on page 277), you must do so before declaring this new feature, or you will get the following error when building your new configuration file:
*** ERROR: FEATURE(conncontrol) requires FEATURE(access_db)
Once you have successfully enabled this FEATURE(conncontrol),
you may use it to control the number of simultaneous
connections, based on IP addresses of hosts or
networks, or to set the default limit:
ClientRate:192.168.23.45 2 ClientRate:127.0.0.1 0 ClientRate: 10 ClientRate:10.5.2 2 ClientRate:IPv6:2002:c0a8:51d2::23f4 5
Here, the first line (as you have seen) limits the
number of simultaneous connections from the IP
address 192.168.23.45 to no more than
two.
In the second line, which specifies zero, the zero
means that there is no limit imposed on the overall
number of simultaneous connections. This is suitable
for the loopback interface address (127.0.0.1) because that
is where the local submission version of sendmail delivers its
mail.
The third line omits the IP address entirely, thereby setting the default limit for all other IP (unspecified) addresses.
The fourth line shows how network addresses may also be limited.
The last line shows that IPv6 addresses may be
specified merely by prefixing each with a literal
IPv6:.
Note that the limits we show here are just examples, not recommendations. The limits you choose will depend on your particular circumstances.
If you also declare FEATURE(delay_checks) (Accept and Reject per Recipient on
page 284), connection control checks will be
delayed until after the first envelope recipient
has been received. Clearly this makes this
connection check less useful than it should be. If
you use delay_checks, you may add an additional
argument to this FEATURE(conncontrol) to get it to run
as early as possible despite the use of that
delaying feature:
FEATURE(`conncontrol', `nodelay')
Here, the nodelay is literal and prevents
FEATURE(delay_checks) from having any
effect on connection controls. Note that if you
declare both the delay_checks and FEATURE(conncontrol),
FEATURE(delay_checks) must appear first
in your mc
file.
Normally, FEATURE(conncontrol) rejects
connections with a temporary error:
452 Too many open connections
If the connecting client terminates the
connection by sending an SMTP QUIT, connection
control terminates as you would expect. But if the
client chooses to ignore that return value, the
client will be given 4yz SMTP (temporary
rejection) replies to all commands it sends until
it sends an SMTP QUIT command. Clearly this may
not be acceptable at your site. If you want the
connection terminated without regard to the
connecting client’s behavior, you may do so by
adding a second argument to this FEATURE(conncontrol):
FEATURE(`conncontrol', `nodelay', `terminate') FEATURE(`conncontrol', ,`terminate')
Here, the terminate is literal and, when present,
causes all rejected connections to be rejected
with a 421 return code. Note that 421 is special,
because it allows sendmail to terminate the connection
without waiting for the client to send a QUIT. If
you omit the nodelay first argument, you need to use
two commas (as in the second example shown
earlier) to make terminate the second argument.
Check SMTP RCPT TO: first V8.10 and later
This feature is fully described in Accept and Reject per Recipient on page 284.
Reject based on various DNS blacklists V8.10 and later
The original feature was called rbl and caused hosts
listed with the original “real-time blackhole list”
to be rejected. That feature has been deprecated and
replaced by this new FEATURE(dnsbl). With this new feature
you can have hosts rejected by any number of
real-time blackhole lists, including or excluding
the original. This feature is fully described in
FEATURE(dnsbl) on page 261.
Rewrite old domain as equivalent to new domain V8.2 and later
Some sites need to use multiple domain names when
transitioning from an old domain to a new one.
FEATURE(domaintable) enables such
transitions to operate smoothly by rewriting the old
domain to the new. To begin, create a file of the
form:
old.domain new.domain
In it, the left side of each line has one of possibly many fully qualified hostnames, and the right side has the new name. The makemap(1) program (The makemap Program on page 370) is then used to convert that file into a database.
FEATURE(domaintable) causes a rule such
as this to be included in your configuration
file:
R $* < @ $+ > $* $: $1 < @ $(domaintable $2 $) > $3
Here, each host part of an address in the canonify rule set 3 is
looked up in the domaintable map. If it is found, the
new name from that map replaces it.
FEATURE(domaintable) enables this
lookup by including a K configuration command:
Kdomaintable hash /etc/mail/domaintable
The form of FEATURE(domaintable) is:
FEATURE(`domaintable')
FEATURE(domaintable) is one of those
that can take an argument to specify a different
form of, or different name for, the database:
FEATURE(`domaintable',`dbm /etc/mail/db/domaintable')
The extra argument causes the aforementioned K command to be replaced
with the following one:
Kdomaintable dbm /etc/mail/db/domaintable
You can provide an extra argument that is a literal LDAP:
FEATURE(`domaintable', `LDAP')
The default in this instance becomes the following (we have wrapped the lines to fit the page):
Kdomaintable ldap −1 -v sendmailMTAMapValue -k (&(objectClass=sendmailMTAMapObject)
(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))
(sendmailMTAMapName=domain)(sendmailMTAKey=%0))See ldap (was ldapx) on page 912 for a description of the ldap database type and
its −1, -v, and -k switches.
Although this feature might appear suitable for a
service provider that wishes to accept mail for
client domains, it really is not. Such a service
provider should use FEATURE(virtusertable) (FEATURE(virtusertable)
on page 645) instead.
Enhanced dnsbl lookups V8.12 and later
This is an enhanced version of FEATURE(dnsbl) and is
fully described in FEATURE(enhdnsbl) on page 263.
Match subdomains in generics table V8.10 and later
This feature extends the use of the FEATURE(genericstable)
(FEATURE(genericstable)
on page 622). Ordinarily, user addresses whose host
part is listed in a special class defined by the
GENERICS_DOMAIN mc macro (GENERICS_DOMAIN mc macro on
page 624) are looked up in the generics table. Thus,
if the generics table contains this rule:
news news@news.our.domain
and if that special class contains the domain our.domain, only sender addresses of the form news@our.domain would be looked up, and addresses of a subdomain form, such as news@sub.our.domain, would not.
If you declare this FEATURE(generics_entire_domain), and if
you also declare contents for that special class
with either GENERICS_DOMAIN (GENERICS_DOMAIN mc macro on
page 624) or GENERICS_DOMAIN_FILE (GENERICS_DOMAIN_FILE mc macro
on page 624), subdomains are also matched. That is,
with this feature declared,
news@sub.our.domain would
also match and be looked up.
Transform sender addresses V8.8 and later
The User Database (userdb on
page 942) allows recipient addresses to be changed
so that they can be delivered to new hosts. For
example, gw@wash.dc.gov can be
transformed with the User Database into
george@us.edu. The genericstable provides
the same type of transformation on the sender’s
address.
To begin, create a file of the form:
user newuser@new.host.domain user@host.domain newuser@new.host.domain
In it, each line begins with the old address, either the user part alone or the full address. On the right is the new address for that sender. One example of a use for this table might be to make the user news always appear as though it was from the news machine:
news news@news.our.domain news@our.domain news@news.our.domain
Note that the bare user part (news in the first line) is looked up
only if sendmail considers it
to be in the local domain. If a domain is listed (as
in the second line in the preceding example), that
entry is looked up only if it is in a special class
defined with the GENERICS_DOMAIN
mc macro (GENERICS_DOMAIN mc macro on
page 624). If you want subdomains to also match, you
must declare FEATURE(generics_entire_domain) (FEATURE(generics_entire_domain) on page 622). Ways to list domains in that
special class are outlined later in this
chapter.
The makemap(1) program (The makemap Program on page 370) is then used to convert this file into a database:
makemap hash db_file < text_fileHere, db_file is the name
you give to the created database, and
text_file is the name
of the source text file.
Note that local and nonlocal hosts can appear in the
special class defined with the GENERICS_DOMAIN
mc macro. Also note that the
members of $=w
are not automatically placed
into this special class.
FEATURE(genericstable) enables this
lookup by including a K configuration command:
Kgenerics hash /etc/mail/genericstable
The form for this FEATURE(genericstable) declaration
is:
FEATURE(`genericstable')
FEATURE(genericstable) is one of those
that can take an argument to specify a different
form of, or a different name for, the
database:
FEATURE(`genericstable',`dbm -o /etc/mail/genericstable')
The extra argument causes the earlier K command to be replaced
with the following one:
Kgenerics dbm -o /etc/mail/genericstable
See -o on page 889 for a
description of the K command -o switch.
You can also provide an extra argument that is a literal LDAP:
FEATURE(`domaintable', `LDAP')
The default in this instance becomes the following (we have wrapped the lines to fit the page):
Kgenerics ldap −1 -v sendmailMTAMapValue -k (&(objectClass=sendmailMTAMapObject)
(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))
(sendmailMTAMapName=generics)(sendmailMTAKey=%0))See ldap (was ldapx) on page 912 for a description of the ldap database type and
its −1, -v, and -k switches.
The genericstable
should be enabled only if you intend to use it. It
causes every sender to be looked up in that
database.
Beginning with V8.8
sendmail, a new
mc macro was introduced to
make it easier to list domains for use with
FEATURE(genericstable). Called
GENERICS_DOMAIN, it is used like this:
GENERICS_DOMAIN(`domain1 domain2 etc.')
Each domain that you intend to list should be listed individually and separated from the others by spaces. Multiple GENERICS_DOMAIN lists can be declared in your mc file:
GENERICS_DOMAIN(`domain1')
GENERICS_DOMAIN(`domain2')
GENERICS_DOMAIN(`etc.')If you are currently declaring the $=G class directly under
the LOCAL_CONFIG mc macro,
you are encouraged to convert to this new
mc macro. Use of it will
insulate you from change in the future if a
different sendmail class is
ever used.
Beginning with V8.8
sendmail, a new
mc macro was introduced to
make it easier to list domains with FEATURE(genericstable).
Called GENERICS_DOMAIN_FILE, it is used like
this:
GENERICS_DOMAIN_FILE(`/etc/mail/genericdomains')
This declaration causes the list of domains to
be read from the file
/etc/mail/genericdomains.
Because GENERICS_DOMAIN_FILE is implemented with
an F
configuration command (The F Class Command on page 857), you
can add whatever F command arguments you desire. For
example:
GENERICS_DOMAIN_FILE(`-o /etc/mail/genericdomains')
Here, the -o switch makes the presence of the
/etc/mail/genericdomains file
optional.
If you are currently reading a list of domains
from a file declared with an FG configuration
command, you are encouraged to convert to this new
macro. Use of it will insulate you from change in
the future if a different class is ever
used.
Block slamming by detecting advance writes V8.13 and later
This FEATURE(greet_pause) allows you to
block sites that write SMTP commands before reading
the prior reply. This feature is described in FEATURE(greet_pause)—V8.13 and Later on page 293.
Reroute recipients based on LDAP lookups V8.10 and later
This FEATURE(ldap_routing) allows recipients
to be rerouted in much the same fashion as the User
Database, but by using an LDAP database instead. See
ldap (was ldapx) on page 912 for a complete description of this
feature.
Only masquerade MASQUERADE_DOMAIN hosts V8.8 and later
Ordinarily, addresses can be masqueraded if they are
unqualified (lack a domain part) or if they match
any hostname in $=w ($=w
on page 876) or in the special class defined by the
MASQUERADE_DOMAIN mc macro
(MASQUERADE_DOMAIN mc Macro
on page 600). Masquerading replaces the hostname
part of an address with the fully qualified hostname
defined by MASQUERADE_AS.
Some sites handle mail for multiple domains. For these
sites, it is important to recognize all incoming
mail as local via $=w. On the other hand, only a subset
of the hosts in $=w should be masqueraded. Consider,
for example, the host
our.domain that receives mail
for the domains his.domain and
her.domain:
Cw our.domain his.domain her.domain
In this scenario, we want all but
her.domain to be masqueraded
as our.domain. The way to
create such exceptions is with FEATURE(limited_masquerade).
FEATURE(limited_masquerade) causes
masquerading to be based only on the special class
defined by the MASQUERADE_DOMAIN
mc macro (MASQUERADE_DOMAIN mc Macro
on page 600) and not $=w. You use limited_masquerade like this:
MASQUERADE_AS(`our.domain') FEATURE(`limited_masquerade') LOCAL_DOMAIN(`our.domain his.domain her.domain') MASQUERADE_DOMAIN(`our.domain his.domain')
Here, MASQUERADE_AS is declared first to define how
masqueraded domains should be rewritten. Then,
FEATURE(limited_masquerade) is
declared. The LOCAL_DOMAIN declares all three
domains to be recognized as local (that is, it adds
them to the class $=w, $=w
on page 876). Finally, MASQUERADE_DOMAIN (MASQUERADE_DOMAIN mc Macro
on page 600) adds only the hosts that you wish
masqueraded to the special class. Specifically, the
special class omits the
her.domain.
FEATURE(limited_masquerade) causes
sendmail to masquerade the
hosts in the special class defined by the
MASQUERADE_DOMAIN mc macro,
without the normal masquerading of the hosts in
$=w too. Note
that MASQUERADE_DOMAIN is also used to list the
domains for the FEATURE(masquerade_entire_domain).
Deliver locally with LMTP and mail.local V8.9 and later
The LMTP can be used to transfer mail from sendmail to the program that delivers mail to the local user. Historically, that has been a program, such as /bin/mail, that simply gathered a message on its standard input and wrote that message to the end of the file that the user read. Beginning with V8.9, sendmail can speak the special LMTP language to local delivery programs. The mail.local program, supplied in source form with the sendmail open source distribution, is one such program.
Operating systems that can use that program for local delivery are already set up correctly to use it. Those that are not already set up to use it can use this feature to override the settings in their OSTYPE (OSTYPE( ) m4 macro on page 590) defaults.
Building and using mail.local is
described in The mail.local Delivery Agent on page
359. Once it is built and installed, you can use
this FEATURE(local_lmtp) to enable use of
that program. One way to do that looks like
this:
FEATURE(`local_lmtp') MAILER(`local')
Note that this feature must be declared before you
define the local
delivery agent. This feature defines both the use of
mail.local and the place
where that program can be found. By default, that
location is
/usr/libexec/mail.local. If
you installed mail.local in a
different place or under a different name, you can
specify that location like this:
FEATURE(`local_lmtp', `/usr/sbin/mail.local') MAILER(`local')
This feature also sets the LOCAL_MAILER_FLAGS (Pre-V8.10 mc modification of F=
on page 744) to a default of F=PSXfmnz9, sets the
LOCAL_MAILER_ARGS (How to define A= with your mc
configuration on page 738) to a default of mail.local -l, and sets
the LOCAL_MAILER_DSN_DIAGNOSTIC_CODE (T= on page 754) to a default of
SMTP. If you need to change any of these, you can do
so with the proper mc macro.
Just be sure you make all your changes after
FEATURE(local_lmtp) was declared, and
before the local
delivery agent is declared:
FEATURE(`local_lmtp')
← define your new values here
MAILER(`local')Beginning with V8.13, sendmail allows you to add a third,
optional argument that supplies the command-line
arguments for the mail.local program (as well as for any
other programs that use LMTP, such as procmail). Essentially,
the third argument is supplied as the value to the
A= equate
(A= on page 738). For
example, the following supplies the −7 command-line switch
(don’t advertise 8-bit MIME support) for the
mail.local
program:
FEATURE(`local_lmtp', , `mail.local -l −7')
And the following enables procmail(1) to be used for LMTP delivery:
FEATURE(`local_lmtp', `/mail/bin/procmail', `procmail -Y -a $h -z')
Note that the second argument, if unused, must be present (but empty) if you wish to specify a third argument. Also note that you should manually append new command-line switches to the default switches, rather than replace them.
Also note that prior to V8.13, this FEATURE(local_lmtp) sets
the default LOCAL_MAILER_FLAGS to F=PSXfmnz9. Beginning
with V8.13, the F=f flag (F=f
on page 771) is no longer set as part of that
default. Recall that if sendmail is run with a -f command-line argument
(-f on page 241) and if the
F=f delivery
agent flag is specified, the A= for this local
delivery agent will have the two additional
arguments -f and
$g inserted
between its argv[0] and argv[1].
Don’t masquerade local mail V8.12 and later
Ordinarily, the MASQUERADE_AS mc configuration macro (MASQUERADE_AS mc Macro on page 600) causes header, envelope, sender, and recipient addresses to appear as though they were sent from the masquerade host. Sometimes it is desirable to perform masquerading only when mail is sent offsite, and not to masquerade when mail is sent from one user to another locally.
For just such situations, FEATURE(local_no_masquerade) is
available. You declare it like this:
FEATURE(`local_no_masquerade')
You must make this declaration before you declare the
local delivery
agent. If you mistakenly declare local first, like
this:
MAILER(`local') ← wrong, local must not be first
FEATURE(`local_no_masquerade')you will see the following error, and your configuration file will be incomplete:
*** MAILER(`local') must appear after FEATURE(`local_no_masquerade')
Use procmail(1), etc. as local delivery agent V8.7 and later
The procmail(1) program can
handle a user’s mail autonomously (for example,
sorting incoming mail into folders based on subject)
and can function as a sendmail
delivery agent. Some administrators prefer
procmail(1) in this latter
role over normal Unix delivery agents. If this is
your preference, you can easily use
procmail(1) in that role with
FEATURE(local_procmail):
FEATURE(`local_procmail')
FEATURE(local_procmail) changes the
P=, F=, and A= equates for the
local delivery
agent into:
P=/usr/local/bin/procmail ← see §20.5.11 on page 748 F=SPfhn9 ← see §20.5.6 on page 743 A=procmail -Y -a $h -d $u ← see §20.5.2 on page 738
If you have installed procmail in a different location, you can specify that alternative location with a second argument:
FEATURE(`local_procmail', `/admin/mail/bin/procmail')
Beginning with V8.10, sendmail
allows this FEATURE(local_procmail) to accept
additional arguments to define the A= values (set with
LOCAL_MAILER_ARGS; How to define A= with your mc
configuration on page 738) and the F= values (set with LOCAL_MAILER_FLAGS;
Pre-V8.10 mc modification of F=
on page 744). Those additional arguments were added
to support other programs in addition to
procmail(1), such as
maildrop(1) and
scanmails(1).[241] They are used like this:
FEATURE(`local_procmail', `/admin/mail/bin/procmail', `A= stuff here', `F= stuff here')
If you need to specify command-line arguments different from the defaults shown earlier, you can do so either with the second argument (the A= stuff here), or by using the LOCAL_MAILER_ARGS (How to define A= with your mc configuration on page 738) mc macro:
FEATURE(`local_procmail') define(`LOCAL_MAILER_ARGS', `procmail -Y -a hidden.domain -d $u')
If you need to use F= flags different from those shown,
you can do so either with the third argument (the
F= stuff here), or by using
the LOCAL_MAILER_FLAGS (Pre-V8.10 mc modification of F=
on page 744) mc macro:
FEATURE(`local_procmail') define(`LOCAL_MAILER_FLAGS', `SPfhn')
Both must follow FEATURE(local_procmail).
You can also use FEATURE(local_procmail) (FEATURE(local_procmail) on page 627) to include support for the other
programs. For example, the following line in your
mc can be used to change the
local delivery
agent to use the maildrop(8)
program:
FEATURE(`local_procmail', `/usr/local/bin/maildrop', `maildrop -d $u')
But before you do this, first create a
configuration file without this feature that looks
at the F=
delivery agent equate for the local delivery agent.
Then add the earlier line and create another
configuration file. Note any differences between
the F= delivery
agent equates from the two configuration files and
decide which are important to retain. If you
decide that there are more F= delivery agent flags
to retain than were created by FEATURE(local_procmail),
you can create a superset and add that superset
declaration to FEATURE(local_procmail) like
this:
FEATURE(`local_procmail', `/usr/local/bin/maildrop', `maildrop -d $u', `SPfhn9A')
The maildrop(8) program is intended for use only with Intel-based architectures, and is available with Debian GNU/Linux from http://packages.debian.org/stable/mail/maildrop.html.
Note that despite our description of
maildrop(1) in this section,
you can use this FEATURE(local_procmail) to install
other programs in the role of the local delivery
program. But test carefully before releasing any
new program in this role.
Enable .domain secondary access.db lookups V8.12 and later
Normally, lookups of hosts in the access database (The access Database on page 277) are literal. That is, host.domain is looked up first as host.domain and then as domain. For example, the host hostA.CS.Berkeley.edu would first be looked up as hostA.CS.Berkeley.edu, then as CS.Berkeley.edu, then as Berkeley.edu, and lastly as edu. None of the components is looked up with a leading dot. That is, host.domain’s second lookup is domain, not .domain.
If you wish each lookup to also include a lookup of
the domain part with a dot prefix, you can declare
this FEATURE(lookupdotdomain):
FEATURE(`lookupdotdomain')
Once declared, all lookups of hosts in the
access database will include
another lookup with the domain part prefixed with a
dot. That is, for example, without lookupdotdomain
declared, the lookups of
hostA.CS.Berkeley.edu will
look like this:
hostA.CS.Berkeley.edu CS.Berkeley.edu Berkeley.edu edu
But with lookupdotdomain declared, the lookups
of hostA.CS.Berkeley.edu will
look like this:
hostA.CS.Berkeley.edu .CS.Berkeley.edu CS.Berkeley.edu .Berkeley.edu Berkeley.edu .edu edu
This allows anything.cs.berkeley.edu to be treated differently from cs.berkeley.edu. For example:
.cs.berkeley.edu REJECT cs.berkeley.edu OK
Here, anything that ends in .cs.berkeley.edu will be rejected, whereas anything ending in cs.berkeley.edu will be accepted.
Note that this FEATURE(lookupdotdomain) requires that
the access.db be
declared first. If you reverse the declarations
(this feature first), you will get the following
warning and your resulting configuration file will
not be what you expect:
*** ERROR: FEATURE(`lookupdotdomain') requires FEATURE(`access_db')
Also note that this FEATURE(lookupdotdomain) should not be
used in conjunction with the FEATURE(relay_hosts_only) (FEATURE(relay_hosts_only) on page 273) because that feature disables
subdomain lookups. If you declare FEATURE(relay_hosts_only) first and
then declare this feature, the following warning
will be printed:
*** WARNING: FEATURE(`lookupdotdomain') does not work well with FEATURE(`relay_hosts_ only')
If you declare this feature first, then FEATURE(relay_hosts_only), no warning
will be printed.
Allow %-hack
relaying V8.9 and later
See FEATURE(loose_relay_check) on page 270 for a complete description of this feature and how it interacts with other relaying features.
Database selects new delivery agents V8.1 and later
A mailertable is a database that
maps host.domain names to
special delivery agent and new domain name pairs.
Essentially, it provides a database hook into the
parse rule set
0. Because mailertable follows handling of the
local host, none of the hosts in the $=w ($=w on page 876) will be
looked up with this feature.
New domain names that result from a mailertable lookup are
used for routing but are not reflected in the
headers of messages.
To illustrate, one mapping in a source text file could look like this:
compuserv.com smtp:compuserve.com
The key portion (on the left) must be either a fully qualified host and domain name, such as lady.bcx.com, or a partial domain specification with a leading dot, such as .bcx.com. On the right, the delivery agent name must be separated from the new domain name by a colon. The source text file is converted into a database with the makemap(1) program (The makemap Program on page 370). Beginning with V8.8 sendmail, the host part of the return value can also specify a user:
downhost.com smtp:postmaster@mailhub.our.domain
↑
V8.8 and laterThe host.domain is looked up in
the mailertable
database, and if that
host.domain is found, a
delivery agent, colon, and domain pair are returned.
If the delivery agent (in mailertable) is error, the #error delivery agent is
called. This allows error messages to be put into
the database, as, for example:
badhost error:nohost mail to badhost is prohibited ← V8.9 and earlier badhost error:5.7.0:550 mail to badhost is prohibited ← V8.10 and later
The first token following the error: is passed in the $@ part of the #error delivery agent.
Note that prior to V8.10, you had to use words or
<sysexits.h > codes
here, not DSN values (such as 5.7.0), because the
latter were wrongly broken up into five tokens.
Beginning with V8.10, you can also use DSN values
here, and they will be handled properly. See error on page 720 for a full
description of the #error delivery agent and for tables of
useful words and codes for the $@ part.
If the host is found and it is not an error delivery agent,
that delivery agent is selected. Otherwise, the
unresolved host.domain is
passed to other rule sets for further
mailertable lookups. Those
other rule sets recursively strip the leftmost part
of the host.domain away and
look up the result in the mailertable. This continues until
either a match is found or only a dot is left. Then
that dot is looked up to give you a hook for failed
lookups:
. smtp:smarthost
As a special case, the delivery agent named local causes slightly
different behavior in that it allows the name of the
target user to be listed without a host part:
virtual.domain local:bob
Here, any mail that is received for the virtual.domain is delivered to the user bob on the local machine. If the user part is missing:
virtual.domain local:
the mail is delivered to the user part of the original
address. This latter approach can be beneficial when
you have a huge number of hosts listed in $=w. Consider moving
those hosts to the mailertable database, and placing
local: on the
righthand side of each entry.[242]
The form for FEATURE(mailertable) is:
FEATURE(`mailertable')
This causes the following database declaration in the configuration file:
Kmailertable hash /etc/mail/mailertable
Here, the hash is
derived from the setting of the DATABASE_MAP_TYPE
mc configuration macro (Set a Default Database-Map Type for Features on page 897) and the /etc/mail is derived from the setting
of the MAIL_SETTINGS_DIR mc
macro (The MAIL_SETTINGS_DIR mc Macro on page 68). If you wish to change the defaults
without having to change these two
mc configuration macros, you
can simply define that new default by adding a
second argument to the feature declaration:
FEATURE(`mailertable',`dbm -o /etc/mail/mailertable')
Here, the database type was changed to dbm, and a -o database switch was
added to make the presence of the database
optional.
You can also provide an extra argument that is a literal LDAP:
FEATURE(`domaintable', `LDAP')
The default in this instance becomes the following (we have wrapped the lines to fit the page):
Kgenerics ldap −1 -v sendmailMTAMapValue -k (&(objectClass=sendmailMTAMapObject)
(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))
(sendmailMTAMapName=mailer)(sendmailMTAKey=%0))See ldap (was ldapx) on page 912 for a description of the ldap database type and
its −1, -v, and -k switches.
FEATURE(mailertable) was inspired by
the IDA version of
sendmail.
In The parse Rule Set 0 on page 696,
we deal with the flow of rules through the parse rule set 0. For
now, merely note that FEATURE(mailertable) fits into the flow
of rules through the parse rule set 0 like this:
Basic canonicalization (list syntax, delete local host, etc.)
LOCAL_RULE_0 (LOCAL_RULE_0 mc macro on page 596)
FEATURE(ldap_routing) (FEATURE(ldap_routing) on page 922)
FEATURE(virtusertable) (FEATURE(virtusertable) on page 645)
Addresses of the form “user@$=w” passed to local delivery agent
FEATURE(mailertable)
UUCP, BITNET_RELAY ($B on page 808), etc.
LOCAL_NET_CONFIG
SMART_HOST (SMART_HOST mc macro on page 597)
SMTP, local, etc. delivery agents
Masquerade all hosts under a domain V8.8 and later
Ordinarily, masquerading transforms any host from a
list of hosts in the class $=w ($=w
on page 876) into the host defined by MASQUERADE_AS.
If domains are also masqueraded with
MASQUERADE_DOMAIN, they too are transformed. For
example, consider these declarations:
MASQUERADE_AS(`our.domain') MASQUERADE_DOMAIN(`her.domain')
The first line causes any host part of an address
contained in the class $=w to be transformed into
our.domain. The second line
transforms the domain part of
her.domain into
our.domain.
The key point here is that the domain part her.domain will be transformed, whereas hosts under that domain will not be transformed:
george@her.domain becomes → george@our.domain george@host.her.domain remains → george@host.her.domain
If you wish MASQUERADE_DOMAIN to transform all the
hosts under the declared domain, you can use
FEATURE(masquerade_entire_domain):
MASQUERADE_AS(`our.domain') MASQUERADE_DOMAIN(`her.domain') FEATURE(`masquerade_entire_domain')
This feature extends masquerading of her.domain to include all the hosts under that domain:
george@her.domain becomes → george@our.domain george@host.her.domain becomes → george@host.her.domain george@host.sub.her.domain becomes → george@our.domain
Note that you can masquerade only domains that are
under your direct jurisdiction and
control. Also note that domain
masquerading is intended for actual domains. Virtual
domains are better handled with the FEATURE(genericstable)
(FEATURE(genericstable)
on page 622).
Masquerade the envelope as well as headers V8.7 and later
Ordinarily, masquerading (Masquerading on page 598) affects only the headers of email messages, but sometimes it is also desirable to masquerade the envelope.[243] For example, error messages are often returned to the envelope-sender address. When many hosts are masquerading as a single host, it is often desirable to have all error messages delivered to that central masquerade host.
FEATURE(masquerade_envelope) causes
masquerading to include envelope addresses:
MASQUERADE_AS(`our.domain') ← masquerade headers FEATURE(`masquerade_envelope') ← also masquerade the envelope
These mc lines cause all envelope
addresses (where the host part is declared as part
of class $=w;
$=w on page 876) to
be transformed into our.domain.
See MASQUERADE_DOMAIN for a way to also masquerade
other domains, and see FEATURE(masquerade_entire_domain) for a
way to also masquerade all the hosts under other
domains.
In general, masquerade_envelope is recommended for
uniform or small sites. Large or variegated sites
might prefer to tailor the envelope on a
subdomain-by-subdomain or host-by-host basis.
Experimental mtamark support V8.13 and later
FEATURE(mtamark)
provides experimental support for the mtamark IETF proposal.
This feature is described in FEATURE(mtamark)—V8.13 and Later,
Experimental
on page 295.
Create a mail submission cf file V8.12 and later
FEATURE(msp) is
used to create a submit.cf file
for use with a mail submission program, which is a
command-line sendmail that
functions as a mail submission agent (MSA).
In its simplest form, this feature is used like this:
FEATURE(`msp')
Here, a configuration file suitable for an MSA will be created. The resulting MSA will forward any message it gathers to the host localhost and will do so without looking up MX records for localhost. Unless told otherwise (as described later), the MSA will submit messages locally to port 25.
In the event that mail does not go to the local host, first check to see that the host named localhost is correctly defined on your machine:
% nslookup localhost
Server: your.name.server
Address: 123.45.67.89
Name: localhost
Address: 127.0.0.1If the address printed is not 127.0.0.1 for IPv4, or ::1 for IPv6, either
correct the problem with your own name server, or
contact your ISP and demand a correction. If that
fails, you can still send to the local host by
putting the correct address directly into the
msp declaration
as an argument:
FEATURE(`msp', `[127.0.0.1]')
Here, the square brackets tell sendmail that it is dealing with an address, rather than a hostname.
The argument can also be used to tell the MSA to connect to a host other than localhost:
FEATURE(`msp', `otherhost')
Here, submitted mail will be forwarded to the host otherhost for delivery, or for relaying outward. Unless you suppress it, the MSA will look up MX records for otherhost and, if found, will deliver to the MX records found. If that is inappropriate, you can suppress MX lookups by surrounding the hostname with square brackets:
FEATURE(`msp', `[otherhost]') ← suppress MX lookupsA second argument can be supplied to this feature which will cause the MSA to submit mail on port 587 instead of on port 25:
FEATURE(`msp', `[otherhost]', `MSA')
If the second argument is a literal MSA, the MSA will
connect to port 587. If it is anything else, no
change in port will be made.
The second argument can be present and the first absent if you wish to connect to port 587 on localhost:
FEATURE(`msp', `', `MSA')
If you wish to have all envelope and header addresses rewritten to appear as though they are from otherhost, you can combine the MASQUERADE_AS mc configuration macro with this feature:
MASQUERADE_AS(`otherhost') FEATURE(`msp', `[otherhost]', `MSA')
This feature is used to create the submit.cf file. See The submit.cf File on page 66 for a description of this process. Also see cf/SECURITY and cf/README in the source distribution.
Don’t canonify with $[ and $] V8.1 and later
Ordinarily, sendmail tries to
canonify (add a domain to) any hostname that lacks a
domain part, and to canonify (ensure a correctly
formed domain) for any host with a domain. It does
this by passing the unadorned hostname to the
$[ and $] operators (Canonicalize Hostname: $[ and $] on page 668). FEATURE(nocanonify) prevents
sendmail from passing
addresses to $[
and $] for
canonicalization. This is generally suitable for use
by sites that act only as mail gateways or that have
MUAs that do full canonicalization
themselves.
The form for FEATURE(nocanonify) is:
FEATURE(`nocanonify')
If you only want hostnames without a domain part canonicalized, you can add a second argument like this:
FEATURE(`nocanonify', `canonify_hosts')
Note that FEATURE(nocanonify) disables only one
possible use of $[ and $] in the configuration file. If the
pre-V8.9 FEATURE(nouucp) is omitted (thereby
including UUCP support), addresses that end in a
.UUCP suffix
still have the preceding part of the address
canonified with $[ and $] even if FEATURE(nocanonify) was
declared.
Also note that the Modifiers=C equate (DaemonPortOptions=Modify=
on page 996) for the DaemonPortOptions option does the same
thing as this FEATURE(nocanonify), but does so on a
port-by-port basis.
Sending out any unqualified addresses can pose a risk. To illustrate, consider a header where the local host is here.us.edu:
To: hans@here.us.edu Cc: jane@here, george@fbi.us.gov From: you@here.us.edu
The assumption here is that this will go to the local
hub machine for delivery, and that the hub will view
jane as a local
user and perform local delivery.
But consider a hub that has two MX records (a rather
small number). One points to itself so that it
always gets mail first. The other points to a host
at another host, off campus. If the hub is down but
its clients are up, mail will be delivered to the
other campus machine on the assumption that it will
hold the mail until the hub returns to service. The
problem is that the address jane@here is unqualified (incomplete)
when it gets to the other campus machine, and will
bounce because a host in
jane@here is unknown.
Beginning with V8.10 sendmail, you can list domains that you want canonified, even though you have enabled this feature. You add those domains to a special sendmail class using either of two new macros:
CANONIFY_DOMAIN(`list of domains') CANONIFY_DOMAIN_FILE(`/path')
The first form causes the list of domains to be added
to your configuration file using the C configuration command.
The second causes the file indicated by
/path to be read (using
the F
configuration command) for a list of domains. For
example, to require that the local domain be always
canonified you can use a declaration such as
this:
CANONIFY_DOMAIN(`$=m')
Subdomains (such as sub.your.domain) will be matched when you list just the domain (your.domain). Therefore, it is only necessary to list top-level domains to have a domain and its subdomains canonicalized.
Omit DNS support from configuration file V8.6 through V8.8, removed V8.13
This feature was still offered through V8.12, but as of V8.9 it did nothing. Instead, beginning with V8.7 sendmail, you should either use the service-switch file (ServiceSwitchFile on page 1088) to control use of DNS or compile a sendmail without DNS support (NAMED_BIND on page 124). This feature was removed as of V8.13.
Disable automatic listening on MSA port 587 V8.10 and later
When V8.10 sendmail starts up in daemon mode, it listens both on the normal port 25 for incoming SMTP connections, and on port 587 for the local submission of mail. This later role is that of an MSA (documented in RFC2476).
Although listening on another port by default might seem like a bad idea, it is actually a very good way to enable a smooth transition to the adoption of MSA services. The MTA, for example, when listening on port 587 will limit the amount of automatic canonicalization it does on unqualified addresses. This is good because that canonicalization is really the role of an MSA connecting to that port.
Although we highly recommend that you leave this
service enabled, you might prefer to disable it. If
so, you can disable it with this FEATURE(no_default_msa):
FEATURE(`no_default_msa')
Additional information about MSAs can be found in our
discussion of the DaemonPortOptions option (DaemonPortOptions on page 993).
Because there is no way to directly change the
settings of the MSA in your mc
configuration file, you can use the following trick
if you need to change, say, the M= equate from M=E to M=Ea:
FEATURE(`no_default_msa') DAEMON_OPTIONS(`Port=587,Name=MSA,M=Ea')
Here, this feature prevents the automatic creation of an mc configuration entry for an MSA. You then insert your own declaration, with your new settings.
Be aware, however, that this feature also disables the listening daemon on port 25. If you use this feature, be certain to redeclare a port 25 daemon if you need one:
FEATURE(`no_default_msa') DAEMON_OPTIONS(`Port=587,Name=MSA,M=Ea') DAEMON_OPTIONS(`Port=smtp, Name=MTA')
Don’t differ user from user@local.host V8.1 through V8.6
Mail addressed to a local user that includes the name
of the local host as part of the address (i.e.,
user@local.host) is delivered
locally. From V8.1 to V8.6
sendmail, if the address has
a host part, lookups in the User Database (userdb on page 942) and the
additional processing of the localaddr rule set 5
(The localaddr Rule Set 5 on
page 700) are skipped. Under V8.6, addresses with
just the user part are always
processed by the User Database and the localaddr rule set
5.
The V8.6 FEATURE(notsticky) changes this logic.
If this feature is chosen, all users are looked up
in the User Database, and the additional processing
done by the localaddr rule set 5 is skipped.
Beginning with V8.7, the default is as though notsticky were used, and
thus the FEATURE(stickyhost) can be used to
restore the previous default.
Eliminate all UUCP support V8.1 and later
If your site wants nothing to do with UUCP addresses,
you can set FEATURE(nouucp). Among the changes this
causes are that the ! character is not recognized as a
separator between hostnames, and all the macros that
relate to UUCP (UUCP Support on
page 606) are ignored. This feature truly means
no UUCP.
You declare nouucp
like this:
FEATURE(`nouucp') ← through V8.9 FEATURE(`nouucp',`nospecial') ← V8.10 and later FEATURE(`nouucp',`reject') ← V8.10 and later
Beginning with V8.10, an argument has been added that
can be either nospecial or reject. The nospecial causes
sendmail to simply ignore the
! character.
The reject causes
sendmail to reject mail with
the ! character.
If you declare neither argument (as in the first
line), and you are using
sendmail V8.10 or above, you
will see the following error, and your configuration
file will fail to build properly:
*** ERROR: missing argument for FEATURE(nouucp):
use `reject' or `nospecial'. See cf/README.Note that all the other UUCP declarations (such as
UUCP_RELAY) will be ignored if you use this nouucp.
When you use this feature on any machine that forwards
uucp mail to a
central mail hub machine, be certain that you also
declare it on that mail hub machine. If you don’t
take this precaution, you open up your mail hub to
risk of unintended relaying.
Relay all mail through a mail host V8.6 and later
Some sites have a number of workstations that never receive mail directly. They are usually clustered around a single mail server. Normally, all clients in a cluster like this send their mail as though the mail is from the server, and they relay all mail through that server rather than sending directly. If you have such a configuration, use a declaration such as the following:
FEATURE(`nullclient', `host.domain')
Note that the host.domain must be the fully qualified
domain name of your mail server or relay to the
outside world.
If you wish to prevent the
nullclient version of
sendmail from trying to
access aliases, add this line
to your .mc
file:
undefine(`ALIAS_FILE')
Note that this works only with V8.8 and later
.mc
files.
Allow unbridled relaying V8.9 and later
The relaying of outside mail through your site to
another outside site is turned off by default. But
if you want to allow this old and dangerous
behavior, declare this FEATURE(promiscuous_relay). This
feature, how it is used, and how it fits into
relaying and spam handling in general are explained
in FEATURE(promiscuous_relay) on page 271.
Retain plussed addresses for delivery V8.12 and later
Beginning with V8.7, sendmail offered plus addressing (Plussed Detail Addressing on page 476) in its aliases file as a means to handle special aliasing needs. Usually, the plus part is stripped from the user part of the address before final delivery. That is, mail to bob+nospam would be delivered to bob.
As new delivery programs are developed, it might become desirable to pass the unstripped address to such programs. Such a delivery program would see bob+nospam as part of its command line.
If yours is such a delivery program, you can enable this latter behavior by defining this feature:
FEATURE(`preserve_local_plus_detail')
Note that this feature should not be enabled unless you are absolutely sure your delivery program will do the correct thing. If you wrongly enable this feature, mail delivery will fail.
Preserve recipient host with LUSER_RELAY V8.12 and later
Normally the LUSER_RELAY mc
configuration macro (LUSER_RELAY mc Macro on
page 605) causes the domain part of recipient
addresses to be replaced with the value given to the
LUSER_RELAY macro. If this behavior is undesirable,
you can define this FEATURE(preserve_luser_host) to correct
it:
FEATURE(`preserve_luser_host')
With this feature defined, the recipient hostname is
preserved. But note that it is preserved only for
delivery agents that take a hostname. The default
local delivery
agent does not.
Select queue groups via the access database V8.12 and later
As of V8.12, you can manage queues via queue groups. This feature allows you to select queue groups by using entries in the access database. See The FEATURE(queuegroup) and the access Database on page 416 for a full description of queue groups and this feature.
Limit the rate at which other MTAs may connect to yours V8.13 and later
This FEATURE(ratecontrol) allows you to use
the access
database to control the rate at which other machines
can connect to your server.[244] The rate is based on the setting of the
ConnectionRateWindowSize option (ConnectionRateWindowSize on page 989),
which defaults to 60 seconds. So, for example, it
you want to reject more than 10 connections per
minute (60 seconds) from the IP address 192.168.23.45, you would
put the following into your access database source
file:
ClientRate:192.168.23.45 10
Here, if the host with the IP address 192.168.23.45 connects
to your server more than 10 times in a given 60
seconds (the default window of time), the 11th and
subsequent connections during that interval will be
rejected.
You enable the FEATURE(ratecontrol) like this:
FEATURE(`ratecontrol')
But note, if you have not already declared the access database (The access Database on page 277), you must do so before declaring this new feature, or you will get the following error when building your new configuration file:
*** ERROR: FEATURE(ratecontrol) requires FEATURE(access_db)
Once you have successfully enabled this FEATURE(ratecontrol),
you may use it to control the connection rate by the
IP addresses of hosts or networks, or to set the
default limit:
ClientRate:192.168.23.45 2 ClientRate:127.0.0.1 0 ClientRate: 10 ClientRate:10.5.2 2 ClientRate:IPv6:2002:c0a8:51d2::23f4 5
Here, the first line (as you have seen) limits the
number of connections from the IP address 192.168.25.45 to no more
than two connections per minute (where the ConnectionRateWindowSize
option, ConnectionRateWindowSize
on page 989, is set to 60 seconds or one
minute).
In the second line, which specifies a zero limit, the
zero means there is no limit imposed on the number
of simultaneous connections allowed. A zero limit is
suitable for the loopback interface address
(127.0.0.1)
because that is the interface over which the local
submission version of sendmail delivers its
mail.
The third line omits the IP address entirely, thereby setting a default limit for all other IP (unspecified) addresses. Without this default setting, any unspecified address would be unlimited.
The fourth line shows how network addresses may also be limited.
The last line shows that IPv6 addresses can be
specified merely by prefixing each with a literal
IPv6:.
Note that the rates we show here are just examples, not recommendations. The rates you choose as limits will depend on your particular circumstances.
If you also declare FEATURE(delay_checks) (Accept and Reject per Recipient on
page 284), rate control checks will be delayed
until after the first envelope recipient has been
received. Clearly this makes this rate-control
check less useful than it should be. If you use
delay_checks,
you may add an additional argument to this
FEATURE(ratecontrol) to get it to run
as early as possible despite the use of that
delaying feature:
FEATURE(`ratecontrol', `nodelay')
Here, the nodelay is literal and prevents
FEATURE(delay_checks) from having any
effect on connection-rate controls. Note that if
you declare both FEATURE(delay_checks) and FEATURE(ratecontrol),
FEATURE(delay_checks) must appear first
in your mc
file.
Normally, FEATURE(ratecontrol) rejects
connections with a temporary error:
452 Connection rate limit exceeded
If the connecting client terminates the
connection by sending an SMTP QUIT, rate control
terminates as you would expect. But if the client
chooses to ignore that return value, the client
will be given 4yz SMTP (temporary failure) replies
to all commands it sends until it sends an SMTP
QUIT command. Clearly this may not be acceptable
at your site. If you want the excess connection
rates terminated without regard to the connecting
client’s other behavior, you may do so by adding a
second argument to this FEATURE(ratecontrol):
FEATURE(`ratecontrol', `nodelay', `terminate') FEATURE(`ratecontrol', , `terminate')
Here, the terminate is literal and, when present, causes all rejected connections to be rejected with a 421 SMTP return code. Note that 421 is special, because it allows sendmail to terminate the connection without waiting for the client to send a QUIT. Note that if you omit the nodelay first argument, you need to use two commas (as in the second example shown earlier) to make terminate the second argument.
Reject connections based on rbl.maps.vix.com V8.9 through V8.11
FEATURE(rbl) was
introduced in V8.10 as an aid to blocking spam
email. But because it directly looked up hosts at
rbl.maps.vix.com, it was soon
rendered obsolete. V8.11
sendmail replaced FEATURE(rbl) with
FEATURE(dnsbl)
(FEATURE(dnsbl) on page 261), which allows you to specify the
host to use for lookups. V8.12
sendmail extended that
ability further with FEATURE(enhdnsbl) (FEATURE(enhdnsbl) on page 263), which also allows you to customize
error messages and determine what to do with
temporary failures.
Add support for address.REDIRECT aliases V8.1 and later
FEATURE(redirect)
allows aliases to be set up for retired accounts.
Those aliases bounce with an indication of the new
forwarding address. A couple of lines from such an
aliases(5) file might look
like this:
george: george@new.site.edu.REDIRECT william: wc@creative.net.REDIRECT
FEATURE(redirect)
causes mail addressed to george, for example, to be bounced with
a message such as this:
551 5.7.1 User not local; please try <george@new.site.edu>
Note that the message is bounced and not forwarded. No notification is sent to the recipient’s new address.
The form of FEATURE(redirect) is:
FEATURE(`redirect')
The actual bounce is caused by calling the error delivery agent
with an RHS such as this:
$#error $@ 5.1.1 $: "551 User not local; please try " <$1@$2>
The 5.1.1 is a DSN
error code (see RFC1893), and the 551 is an SMTP code (see
RFC821).
If your site’s policy is to notify and forward, you can use an entry such as this in your aliases database:
george: george@new.site.edu.REDIRECT, george@new.site.edu
Here, the sender will receiver notification of the new address, and the recipient will receive the original messages.
A problem can arise when spam messages are sent to a
REDIRECT address. Because some spam is sent with a
fictitious envelope sender, the bounce caused by the
REDIRECT will itself bounce too. This creates what
is called a double bounce (a bounce notification
that bounces). Double bounces are delivered to the
address defined by the DoubleBounceAddress option (DoubleBounceAddress on page 1025). If
spam bounces of REDIRECT addresses start to annoy
you, consider redefining the DoubleBounceAddress
option to deliver double bounce notification to a
less offensive address, such as an address aliased
to /dev/null. But be aware that
this will cause all double bounces to be sent to
that address, not just spam double bounces.
Relay based on MX records V8.9 and later
Ordinarily, the decision to relay is not based on MX records. Relaying based on MX records poses a risk that outsiders might use your server as a relay for their site (that is, they might set up an MX record pointing to your mail server, and you will relay mail addressed to them without any prior arrangement).
This FEATURE(relay_based_on_MX) reverses
that policy. This feature, how it is used, and how
it fits into relaying and spam handling are
explained in FEATURE(relay_based_on_MX) on page 271.
Relay based on $=m V8.9 and later
Ordinarily, only hosts listed with RELAY_DOMAIN (The RELAY_DOMAIN mc macro
on page 269) are allowed to relay through the local
machine. This FEATURE(relay_entire_domain) allows
domains listed in the $=m class to also be relayed, including
any hosts that end in any of the domains listed in
the $=m class.
This feature, how it is used, and how it fits into
relaying and spam handling are explained in FEATURE(relay_entire_domain) on page 272.
Relay individual hosts, not domains V8.9 and later
Ordinarily, the names listed with RELAY_DOMAIN (those
allowed to relay through the local machine, The RELAY_DOMAIN mc macro
on page 269) are names of domains. By declaring this
FEATURE(relay_hosts_only), you cause
the names in that list to be interpreted as the
names of hosts, not domains. This feature, how it is
used, and how it fits into relaying and spam
handling are explained in FEATURE(relay_hosts_only) on page 273.
Relay based on MAIL From: V8.9 and later
Ordinarily, permission to relay is not based on the
SMTP MAIL From:
command. This feature changes that behavior. How it
is used and how it fits into relaying and spam
handling are explained in FEATURE(relay_local_from) on page 273.
Relay based on MAIL From: and on RELAY in access_db V8.10 and later
By declaring this FEATURE(relay_mail_from), you enable
relaying for envelope sender addresses based on the
RELAY value in the access database. This feature,
how it is used, and how it fits into relaying and
spam handling are explained in FEATURE(relay_mail_from) on page 274.
Reject unresolvable IP addresses V8.14 and later
This FEATURE(require_rdns) rejects clients
whose IP address cannot be properly resolved with a
reverse lookup. This feature is described inFEATURE(require_rdns)—V8.14 and Later on page 296.
Use smrsh (sendmail restricted shell) V8.7 and later
Although sendmail tries to be very safe about how it runs programs from the aliases(5) and ~/.forward files (Delivery Via Programs on page 468), it still can be vulnerable to some internal attacks. To limit the selection of programs that sendmail is allowed to run, V8 sendmail includes source and documentation for the smrsh (sendmail restricted shell) program. See The smrsh Program on page 379 for a full description of the smrsh program.
Differ user from user@local.host V8.7 and later
Beginning with V8.7 sendmail,
addresses with and without a host part that resolve
to local delivery are handled in the same way. For
example, user and
user@local.host are both
looked up with the User Database (userdb on page 942) and processed
by the localaddr
rule set 5 (The localaddr Rule Set 5 on page 700). This processing can result in those
addresses being forwarded to other machines.
With FEATURE(stickyhost), you can change
this behavior:
FEATURE(`stickyhost')
By defining stickyhost, you are telling
sendmail to mark addresses
that have a local host part as “sticky”:
user ← not sticky user@local.host ← sticky
Sticky hosts tend to be delivered on the local
machine. That is, they are not looked up with the
User Database and are not processed by the localaddr rule set
5.
One use for this feature is to create a domain-wide namespace. In it, all addresses without a host part will be forwarded to a central mail server. Those with a local host part will remain on the local machine and be delivered in the usual local way.
Note that this is opposite the behavior of the former
FEATURE(notsticky) of V8.6.
Replace IP address with ${client_ptr} in check_relay V8.13 and later
This FEATURE(use_client_ptr) causes the
check_relay
rule set to use the value of ${client_ptr} in place
of the client’s IP address. This feature is fully
described in FEATURE(use_client_ptr)—V8.13 and Later on page 297.
Use /etc/mail/trusted-users for a list of trusted users V8.7 and later
V6 sendmail removed the concept
of trusted users (Security Features on page 173). V8.7 reintroduced trusted users,
but in a form different from that used by V5
sendmail. Now, trusted users
are those who can rebuild the
aliases database, and who can
run sendmail with the -f switch (-f on page 241) without generating
an authentication warning (X-Authentication-Warning: on page
1167):
X-Authentication-Warning: host: user set sender to other using -f
To prevent this warning, the
user should be added to
a list of trusted users. Simply use this FEATURE(use_ct_file) and
add user to the file
/etc/mail/trusted-users
(V8.10 and later) or
/etc/mail/sendmail.ct (V8.9
and earlier). You declare FEATURE(use_ct_file) like this:
FEATURE(`use_ct_file')
If you want to locate the /etc/mail/trusted-users in a different place or give it a different name, you can do so with this declaration:
define(`confCT_FILE', `/etc/mail/trusted.list')
Note that the file must exist before sendmail is started, or it will complain:
fileclass: cannot open /etc/mail/trusted.list: No such file or directory
If you want the file to optionally exist, you can add
a -o (The F Class Command on page 857) to
the conf-CT_FILE
definition:
define(`confCT_FILE', `-o /etc/mail/trusted_users')
Here, we retain the file’s default name and location,
but add the -o to
make the file’s presence optional.
You can also add trusted users directly in your mc configuration file like this:
define(`confTRUSTED_USERS',`root bob')
Here, two users are added to the list of trusted
users, root and
bob.
See also Declare trusted users (ignored V8.1 through V8.6) on page 174 for a discussion of trusted users in general.
Use /etc/mail/local-host-names V8.1 and later
FEATURE(use_cw_file) causes the file
/etc/mail/local-host-names
(V8.10 and later) or
/etc/sendmail.cw (V8.9 and
earlier) to be read to obtain alternative names for
the local host. One use for such a file might be to
declare a list of hosts for which the local host is
acting as the MX recipient. The use_cw_file is used like
this:
FEATURE(`use_cw_file')
This feature causes the following F configuration command
(The F Class Command on page
857) to appear in the configuration file:
Fw/etc/sendmail.cw ← V8.9 and earlier Fw/etc/mail/local-host-names ← V8.10 and later
The actual filename can be changed from the default by
defining the confCW_FILE macro:
define(`confCW_FILE', `-o /etc/mail/local.list')
Here, we both rename the file and make its presence
optional by adding the -o switch (The F Class Command on page
857).
If the local host is known by only a few names, an alternative is to instead include the mc macro in place of the earlier feature:
LOCAL_DOMAIN(`name1 name2')Here, name1 and
name2 are alternative
names for the local host.
Convert UUCP hosts via a database Deprecated
This has been deprecated as of V8.10. If you currently
use this feature, you should convert to FEATURE(domaintable)
(FEATURE(domaintable) on page 621) soon.
FEATURE(uucpdomain)
was similar to bitdomain (FEATURE(bitdomain) on page 617) but was used to translate addresses
of the form:
user@host.UUCP
into a DNS domain format, such as host.domain.com. The database for this would contain, for example, key and data pairs such as these:
host host.domain.com
This source text file was converted into a database with the makemap(1) program (The makemap Program on page 370).
The way you declare uucpdomain is like this:
FEATURE(`uucpdomain')
This causes rules to be added so that a host with a
.UUCP suffix will be looked up in the database
uudomain.
FEATURE(uucpdomain) also creates the
declaration for that database:
Kuudomain hash /etc/mail/uudomain
If you wish to use a different form of database or a different location for the database file, you can do so by adding an argument to the feature declaration:
FEATURE(`uucpdomain', `dbm -o /etc/mail/uudomain')
Here, we tell sendmail that we
will be using the NDBM form of database instead of
the original NEWDB form (Enable at Compile Time on page 879).
We also add a -o
to make the presence of the file optional.
If you provide a second argument that is a literal LDAP:
FEATURE(`uucpdomain', `LDAP')
the default becomes the following (we have wrapped the lines to fit the page):
Kauthinfo ldap −1 -v sendmailMTAMapValue -k (&(objectClass=sendmailMTAMapObject)
(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))
(sendmailMTAMapName=uucpdomain)(sendmailMTAKey=%0))See ldap (was ldapx) on page 912 for a description of the ldap database type and
its −1, -v, and -k switches.
Match subdomains in the virtual user table V8.10 and later
Ordinarily, domains listed in the $=w class or the
$={VirtHost}
class are looked up in the virtual user table as is,
meaning that only host-for-host or domain-for-domain
matches are made. This FEATURE(virtuser_entire_domain) changes
that behavior and allows subdomains to also be
looked up.
Consider, for example, that the domain wanted.com is listed with the VIRTUSER_DOMAIN mc configuration macro (VIRTUSER_DOMAIN mc macro on page 647) and the following lines are listed in the virtual host table:
info@wanted.com hans@remote.host info@sales.wanted.com hans@remote.host
Here, mail sent to
info@sales.wanted.com would
ordinarily not be looked up. But by declaring this
FEATURE(virtuser_entire_domain), all
hosts in the subdomain
wanted.com would will be
looked up, so the address
info@sales.wanted.com would now
find a match.
Support for virtual domains V8.8 and later
A virtusertable is
a database that maps virtual (possibly nonexistent)
domains into new addresses. Essentially, it gives
you a database hook into the early part of the
parse rule set
0. Note that this only reroutes delivery. It does
not change mail headers.
By way of example, consider one mapping in a source text file:
info@stuff.for.sale.com bob info@stuff.wanted.com hans@remote.host info@auction.com hans@remote.host @fictional.com user@another.host
The key portion (on the left) must be either a full address (user, host, and domain name), as in the first two lines, or an address without a host part (just a domain), as in the third line, or an address with the user part missing, as in the last line. This source text file is converted into a database with the makemap(1) program (The makemap Program on page 370).
The first three lines illustrate a full address for the key. The first line will be delivered to a local user (bob), the second and third to a remote user (hans@remote.host). The fourth line shows how all mail to a virtual domain (fictional.com) can be delivered to a single address, regardless of the user part.
Note that sendmail does multiple lookups, so one line can reference another. The following, for example, will work:
info@stuff.for.sale.com forsale@fictional.com @fictional.com user@another.host
Here, mail to info@stuff.for.sale.com will be delivered to user@another.host.
Also note that virtual hosts, just like real hosts,
need to belong to class $=w ($=w
on page 876) for them to be recognized as local.
Also note that beginning with V8.10, virtual hosts
can also be listed in your mc
file, or in an external file, by using the
VIRTUSER_DOMAIN mc
configuration macro (VIRTUSER_DOMAIN mc macro on
page 647) or the VIRTUSER_DOMAIN_FILE
mc configuration macro (VIRTUSER_DOMAIN_FILE mc macro
on page 647). Hosts listed with these macros will be
looked up in the virtusertable but will not be
considered local.
If the value (the righthand side in virtusertable) is
error:, the
#error delivery
agent is called. This allows error messages to be
put into the database, as, for example:
info@for.sale.com error:nouser We no longer sell things here ← V8.9 and earlier info@for.sale.com error:5.7.0:550 We no longer sell things here ← V8.10 and later
The text following the error: is passed to the #error delivery agent.
The first token following the error: is passed in the
$@ part. Note
that prior to V8.10, you had to use words or
<sysexits.h > codes
here, not DSN values (such as 5.7.0), because the
latter were wrongly broken up into five tokens.
Beginning with V8.10, you can also use DSN values
here, and they will be handled properly. See error on page 720 for a full
description of the #error delivery agent and for tables of
useful words for the $@ part.
You declare the virtusertable like this in your
mc file:
FEATURE(`virtusertable')
This causes the following database declaration to appear in the configuration file:
Kvirtusertable hash /etc/mail/virtusertable
If you wish to use a different form of database (such
as dbm) or a different
location, FEATURE(virtusertable) accepts an
argument:
FEATURE(`virtusertable',`dbm -o /etc/mail/virt_user_table')
If you provide a second argument for FEATURE(virtusertable)
that is a literal LDAP:
FEATURE(`virtusertable', `LDAP')
the default becomes the following (we have wrapped the lines to fit the page):
Kauthinfo ldap −1 -v sendmailMTAMapValue -k (&(objectClass=sendmailMTAMapObject)
(|(sendmailMTACluster=${sendmailMTACluster})(sendmailMTAHost=$j))
(sendmailMTAMapName=virtuser)(sendmailMTAKey=%0))See ldap (was ldapx) on page 912 for a description of the ldap database type and
its −1, -v, and -k switches.
In The parse Rule Set 0 on page 696,
we deal with the flow of rules through the parse rule set 0. For
now, merely note that FEATURE(virtusertable) fits into the
flow of rules through the parse rule set 0 like this:
Basic canonicalization (list syntax, delete local host, etc.)
LOCAL_RULE_0 (LOCAL_RULE_0 mc macro on page 596)
FEATURE(ldap_routing) (FEATURE(ldap_routing) on page 922)
FEATURE(virtusertable)
Addresses of the form “user@$=w” passed to local delivery agent
FEATURE(mailertable) (FEATURE(mailertable) on page 629)
UUCP, BITNET_RELAY ($B on page 808), etc.
LOCAL_NET_CONFIG (LOCAL_NET_CONFIG mc macro on page 598)
SMART_HOST (SMART_HOST mc macro on page 597)
SMTP, local, etc. delivery agents
Beginning with V8.10
sendmail, a new macro was
introduced to make it easier to add domains for
use with FEATURE(virtusertable). Called
VIRTUSER_DOMAIN, it is used like this:
VIRTUSER_DOMAIN(`domain1 domain2 etc')
Each domain that you intend to list should be listed individually, each separated from the others by spaces. Multiple VIRTUSER_DOMAIN lists can be declared in your mc file like this:
VIRTUSER_DOMAIN(`domain1') VIRTUSER_DOMAIN(`domain2') VIRTUSER_DOMAIN(`etc')
If you are currently declaring virtual user
domains in the $=w class, you are encouraged to
convert to this new macro. Use of it will insulate
you from change in the future. Note that hosts in
$=w for
masquerading should not be moved, but should,
instead, be copied.
Beginning with V8.10
sendmail, a new macro was
introduced to make it easier to list domains for
use with FEATURE(virtusertable). Called
VIRTUSER_DOMAIN_FILE, it is used like
this:
VIRTUSER_DOMAIN_FILE(`/etc/mail/virtuserdomains')
This declaration causes domains to be read
from the file
/etc/mail/virtuserdomain.
Because VIRTUSER_DOMAIN_FILE is implemented with
an F
configuration command (The F Class Command on page 857), you
can add whatever F command arguments you desire. For
example:
VIRTUSER_DOMAIN_FILE(`-o /etc/mail/virtuserdomains')
Here, the -o switch makes the presence of the
/etc/mail/virtuserdomains
file optional.
If you are currently storing virtual domains
in the $=w
class, you are encouraged to convert to this new
VIRTUSER_DOMAIN_FILE macro. Use of it will
insulate you from change in the future. Note that
hosts in $=w
for masquerading should instead be copied.
[235] * This is not the same Build script that is documented in The Build Script on page 346. It is a small shell script that works only in the cf/cf directory and can be used only to build configuration files. You can use make in its place, but make will not automatically find the correct version of m4 for you.
[236] † This is actually
a good idea. It prevents new
sendmail distributions from
clobbering your .mc files.
[237] * We fudge for simplicity. Actually, OSTYPE can legally be preceded by VERSION (VERSIONID m4 macro on page 593) and m4 comments.
[238] * Although it can and probably should be followed by rule set declarations, as for example, LOCAL_RULESET_0.
[239] * Actually, there
are only four; uucp and uucp-old are synonyms for the same
agents, as are suucp and uucp-new.
[240] * This feature
limits per connecting host, whereas the FEATURE(ratecontrol)
(FEATURE(ratecontrol) on page 638) limits all simultaneous
connections.
[241] * See cf/README for examples of how to use this feature with maildrop(1) and scanmails(1).
[242] * Note that
moving the host from $=w into the mailertable database can adversely
affect masquerading and relay control.
[243] * See The Envelope on page 9 for a description of the envelope and how it differs from headers.
[244] * This feature
limits the aggregate of all connections, whereas
FEATURE(conncontrol) (FEATURE(conncontrol) on page 619) limits connections per MTA.