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...