Contents:
The S Configuration Command
Rule Sets and m4
The Sequence of Rule Sets
Rule Set 3
Rule Set 4
Rule Set 0
Rule Set 5
Rule Set 2
Rule Set 1
The check_... Rule Sets
Pitfalls
Rule sets in the configuration file, like subroutines in a program, control the sequence of steps sendmail uses to rewrite addresses. Inside each rule set is a series of zero or more individual rules. Rules are used to select the appropriate delivery agent for any particular address, to detect and reject addressing errors, and to transform addresses to meet particular needs.
In this chapter we will cover all aspects of rule sets, showing that rule sets are called in particular orders and explaining why this is so.
We will explain many of the rules that typically appear in rule sets. But be forewarned: The examples of rules in this chapter are explanatory only. Your sendmail.cf file is likely to have rules that are somewhat different from these examples. Copying or using these examples, without first understanding the underlying principles, can cause email to begin to fail.
The
S
configuration command declares the start of a rule set. It is perhaps the simplest of all configuration commands and looks like this:
Sident
The
S
, like all configuration commands, must begin the line. The
ident
identifies the rule set. There may be whitespace between the
S
and the
ident
. If the
ident
is missing,
sendmail
prints the following error message and skips that particular rule set declaration:
/etc/sendmail.cf: linenum
: invalid ruleset name: ""
Prior to V8.7
sendmail
the
ident
could only be numeric. Beginning with V8.7
sendmail
the
ident
may be numeric or alphanumeric. We cover the old form first, then the new.
Prior to V8.7 sendmail , rule sets could be identified only by numbers. When a rule set is declared with an integer, that integer is taken to be the numeric identity of the rule set:
S#
Here,
#
is an integer such as 23. If the
#
is greater than half [1] the maximum number of rule sets allowed (MAXRWSETS in
conf.h
) or is negative,
sendmail
syslog
(3)'s the following error message at the level LOG_CRIT and defaults the rule set to 0:
[1] The reason for this will become clear shortly.
bad ruleset#
(n
max)
Here, the
#
is the bad rule-set number from the configuration file, and
n
is the maximum allowable rule-set number (the value of MAXRWSETS/2). By default, the maximum value for
#
is 99.
Beginning with V8.7 sendmail , rule sets may be declared with numbers (as above) or with more meaningful names. The form for a rule-set name declaration looks like this:
Sname
The name may contain only ASCII alphanumeric characters and the underscore character. Any bad character causes that character and the characters following it to be silently ignored:
My_rule good My rule bad, name is ``My''
Case is recognized; that is,
Myrule
and
MYRULE
are different names. You may use any name that begins with an uppercase letter. Names that begin with a lowercase letter or an underscore character are reserved for internal use by
sendmail
.
There may be at most MAXRWSETS/2 named rule sets (where MAXRWSETS is defined in conf.h ). Each rule set that is declared beyond that amount causes sendmail to print the following error and ignore that rule-set declaration:
name
: too many named rulesets (#
max)
When you declare a rule set name, sendmail associates a number with it. That number is selected by counting down from MAXRWSETS. That is, the first name is given the number MAXRWSETS-1, the second is given the number MAXRWSETS-2, and so on. Named rule sets may be used anywhere that numbered rule sets can be used.
When knowing the number associated with a named rule set is of importance, you can associate a number with a name when the name is declared. The form of such a combined declaration looks like this:
Sname
=num
Here, the rule set named
name
is declared. Instead of
sendmail
associating a number with it, you create the association by following the
name
with an
=
character and then an integer
num
. Arbitrary whitespace may surround the
=
character. If the integer is missing or non-numeric,
sendmail
prints the following error and skips that rule-set declaration:
/etc/sendmail.cf: linenum
: bad ruleset definition "bad
" (number required after `=')
Although it is ugly, different names may share the same number:
Sfoo=1 Sfee=1
However, the same name may not be given a different number. Consider the following example:
SMyrule=1 SMyrule=2
This causes sendmail to print the following error and skip the second declaration:
/etc/sendmail.cf: linenum
: Myrule: ruleset changed value (old 1, new 2)
Named rule sets have numbers associated with them when they first appear. If you use a named rule set in an
S=
equate for a delivery agent and then later attempt to assign it a value, you will get an error like the above:
Mprog, P=sh, ...., S=Myrule
, ... ... SMyrule
=2
The solution is either to move the rule-set declaration (and its rules) so that they reside above the delivery agent declaration or to declare a numeric association in the delivery agent declaration instead of in the rule-set declaration:
Mprog, P=sh, ...., S=Myrule=2
, ... ... SMyrule
or to place just the
S
line above the delivery agent declaration and the rules, without the
=2
, below it:
SMyrule=2
Mprog, P=sh, ...., S=Myrule
, ... ... SMyrule
In general, we recommend that you assign numbers to named rule sets only if there is a genuine need.
Macros may be used in any or all of a part of a rule-set declaration. They may be used to declare a name:
D{NAME}myname S${NAME}
or to declare a number:
D{NUMBER}12 S${NUMBER}
or both a name and a number:
D{NAME}myname D{NUMBER}12 S${NAME}=${NUMBER}
or even the whole thing:
D{SET}myset=12 S${SET}
You may use single- and multicharacter macros in any combination. Macros may be used in any rule-set declaration, including subroutine calls inside rules:
R$* < $=w > $* $@ $>${NAME} $2
But they may not be used in the
S=
or the
R=
of delivery agents:
Mprog, P=sh, ..., S=$X, R=$X, ... neither of these will work
Macros can be used in the command line to modify a configuration file when sendmail is run. Consider the desire to call one rule set when running as a daemon and another when processing the queue. You might declare such a rule like:
R$* < @ $+ > $* $@ $>$A
$2
The two different runs might look like this:
# /usr/lib/sendmail -MAdaemon_rule -bd # /usr/lib/sendmail -MAqueue_rule -q30m
The first defines the
$A
macro to have the value
daemon_rule
and results in this subroutine call:
R$* < @ $+ > $* $@ $>daemon_rule
$2
The second defines the
$A
macro to have the value
queue_rule
and results in this different subroutine call:
R$* < @ $+ > $* $@ $>queue_rule
$2
Note that you cannot define multi character macros from the command line. Also note that defining macros from the command line can result in sendmail giving up its root privilege.
All rules (
R
lines) that follow a rule-set declaration are added to and become part of that rule set:
S0 R... rules added to rule set 0 SMyset R... rules added to rule set Myset S1 R... rules added to rule set 1
Rule sets need not be declared in any particular order. Any order that clarifies the intention of the configuration file as a whole is acceptable. If a rule set appears more than once in a configuration file, V8 sendmail will print a warning:
WARNING: Rulesetname
redefined Prior to V8.8 WARNING: Rulesetname
has multiple definitions V8.8
and append the new rules to the old:
S0 R... rules added to rule set 0 S2 R... rules added to rule set 2 S0 warning issued R... rules appended to earlier rule set 0
Note that the warning is given in all cases prior to V8.8, but beginning with V8.8, it is issued only in
-bt
rule-testing mode or if the
-d37.1
debugging switch is set.
Other configuration commands may be interspersed among rule definitions without affecting the rule set to which the rules are added:
S0 R... rules added to rule set 0 Pjunk=-100 DUuucphost.our.domain R... rules added to rule set 0
Any rules that appear before the first
S
command are added to rule set 0 by default:
R... rules added to rule set 0 S1 first S command in configuration file R... rules added to rule set 1
Arbitrary text that follows a rule set declaration is ignored unless it appears to be part of the declaration:
S11 100 more rule sets rule set 11 S11100 more rule sets rule set 11,100 is illegal SMyset 100 more rule sets rule set Myset
Although the first and last of the above examples work, we recommend that you use the
#
commenting mechanism instead:
S11 #100 more rule sets rule set 11 S11#100 more rule sets rule set 11 SMyset #100 more rule sets rule set Myset
A rule-set declaration that has no rules associated with it is exactly the same as a rule set that is not declared. Both are like do-nothing subroutines:
rule set 1 not declared. Same as S2 rule set 2 without rules S3 R...