Tải bản đầy đủ
[Chapter 10] 10.6 Rewriting the Mail Address

[Chapter 10] 10.6 Rewriting the Mail Address

Tải bản đầy đủ

[Chapter 10] 10.6 Rewriting the Mail Address

$x
$%x
$!x
$%y

Match all tokens in macro x.
Match any token in the NIS map named in macro x. [17]
Match any token not in the NIS map named in macro x.[17]
Match any token in the NIS hosts.byname map.[17]
[17] This symbol is specific to Sun operating systems.

All of the metasymbols request a match for some number of tokens. A token is a string of characters
in an email address delimited by an operator. The operators are the characters defined in the
OperatorChars option. [18] Operators are also counted as tokens when an address is parsed. For
example:
[18] On older systems, they are defined in the o macro. See Appendix E.
becky@peanut.nuts.com
This email address contains seven tokens: becky, @, peanut, ., nuts, ., and com. This address would
match the pattern:
$-@$+
The address matches the pattern because:




It has exactly one token before the @ that matches the requirement of the $- symbol.
It has an @ that matches the pattern's literal @.
It has one or more tokens after the @ that match the requirement of the $+ symbol.

Many addresses, hostmaster@rs.internic.net, craigh@ora.com, etc., match this pattern, but other
addresses do not. For example, rebecca.hunt@nuts.com does not match because it has three tokens:
rebecca, ., and hunt, before the @. Therefore, it fails to meet the requirement of exactly one token
specified by the $- symbol. Using the metasymbols, macros, and literals, patterns can be constructed
to match any type of email address.
When an address matches a pattern, the strings from the address that match the metasymbols are
assigned to indefinite tokens. The matching strings are called indefinite tokens because they may
contain more than one token value. The indefinite tokens are identified numerically according to the
relative position in the pattern of the metasymbol that the string matched. In other words, the
indefinite token produced by the match of the first metasymbol is called $1; the match of the second
symbol is called $2; the third is $3; and so on. When the address becky@peanut.nuts.com matched the
pattern $-@$+, two indefinite tokens were created. The first is identified as $1 and contains the single
token, becky, that matched the $- symbol. The second indefinite token is $2 and contains the five
tokens - peanut, ., nuts, ., and com - that matched the $+ symbol. The indefinite tokens created by the
pattern matching can then be referenced by name ($1, $2, etc.) when rewriting the address.

file:///C|/mynapster/Downloads/warez/tcpip/ch10_06.htm (2 of 9) [2001-10-15 09:18:41]

[Chapter 10] 10.6 Rewriting the Mail Address

A few of the symbols in Table 10.4 are used only in special cases. The $@ symbol is normally used
by itself to test for an empty, or null, address. The symbols that test against NIS maps, can only be
used on Sun systems that run the sendmail program that Sun provides with the operating system. We'll
see in the next section that systems running sendmail V8 can use NIS maps, but only for
transformation - not for pattern matching.

10.6.2 Transforming the Address
The transformation field, from the righthand side of the rewrite rule, defines the format used for
rewriting the address. It is defined with the same things used to define the pattern: literals, macros,
and special metasymbols. Literals in the transformation are written into the new address exactly as
shown. Macros are expanded and then written. The metasymbols perform special functions. The
transformation metasymbols and their functions are shown in Table 10.5
Table 10.5: Transformation Metasymbols
Symbol
Meaning
$n
Substitute indefinite token n.
$[name$]
Substitute the canonical form of name.
$(map key $@argument $:default$) Substitute a value from database map indexed by key.
$>n
Call ruleset n.
$@
Terminate ruleset.
$:
Terminate rewrite rule.
The $n symbol, where n is a number, is used for the indefinite token substitution discussed above.
The indefinite token is expanded and written to the "new" address. Indefinite token substitution is
essential for flexible address rewriting. Without it, values could not be easily moved from the input
address to the rewritten address. The following example demonstrates this.
Addresses are always processed by several rewrite rules. No one rule tries to do everything. Assume
the input address mccafferty@peanut has been through some preliminary processing and now is:
kathy.mccafferty<@peanut>
Assume the current rewrite rule is:
R$+<@$->

