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