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