$1<@$2.$D>

user@host -> user@host.domain

The address matches the pattern because it contains one or more tokens before the literal <@, exactly
one token after the <@, and then the literal >. The pattern match produces two indefinite tokens that
are used in the transformation to rewrite the address.
The transformation contains the indefinite token $1, a literal <@, indefinite token $2, a literal dot (.),
file:///C|/mynapster/Downloads/warez/tcpip/ch10_06.htm (3 of 9) [2001-10-15 09:18:41]

[Chapter 10] 10.6 Rewriting the Mail Address

the macro D, and the literal >. After the pattern matching, $1 contains kathy.mccafferty and $2
contains peanut. Assume that the macro D was defined elsewhere in the sendmail.cf file as nuts.com.
In this case the input address is rewritten as:
kathy.mccafferty<@peanut.nuts.com>
Figure 10.3 illustrates this specific address rewrite. It shows the tokens derived from the input address,
and how those tokens are matched against the pattern. It also shows the indefinite tokens produced by
the pattern matching, and how the indefinite tokens, and other values from the transformation, are
used to produce the rewritten address. After rewriting, the address is again compared to the pattern.
This time it fails to match the pattern because it no longer contains exactly one token between the
literal <@ and the literal >. So, no further processing is done by this rewrite rule and the address is
passed to the next rule in line. Rules in a ruleset are processed sequentially, though a few
metasymbols can be used to modify this flow.
Figure 10.3: Rewriting an address

The $>n symbol calls ruleset n and passes the address defined by the remainder of the transformation
to ruleset n for processing. For example:
$>9 $1 % $2
This transformation calls ruleset 9 ($>9), and passes the contents of $1, a literal %, and the contents of
$2 to ruleset 9 for processing. When ruleset 9 finishes processing, it returns a rewritten address to the
calling rule. The returned email address is then compared again to the pattern in the calling rule. If it
still matches, ruleset 9 is called again.
The recursion built into rewrite rules creates the possibility for infinite loops. sendmail does its best to
detect possible loops, but you should take responsibility for writing rules that don't loop. The $@ and
file:///C|/mynapster/Downloads/warez/tcpip/ch10_06.htm (4 of 9) [2001-10-15 09:18:41]

[Chapter 10] 10.6 Rewriting the Mail Address

the $: symbols are used to control processing and to prevent loops. If the transformation begins with
the $@ symbol, the entire ruleset is terminated and the remainder of the transformation is the value
returned by the ruleset. If the transformation begins with the $: symbol, the individual rule is executed
only once. Use $: to prevent recursion and to prevent loops when calling other rulesets. Use $@ to
exit a ruleset at a specific rule.
The $[name$] symbol converts a host's nickname or its IP address to its canonical name by passing
the value name to the name server for resolution. For example, using the nuts.com name servers,
$[goober$] returns peanut.nuts.com and $[[172.16.12.1]$] returns almond.nuts.com.
In the same way that a hostname or address is used to look up a canonical name in the name server
database, the $(map key$) syntax uses the key to retrieve information from the database identified by
map. This is a more generalized database retrieval syntax than is the one that returns canonical
hostnames, and it is more complex to use. Before we get into the details of setting up and using
databases from within sendmail, let's finish describing the rest of the syntax of rewrite rules.
There is a special rewrite rule syntax that is used in ruleset 0. Ruleset 0 defines the triple (mailer, host,
user) that specifies the mail delivery program, the recipient host, and the recipient user.
The special transformation syntax used to do this is:
$#mailer$@host$:user
An example of this syntax taken from the linux.smtp.cf sample file is:
R$*<@$*>$*

$#smtp$@$2$:$1<@$2>$3

