There is rarely any need to use sendmail.cf commands in your configuration because the sendmail macros created by the sendmail developer handle most possible configurations. Yet it is useful to know something about the sendmail.cf command for those rare occasions when you come across a configuration that requires something that the sendmail developers just didn't think of. Table 12-3 lists the sendmail.cf configuration commands.
Command |
Syntax |
Meaning |
---|---|---|
Version Level |
Specify version level. | |
Define Macro |
Set macro x to value. | |
Define Class |
Set class c to word1 word2 .... | |
Define Class |
Load class c from file. | |
Key File |
Define database name. | |
Set Option |
Set option to value. | |
Trusted Users |
Trusted users are user1 user2 .... | |
Set Precedence |
Set name to precedence number. | |
Define Mailer |
Define mailer name. | |
Define Header |
Set header format. | |
Set Ruleset |
Start ruleset number n. | |
Define Rule |
Rewrite lhs patterns to rhs format. |
All of the commands in this table, except the last two, can be used with the LOCAL_CONFIG macro. The LOCAL_CONFIG macro is the one that heads a section of sendmail.cf commands used to define values for the configuration. These can be sendmail.cf database declarations, macros, or class values. Essentially anything except rewrite rulesets. Despite this, several of the sendmail.cf commands shown in Table 12-3 are simply not needed in the sendmail.mc file, even when you create a special configuration.
There is no real reason to add sendmail.cf O commands to the sendmail.mc configuration because all sendmail.cf options can be set using the define command and m4 variables. Likewise, all necessary M commands are added to the sendmail.cf file by the m4 MAILER macros, and therefore it is very unlikely you would use LOCAL_CONFIG to add M commands to your configuration. The T and P commands have limited roles. The T command adds usernames to the list of users who are allowed to send mail under someone else's username. Because of security considerations, you should be very careful about extending this list, and even if you do, you can use the confTRUSTED_USERS define in the m4 file, or the FEATURE(use_ct_file) macro and define the usernames in the /etc/mail/trusted-users file. The P command defines mail precedence, and frankly the default sendmail.cf configuration already has more mail precedence defined you will ever need.
The sendmail.cf commands that most commonly follow the LOCAL_CONFIG macro are D, C, F, and K. All of these can be used to define custom values that are later use, in a custom ruleset. The D command sets the value for a sendmail.cf macro. The C command adds values to a sendmail.cf class from the command line. The F command adds values to a sendmail.cf class from a file. The K command defines a database from which sendmail can obtain values. All of the standard sendmail.cf macros, classes, and databases can be used through standard m4 macros. D, C, F, or K commands are added to the sendmail.mc configuration only on those rare occasions when you create your own private macros, classes, or databases.
The H command defines a mail header. All of the standard mail headers are already defined in the default configuration, and it is unlikely you will ever need to define a new header type. Calling special header processing is the most common reason to add a header definition to the configuration. (See the cf/cf/knecht.mc file for an example of a header definition that calls special processing, and see Recipe 6.9 in the sendmail Cookbook [O'Reilly] by Craig Hunt for a good description of how special header processing is invoked.) Of course, if you do call special header processing, you must also write the ruleset that performs the processing. The S and R commands used to write custom rulesets are our next topic.
Arguably the most powerful feature of sendmail is the rewrite rule. Rewrite rules determine how sendmail processes a mail message. sendmail passes the addresses from the headers of a mail message through collections of rewrite rules called rulesets. In the sendmail.cf file, each ruleset is named using an S command, coded as Sn, where n specifies the name or number that is to be assigned to the current ruleset.
The rules themselves are defined by R commands grouped together as rulesets. Each rule has a left side and a right side, separated by at least one tab character.[3] When sendmail is processing a mail address, it scans through the rewrite rules looking for a match on the left side. If the address matches the left side of a rewrite rule, the address is replaced by the right side and processed again. In this manner, the rewrite rules transform a mail address from one form to another. Think of them as being similar to an editor command that replaces all text matching a specified pattern with another.
[3] Only tabs can separate the left and right side.
A sendmail ruleset therefore looks like this:
Sn Rlhs rhs Rlhs2 rhs2
The left side of a rewrite rule specifies the pattern an address must match to be transformed. The pattern may contain literals, sendmail.cf macros and classes, and the metasymbols described in the following list:
Match exactly zero tokens
$*
Match zero or more tokens
$+
Match one or more tokens
$-
Match exactly one token
$= x
Match any value in class x
$~ x
Match any value not in class x
A token is either a string of characters delimited by an operator or a delimiting operator. The operators are defined by the sendmail.cf OperatorChars option, as shown below:
O OperatorChars=.:%@!^/[ ]+
Assume the following address:
alana@ipa.vbrew.com
This email address contains seven tokens: alana, @, ipa, ., vbrew, ., and com. Three of these tokens, two dots (.), and an @, are operators. The other four tokens are strings. This address would match the symbol $+ because it contains more than one token, but it would not match the symbol $- because it does not contain exactly one token.
When a rule matches an address, the text matched by each of the patterns in the expression is assigned to special variables, called indefinite tokens, which can then be used in the right side. The only exception to this is the $@, which matches no tokens and therefore will never generate text to be used on the right side.
When the left side of a rewrite rule matches an address, the original text is deleted and replaced by the right side of the rule. Literal values in the right side are copied to the new address verbatim. Righthand side sendmail.cf macros are expanded and copied to the new address. Just as the left side has a number of metasymbols used for pattern matching, the right side has a special syntax for transforming an address, as described in the following list:
$ n
This metasymbol is replaced with the n'th indefinite token from the left side.
$[ name$]
This string is replaced by the canonical form of the hostname supplied.
$( map key $ :default $)
This special syntax returns the result of looking up key in the database named map. If the lookup is unsuccessful, the value defined for default is returned. If a default is not supplied and lookup fails, the key value is returned.
$> n
This metasymbol calls ruleset n to process the rest of the line.
A rewrite rule that matches is normally tried repeatedly until it fails to match, then parsing moves on to the next rule. This behavior can be changed by preceding the right side with one of two special loop control metasymbols:
$@
This metasymbol terminates the ruleset.
$:
This metasymbol terminates this individual rule.
There is also a special right side syntax used to create the mail delivery triple of mailer, host and user. This syntax is most commonly seen in ruleset 0, which parses the mail delivery address. These symbols are:
$# mailer
This metasymbol causes ruleset evaluation to halt and specifies the mailer that should be used to transport this message in the next step of its delivery. The special mailer error can be invoked in this manner to return an error message.
$@ host
This metasymbol specifies the host to which this message will be delivered. If the destination host is the local host, this syntax may be omitted from the mail delivery triple. The host may be a colon-separated list of destination hosts that will be tried in sequence to deliver the message.
$ :user
This metasymbol specifies the recipient user for the mail message.
To better see how the macro substitution patterns operate, consider the following left side:
$* < $+ >
This rule matches "Zero or more tokens, followed by the < character, followed by one or more tokens, followed by the > character."
If this rule were applied to brewer@vbrew.com or Head Brewer < >, the rule would not match. The first string would not match because it does not include a < character, and the second would fail because $+ matches one or more tokens and there are no tokens between the <> characters. In any case in which a rule does not match, the right side of the rule is not used.
If the rule were applied to Head Brewer < brewer@vbrew.com >, the rule would match, and on the right side $1 would be substituted with Head Brewer and $2 would be substituted with brewer@vbrew.com.
If the rule were applied to < brewer@vbrew.com > the rule would match because $* matches zero or more tokens, and on the right side $1 would be substituted with the empty string.
The following example uses the LOCAL_NET_CONFIG macro to declare a local rule and to insert the rule near the end of ruleset 0. Ruleset 0 resolves a delivery address to a mail delivery triple specifying the mailer, user, and host. Example 12-1 shows a sample rewrite rule.
LOCAL_NET_CONFIG R$*<@$*.$m.>$* $#esmtp $@$2.$m. $:$1<@$2.$m.>$3
The LOCAL_NET_CONFIG macro is used to direct m4 to place the rewrite rule in ruleset 0. The rule itself is the line beginning with R. Let's look at the rule's left side and the right side in turn.
The left side looks like: $*<@$*.$m.>$*.
< and > are focus characters, inserted by ruleset 3 early on in the address processing, which enclose the host part of the mail address. All addresses get rewritten with these focus characters. The @ is literally the @ used in an Internet email address to separate the user part from the host part. The dots (.) are literally the dots used in domain names. $m is a sendmail.cf macro used to hold the local domain name. The three remaining items are all $* metasymbols.
This rule matches any mail address that looks like: DestUser<@somehost.ourdomain.>Some Text. That is, it matches mail for any user at any host within our domain.
Text matched by metasymbols on the left side of a rewrite rule is assigned to indefinite tokens for use on the right side. In this example, the first $* matches all text from the start of the address until the <@ characters. All of this text is assigned to $1 for use on the right side. Similarly, anything matching the second $* in this rewrite rule is assigned to $2, and anything matching the last $* is assigned to $3.
When this rule matches an address of any user at any host within our domain, it assigns the username to $1, the hostname to $2, and any trailing text to $3. The right side is then used to process these values.
The right side of our example rewrite rule looks like this: $#esmtp $@$2.$m. $:$1<@$2.$m.>$3.
When the right side of our ruleset is processed, each of the metasymbols are interpreted and relevant substitutions are made.
The $# metasymbol causes this rule to resolve to a specific maileresmtp, in our case.
The $@ metasymbol specifies the target host. In our example, the target host is specified as $2.$m., which is the fully qualified domain name of the host in our domain. The FQDN is constructed of the hostname component assigned to $2 from our left side with our domain name (.$m.) appended.
The $: metasymbol specifies the recipient user's address. This is the full email address of the recipient, constructed in this case by $1 < @ $2.$m. > $3user, bracket, at, host, dot, domain, dot, bracket, trailing text.
Since this rule resolves to a mailer, the message is forwarded to the mailer for delivery. In our example, the message would be forwarded to the destination host using the SMTP protocol.