COMPUTER AND NETWORK
SYSTEM ADMINISTRATION
Summer 1996 - Lesson 21
Sendmail III
E. rewriting rules
> now we got the skin off the frog
1. many of the rewriting rules are for translating
address formats from archaic (or soon to be archaic)
mailers
ex: mail kuncick at sed
ex: mail sed.cs.fsu.edu\!tau.cs.fsu.edu\!kuncick ("UUCP bangland")
ex: mail kuncick@fsu.BITNET
2. syntax
- the rewrite rules are organized into rulesets
S3
.....
rules
.....
S6 - continues until another "S" flag is found
- rules consist of 3 fields LHS, RHS, and comments
- these are TAB separated!
- many a system group member has fallen on this one
- rule sets do not have to be in any particular order
- a ruleset with no rules in it acts like a "do nothing" subroutine
3. general rule functions
- mainly do one of 4 things:
substitute ex: replace 'at' with '@'
R$+ at $+ $1@$2
> if one or more tokens is followed by
' at ' followed by one or more tokens
then rewrite as $1@$2
strip ex: remove trailing dots
R$*<$*.>$* $1<$2>$3
> if zero or more tokens is followed by
'<' then zero or more tokens followed by
a '.>' then zero or more tokens
then rewrite as $1<$2>$3
> root@ ---> root@
focus ex: surround host name with < and >
defocus ex: remove < and > markers
4. order of ruleset execution
- Exhibit D, page 478
- the order of ruleset execution varies depending on whether or not
the address being operated on is a sender or recipient address
- a third branch is used to select delivery agents
- first sendmail finds the rule set numbers for R= and S=
- it follows the 'delivery agent' path to do this
3 ---> 0 ---> delivery agent selection
> the delivery agent supplies the meaning of S= and R= using the
recipient address
- after a delivery agent has been chosen the sender address path
is processed:
3 ---> 1 ---> S= ----> 4 ----> exit
> this rewritten sender address appears in the header and envelope
of the mail message
- finally, the recipient address need to be rewritten for inclusion
in the header and envelope
3 ---> 2 ---> R= ---> 4 ---> exit
- in our config file S1 and S2 are one-rule sets and are identical
> they simply de-focus the address
S1
R$*<$*>$* $1$2$3 defocus
S2
R$*<$*>$* $1$2$3 defocus
- why would we want sender and recipient addresses to be handled
separately?
> example: if we want format of all sender addresses to be
user@cs.fsu.edu
> we don't want the recipient address to have this format
- what about the other rulesets? when are they used?
> they are called as subroutines, example:
R$+%$+.BITNET<@cunyvm.cuny.edu> $>5$1<%$2.BITNET> strip
> this calls ruleset 5 and passes $1<%$2.BITNET> as the argument
5. order of rule execution within a ruleset
- once a ruleset is entered rules are processed in order UNLESS:
> a subroutine is called
> it escapes early using the $@ which terminates the ruleset
example:
R$+:$*;@$+ $@$1:$2;@$3 list syntax
> it escapes early using the $: which terminates the rule
example:
R$+%$+ $:$>5$1%$2 user%host%host
- otherwise, a rule is repeatedly executed until the LHS fails to match
- note that rules are by default applied in order listed,
but rulesets are not
F. Definitions of mailers
- third section of sendmail.cf
- defines programs to use
- local is for local mail delivery
Mlocal, P=/bin/mail, F=SlsDFMPpmnxr, S=10, R=20, A=mail -d $u
- prog is for execution of programs via mail (vacation, filters)
Mprog, P=/bin/sh, F=lsDFMpxehu, S=10, R=20, A=sh -c $u
- tcp is for network connection to another sendmail
Mtcp, P=[IPC], F=AmnDFMpueXLC, S=14, R=14, A=IPC $h, E=\r\n
- flags are defined on page 487
5. order of rule execution within a ruleset
###############################################################################
# RULESET ZERO PREAMBLE #
###############################################################################
S0
# first make canonical
R$*<$*>$* $1$2$3 defocus
R$+ $:$>3$1 make canonical
# handle special cases.....
R@ $#local$:$n handle <> form
R$*<@[$+]>$* $:$1<@$[[$2]$]>$3 lookup numeric addr
R$*<@[$+]>$* $#tcp$@[$2]$:$1@[$2]$3 numeric internet spec
# canonicalize using the nameserver if not internal domain
R$*<@$*.$~I>$* $:$1<@$[$2.$3$]>$4
R$*<@$->$* $:$1<@$[$2$]>$3
# now delete the local info
R$*<$*$=w.UUCP>$* $1<$2>$4 thishost
R$*<$*$=w.$T.$D>$* $1<$2>$4 thishost
R$*<$*$=w>$* $1<$2>$4 thishost
R$*<$*@zip.fsu.edu>$* $1.zip<@>$3
R$*<$*@zap.fsu.edu>$* $1.zap<@>$3
#R$*<$*$=T.$D>$* $1<$2>$4 otherhost
#R$*<$*$=T>$* $1<$2>$4 oth
R$*<$*.>$* $1<$2>$3 drop trailing dot
R<@>:$* $@$>0$1 retry after route strip
R$*<@> $@$>0$1 strip null trash & retry
# return uucp mail that looks like decvax!ittvax!marsvax! since it
# will be rejected at the final site with no username on it
R$*!<@$-.UUCP> $#error$:Destination address truncated
###############################################################################
### Machine dependent part of ruleset zero (where we decide what to do) ###
###############################################################################
# resolve various and sundry other unofficial networks
R$*<@$+.BITNET>$* $#tcp$@cunyvm.cuny.edu$:$1@$2.BITNET$3
R$*<@$+.ESNET>$* $#tcp$@ccc.nersc.gov$:$1@$2.ESNET$3
R$*<@$+.SPAN>$* $#tcp$@csa1.lbl.gov$:$1@$2.SPAN$3
R$*<@$+.HEPNET>$* $#tcp$@lbl.gov$:$1@$2.HEPNET$3
R$*<@$+.UUCP>$* $#tcp$@uunet.uu.net$:$1@$2$3
# when all else fails, look up the whole name in the host table
R$*<@$+>$* $#tcp$@$2$:$1@$2$3 user@domain
# remaining names must be local
R@ $n fix magic token
R$+ $#local$:$1 everything else
###############################################################################
### End of ruleset zero ###
###############################################################################
###########################
# Name Canonicalization #
###########################
S3
# handle "from:<>" special case
R<> $@@ resolve into magic token
# basic textual canonicalization
R$*<$*<$*<$+>$*>$*>$* $4 3-level <> nesting
R$*<$*<$+>$*>$* $3 2-level <> nesting
R$*<$+>$* $2 basic RFC821/822 parsing
R$+ at $+ $1@$2 "at" -> "@" for RFC 822
R$*<$*>$* $1$2$3 in case recursive
# make sure <@a,@b,@c:user@d> syntax is easy to parse -- undone later
R@$+,$+ @$1:$2 change all "," to ":"
# localize and dispose of domain-based addresses
R@$+:$+ $@$>6<@$1>:$2 handle
# more miscellaneous cleanup
R$+ $:$>8$1 host dependent cleanup
R$+:$*;@$+ $@$1:$2;@$3 list syntax
R$+@$+ $:$1<@$2> focus on domain
R$+<$+@$+> $1$2<@$3> move gaze right
R$+<@$+> $@$>6$1<@$2> already canonical
# convert old-style addresses to a domain-based address
R$+^$+ $1!$2 convert ^ to !
R$+!$+ $@$>9$1!$2 uucp name hackery
R$+%$+ $:$>5$1%$2 user%host%host
R$+<@$+> $@$>6$1<@$2> canonical
# Given multiple %'s change rightmost % to @.
S5
R$*<$*>$* $1$2$3 defocus
R$*%$* $1@$2 First make them all @'s.
R$*@$*@$* $1%$2@$3 Undo all but the last.
R$*@$* $@$1<@$2> Put back the brackets.
###############################################################################
#### Assorted name hackery to make things simple for people ####
###############################################################################
# here we look for addresses of the form: user%host.domain@gateway
# and strip off the gateway name (for the ones that we know)
S6
# conventional percent format
R$+%$+.SPAN<@csa1.lbl.gov> $>5$1<%$2.SPAN> strip
R$+%$+.ESNET<@ccc.nersc.gov> $>5$1<%$2.ESNET> strip
R$+%$+.HEPNET<@lbl.gov> $>5$1<%$2.HEPNET> strip
R$+%$+.BITNET<@cunyvm.cuny.edu> $>5$1<%$2.BITNET> strip
R$+%$+.UUCP<@uunet.uu.net> $>5$1<%$2.UUCP> strip
# regulation route-addr format
R<@csa1.lbl.gov>:$+@$+.SPAN $1<@$2.SPAN> strip
R<@ccc.nersc.gov>:$+@$+.ESNET $1<@$2.ESNET> strip
R<@lbl.gov>:$+@$+.HEPNET $1<@$2.HEPNET> strip
R<@cunyvm.cuny.edu>:$+@$+.BITNET $1<@$2.BITNET> strip
R<@uunet.uu.net>:$+@$+.UUCP $1<@$2.UUCP> strip
# mung up names for the outside world - called from tcp mailer
S7
R$+@$+.SPAN $1%$2.SPAN@csa1.lbl.gov
R$+@$+.ESNET $1%$2.ESNET@ccc.nersc.gov
R$+@$+.HEPNET $1%$2.HEPNET@lbl.gov
R$+@$+.BITNET $1%$2.BITNET@cunyvm.cuny.edu user@host.BITNET
R$+@$+.UUCP $1%$2@uunet.uu.net
###############################################################################
#### UUCP address hackery ####
###############################################################################
S9
R$+!$=w!$+ $3 collapse loops
R$-.$+!$+ $@$>6$3<@$1.$2> do.main!user
R$-!$+ $@$>6$2<@$1.UUCP> host!user
################################
# Sender Field Pre-rewriting #
################################
S1
R$*<$*>$* $1$2$3 defocus
###################################
# Recipient Field Pre-rewriting #
###################################
S2
R$*<$*>$* $1$2$3 defocus
###################################
# Final Output Post-rewriting #
# Standard Domain-based version #
###################################
S4
R@ $n handle <> error addr
# resolve numeric addresses to name if possible
R$*<@[$+]>$* $:$1<@$[[$2]$]>$3 lookup numeric addr
# externalize local domain info
R@$+:$+:$+ $@@$1,$2:$3 canonical
# UUCP must always be presented in old form
R$+@$-.UUCP $2!$1 u@h.UUCP => h!u
###############################################################################
### Local, and Program Mailer specifications ###
###############################################################################
# Nota Bene: what mailer flags you use depends upon what version of /bin/mail
# you have:
#
# 4th Berkeley Software Distribution (4.1 BSD or later)
Mlocal, P=/bin/mail, F=SlsDFMPpmnxr, S=10, R=20, A=mail -d $u
#
# USG UNIX (System III, System V, Xenix 3.0 or later)
# Mlocal, P=/bin/mail, F=SlsDFMPpmnx, S=10, R=20, A=mail $u
#
# Also, if you are using System V, you should get the Berkeley version of
# /bin/mail as soon as you can and junk the one you've got: it doesn't
# believe in sendmail, so the wrong thing will happen when someone types
# mail user@host (i.e. it will attempt local delivery, rather than call
# sendmail)
#
Mprog, P=/bin/sh, F=lsDFMpxehu, S=10, R=20, A=sh -c $u
#Mprog, P=/bin/false, F=, S=10, R=20, A=
#
S10
S20
###############################################################################
#### IP/TCP/SMTP mailer (going out to internet land) ####
###############################################################################
Mtcp, P=[IPC], F=AmnDFMpueXLC, S=14, R=14, A=IPC $h, E=\r\n
S14
R$*@[$+]$* $@$1@[$2]$3 already ok (inet addr spec)
R@$+@$+ $@@$1@$2 already ok (route-addr)
R$+@$=X.UUCP $2!$1@$X fix remote UUCP
R$+@$=Y.UUCP $2!$1@$Y fix remote UUCP
R$+@$=Z.UUCP $2!$1@$Z fix remote UUCP
R$+@$-.UUCP $2!$1@$j undo local UUCP hack
R$+@$+ $@$>7$1@$2 fix up names for the internet
R$+ $@$1@$j add our official host name