user@host.domain

Assume the email address david<@filbert.nuts.com> is processed by this rule. The address matches
the pattern $*<@$+>$* because:







The address has zero or more tokens (the token david) that match the first $* symbol.
The address has a literal <@.
The address has zero or more tokens (the five tokens filbert.nuts.com) that match the
requirement of the second $* symbol.
The address has a literal >.
The address has zero or more, in this case zero, tokens that match the requirement of the last $*
symbol.

This pattern match produces two indefinite tokens. Indefinite token $1 contains david and $2 contains
filbert.nuts.com. No other matches occurred, so $3 is null. These indefinite tokens are used to rewrite
the address into the following triple:
$#smtp$@filbert.nuts.com$:david<@filbert.nuts.com>
The components of this triple are:
file:///C|/mynapster/Downloads/warez/tcpip/ch10_06.htm (5 of 9) [2001-10-15 09:18:41]

[Chapter 10] 10.6 Rewriting the Mail Address

$#smtp
smtp is the internal name of the mailer that delivers the message.
$@filbert.nuts.com
filbert.nuts.com is the recipient host.
$:david<@filbert.nuts.com>
david<@filbert.nuts.com> is the recipient user.
There is one special variant of this syntax, also used only in ruleset 0, that passes error messages to
the user:
$#error$@comment$:message
The comment field is ignored by sendmail. message is the text of an error message returned to the
user, for example:
R<@$+>

$#error$@5.1.1$:"user address required"

This rule returns the message "user address required" if the address matches the pattern.
10.6.2.1 Transforming with a database
External databases can be used to transform addresses in rewrite rules. The database is included in the
transformation part of a rule by using the following syntax:
$(map key [$@argument...] [$:default] $)
map is the name assigned to the database within the sendmail.cf file. The name assigned to map is not
limited by the rules that govern macro names. Like mailer names, map names are only used inside of
the sendmail.cf file and can be any name you choose. Select a simple descriptive name, such as
"users" or "mailboxes." The map name is assigned with a K command. (More on the K command in a
moment.)
key is the value used to index into the database. The value returned from the database for this key is
used to rewrite the input address. If no value is returned, the input address is not changed unless a
default value is provided.
An argument is an additional value passed to the database procedure along with the key. Multiple
arguments can be used, but each argument must start with $@. The argument can be used by the
database procedure to modify the value it returns to sendmail. It is referenced inside the database as
%n, where n is a digit that indicates the order in which the argument appears in the rewrite rule - %1,
file:///C|/mynapster/Downloads/warez/tcpip/ch10_06.htm (6 of 9) [2001-10-15 09:18:41]

[Chapter 10] 10.6 Rewriting the Mail Address

%2, and so on - when multiple arguments are used. (Argument %0 is the key.)
An example will make the use of arguments clear. Assume the following input address:
tom.martin<@sugar>
Further, assume the following database with the internal sendmail name of "relays":
oil
sugar
salt

%1<@relay.fats.com>
%1<@relay.calories.com>
%1<@server.sodium.org>

Finally, assume the following rewrite rule:
R$+<@$->

$(relays $2 $@ $1 $:$1<@$2> $)

The input address tom.martin<@sugar> matches the pattern because it has one or more tokens
(tom.martin) before the literal <@ and exactly one token (sugar) after it. The pattern matching creates
two indefinite tokens and passes them to the transformation. The transformation calls the database
(relays) and passes it token $2 (sugar) as the key and token $1 (tom.martin) as the argument. If the
key is not found in the database the default ($1<@$2>) is used. In this case, the key is found in the
database. The database program uses the key to retrieve "%1@relay.calories.com", expands the %1
argument, and returns "tom.martin@relay.calories.com" to sendmail, which uses the returned value to
replace the input address.
Before a database can be used within sendmail, it must be defined. This is done with the K command.
The syntax of the K command is:
Kname type [arguments]
name is the name used to reference this database within sendmail. In the example above, the name is
"relays".
type is the class of database. The type specified in the K command must match the database
support complied into your sendmail. Most sendmail programs do not support all database types, but a
few basic types are widely supported. Common types are dbm, hash, btree, and nis. There are many
more, all of which are described in Appendix E.
arguments are optional. Generally, the only argument is the path of the database file. Occasionally
the arguments include flags that are interpreted by the database program. The full list of K command
flags that can be passed in the argument field are listed in Appendix E.
To define the "relays" database file used in the example above, we might enter the following
command in the sendmail.cf file:
file:///C|/mynapster/Downloads/warez/tcpip/ch10_06.htm (7 of 9) [2001-10-15 09:18:41]

[Chapter 10] 10.6 Rewriting the Mail Address

Krelays dbm /usr/local/relays
The name relays is simply a name you chose because it is descriptive. The database type dbm is a type
supported by your version of sendmail and was used by you when you built the database file. Finally,
the argument /usr/local/relays is the location of the database file you created.
Don't worry if you're confused about how to build and use database files within sendmail. We will
revisit this topic later in the chapter and the examples will make the practical use of database files
clear.

10.6.3 The Set Ruleset Command
Rulesets are groups of associated rewrite rules that can be referenced by a number. The S command
marks the beginning of a ruleset and identifies it with a number. In the Sn command syntax, n is the
number that identifies the ruleset. Numbers in the range of 0 to 99 are used.
Rulesets can be thought of as subroutines, or functions, designed to process email addresses. They are
called from mailer definitions, from individual rewrite rules, or directly by sendmail. Six rulesets have
special functions and are called directly by sendmail. These are:


Ruleset 3 is the first ruleset applied to addresses. It converts an address to the canonical form:
local-part@host.domain.
In specific circumstances the @host.domain part is added by sendmail after ruleset 3
terminates. This happens only if the mail has been received from a mailer with the C flag set.
[19] In our sample configuration file, none of the mailers use this flag. If the C flag is set, the
sender's @host.domain is added to all addresses that have only a local-part. This processing is
done after ruleset 3 and before rulesets 1 and 2. (This function is represented in Figure 10.4 by
the box marked "D.")
[19] See Appendix E for the full set of mailer flags.









Ruleset 0 is applied to the addresses used to deliver the mail. Ruleset 0 is applied after ruleset
3, and only to the recipient addresses actually used for mail delivery. It resolves the address to
the triple (mailer, host, user) composed of the name of the mailer that will deliver the mail, the
recipient hostname, and the recipient username.
Ruleset 1 is applied to all sender addresses in the message.
Ruleset 2 is applied to all recipient addresses in the message.
Ruleset 4 is applied to all addresses in the message and is used to translate internal address
formats into external address formats.
Ruleset 5 is applied to local addresses after sendmail processes the address against the aliases
file. Ruleset 5 is only applied to local addresses that do not have an alias.

file:///C|/mynapster/Downloads/warez/tcpip/ch10_06.htm (8 of 9) [2001-10-15 09:18:41]

[Chapter 10] 10.6 Rewriting the Mail Address

Figure 10.4 shows the flow of the message and addresses through these rulesets. The D box does not
symbolize a ruleset. It is the internal sendmail process described above. The S and R symbols do stand
for rulesets. They have numeric names just like all normal rulesets, but the numbers are not fixed as is
the case with rulesets 0, 1, 2, 3, 4, and 5. The S and R ruleset numbers are defined in the S and R
fields of the mailer definition. Each mailer may specify its own S and R rulesets for mailer-specific
cleanup of the sender and recipient addresses just before the message is delivered.
Figure 10.4: Sequence of rulesets

There are, of course, many more rulesets in most sendmail.cf files. The other rulesets provide
additional address processing and are called by existing rulesets using the $>n construct. [20] The
rulesets provided in any sample sendmail.cf file will be adequate for delivering SMTP mail. It's
unlikely you'll have to add to these rulesets, unless you want to add new features to your mailer.
[20] See Table 10-5.

Previous: 10.5 sendmail
Configuration
10.5 sendmail Configuration

TCP/IP Network
Administration
Book Index

Next: 10.7 Modifying a
sendmail.cf File
10.7 Modifying a sendmail.cf
File

[ Library Home | DNS & BIND | TCP/IP | sendmail | sendmail Reference | Firewalls | Practical Security ]

file:///C|/mynapster/Downloads/warez/tcpip/ch10_06.htm (9 of 9) [2001-10-15 09:18:41]

[Chapter 10] 10.7 Modifying a sendmail.cf File

Previous: 10.6 Rewriting
the Mail Address

Chapter 10
sendmail

Next: 10.8 Testing
sendmail.cf

10.7 Modifying a sendmail.cf File
In this section we put into practice everything we discussed about sample configuration files - their
structure and the commands used to build them. We'll modify the prototype configuration file,
linux.smtp.cf, for use on peanut.nuts.com. We've chosen to modify this file because its configuration is
closest to the configuration we need for peanut.nuts.com. peanut is a Linux workstation on a TCP/IP
Ethernet, and it uses SMTP mail and domain name service (DNS).
The following sections are titled according to the sections of the file, and they describe the modifications
we'll make to the file, section by section. Remember that other sendmail.cf files will probably use different
section titles, but the basic information provided in the configuration will be the same.

10.7.1 Modifying Local Information
The first line in the local information section of the sendmail.cf file defines class w. [21] Class w is the full
set of host names for which this system accepts mail. Use the class w command to add hostnames to this
set. sendmail initializes this class to the value in macro w ($w), which is the hostname of this computer. On
most systems that is enough; sendmail is able to correctly identify most of the other hostnames for which it
should accept mail by querying DNS. The w class needs only to identify systems that expect this host to
accept mail for them and that do not have CNAME or MX entries in the DNS that point to this host. You'll
need to add a hostname to class w, or an MX record to DNS, if you see the following mail error:
[21] The full text of the local information section is shown in Appendix E.
mil-gw.nuts.com. config error: mail loops back to me (MX problem?)
In our sample, we accept the Cw command as written, and let sendmail define the value for w internally.
This is the most common method for desktop systems like peanut. On the system almond, which is also
known by the name mil-gw, we would add values to class w as follows:
Cwlocalhost mil-gw mil-gw.nuts.com
Now mail addressed to user@mil-gw.nuts.com would be accepted by almond and not rejected as being
addressed to the wrong host.
Some mail servers might need to be configured to accept mail for many different hostnames. In that case
file:///C|/mynapster/Downloads/warez/tcpip/ch10_07.htm (1 of 5) [2001-10-15 09:18:42]

[Chapter 10] 10.7 Modifying a sendmail.cf File

you may want to load class w from a file containing all of the hostnames. Do that with the F command.
No modification is necessary for the j macro definition because, on this system, sendmail obtains a fully
qualified domain name for the j macro from DNS. On some systems this is the case; on other systems
sendmail obtains the hostname without the domain extension. If j doesn't contain the full name, initialize j
with the hostname ($w) and the domain name. In the sample file we would do this by "uncommenting" the
Dj command and editing the domain string to be nuts.com. However, there is no need to do this because j
has the correct value.
To test if j is set to the correct value on your system, run sendmail with the -bt option and the debug level
set to 0.4. In response to this, sendmail displays several lines of information, including the value of j. In the
example below, sendmail displays the value peanut.nuts.com for j. If it displayed only peanut, we would
edit sendmail.cf to correct the value for j.
# sendmail -bt -d0.4
Version 8.8.5
Compiled with: LOG MATCHGECOS MIME8TO7 NAMED_BIND NDBM
NETINET NETUNIX NEWDB SCANF USERDB XDEBUG
canonical name: peanut.nuts.com
UUCP nodename: peanut
a.k.a.: peanut.nuts.com
a.k.a.: [172.16.12.2]
============ SYSTEM IDENTITY (after readcf) ============
(short domain name) $w = peanut
(canonical domain name) $j = peanut.nuts.com
(subdomain name) $m = nuts.com
(node name) $k = peanut
========================================================
ADDRESS TEST MODE (ruleset 3 NOT automatically invoked)
Enter

> ^D
The next line in the local information section defines class P. In our sample configuration file, class P
stores the names of some special mail routing domains. These pseudo-domain names allow us to address
users who are not on the Internet with Internet style email addresses. For example, mail can be addressed
using the normal UUCP "bang" syntax, e.g., ora!los!craig, or it can be addressed in a pseudo-Internet
format, e.g., craig@los.ora.uucp. These mail routing domains simplify the address that the user enters, and
route the mail to the correct mail relay host. However, pseudo-domains are rarely needed because most
mailers now support standard Internet-style addresses. The class P definition in linux.smtp.cf does not
require any modification. The only value assigned as a pseudo-domain is a dot (.), which is used in this
sendmail.cf file to identify canonical domain names.
The configuration file has macro definitions for several mail relays. None of these are assigned a value in
our sample file. You only need a relay host if your system cannot deliver the mail because it lacks
capability or connectivity. UNIX systems do not lack capability, but a firewall might limit connectivity.
file:///C|/mynapster/Downloads/warez/tcpip/ch10_07.htm (2 of 5) [2001-10-15 09:18:42]

[Chapter 10] 10.7 Modifying a sendmail.cf File

Some sites use a mail relay so that only one systems needs a full sendmail.cf configuration. The other hosts
at the site simply forward their mail to the smart host for delivery. If this is the configuration policy of your
site, enter the name of the mail relay as the "smart" relay. For example:
DSrelay.nuts.com
We don't enter anything in any of the relay settings on peanut. This desktop system will handle all its own
mail. Hey, that's why we run UNIX!
The local information section in the sample file also includes four key file definitions. Three of these K
commands are commented out, and all four of them can be ignored. The one key file definition that is not
commented out defines the dequote database, which is an internal sendmail database used to remove quotes
from within email addresses. The user key file, which is commented out, is also an internal database. It is
used to check if a username exists. The last two databases exist only if you create them. The domaintable is
used to rewrite domain names and the mailertable database is used to send mail addressed to a specific
domain through a particular mailer to a specific remote host.
The version number doesn't require modification - but it's a good idea to keep track of the changes you
make to your sendmail configuration, and this is the place to do it. Each time you modify the configuration,
change the version number by adding your own revision number. At the same time, enter a comment in the
file describing the changes you made. Usually, this is the last change made to the files so the comments
reflect all changes. For example, the original version number section in the linux.smtp.cf file is:
######################
#
Version Number
#
######################
DZ8.7.3
After we have finished all of our modifications, it will contain:
######################
#
Version Number
#
######################
# R1.0 - modified for peanut by Craig
#
- cleaned up the comments in the local info section
# R1.1 - modified macro M to use nuts.com instead of the
#
hostname in outgoing mail
# R2.0 - added rule a to S11 & S31 to rewrite to first.last format
DZ8.7.3R2.0
Finally, we need to understand the purpose of a few other classes and macros found in this section. The M
macro is used to rewrite the sender host address. Define a value for M to hide the name of the local host in
outbound mail. Classes E and M are both related to macro M. Class E defines the usernames for which the
hostname is not rewritten even if the M macro is defined. For example, root@peanut.nuts.com is not
rewritten to root@nuts.com even if M is defined as DMnuts.com. Class M is defines other hostnames, not
just the local hostname, that should be rewritten to the value of macro M. This is used on mail servers that
file:///C|/mynapster/Downloads/warez/tcpip/ch10_07.htm (3 of 5) [2001-10-15 09:18:42]