home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1992 March / Source_Code_CD-ROM_Walnut_Creek_March_1992.iso / usenet / altsrcs / 2 / 2845 / INTRO
Encoding:
Text File  |  1991-02-24  |  7.6 KB  |  204 lines

  1.         An introduction to Sendmail Rules
  2.         Copyright 1991, All rights reserved
  3.         Bruce Barnett
  4.  
  5.     First of all, sendmail is easy to learn, once you learned all
  6. about electronic mail. Figuring out how to handle the address
  7.  
  8.     bigvax::a!b!another.domain!c%d%domain.com@another.domain
  9.  
  10. is much more challenging. Here's the scoop.
  11.  
  12.     When sendmail gets a, address, it always passes it to rule 3.
  13.  
  14.     Rule 3 with transform the address, and eventually sent it to
  15.     rule 0.
  16.  
  17.     Rule 0 makes the final decision, and selects three things:
  18.  
  19.             The address
  20.             The Machine to send the address to
  21.             The mailer to use.
  22.                 This could be UUCP, ethernet, DECNet,
  23.                 a local user, a program, etc.
  24.  
  25.     Once the above has been decided on, the address is transformed
  26.     in the following way:
  27.  
  28.     Ruleset 1 is applied to the From: line
  29.     Ruleset 2 is applied to the To: and Cc: line
  30.     
  31.     Each mailer then applies a rule. These rules are other unique
  32.     for each mailer.
  33.  
  34.     Finally ruleset 4 is applied.
  35.  
  36.  
  37. Now let's go through an example in detail.
  38.  
  39. grymoire% /usr/lib/sendmail -bt -C/etc/sendmail.cf
  40. ADDRESS TEST MODE
  41. Enter <ruleset> <address>
  42. > 0 user@crdgw1.crd        # <---- I typed this line here 
  43. rewrite: ruleset  3   input: "user" "@" "crdgw1" "." "crd"
  44. rewrite: ruleset  6   input: "user" "<" "@" "crdgw1" "." "crd" ">"
  45. rewrite: ruleset  6 returns: "user" "<" "@" "crdgw1" "." "LOCAL" ">"
  46. rewrite: ruleset  3 returns: "user" "<" "@" "crdgw1" "." "LOCAL" ">"
  47. rewrite: ruleset  0   input: "user" "<" "@" "crdgw1" "." "LOCAL" ">"
  48. rewrite: ruleset  0 returns: $# "ether" $@ "crdgw1" $: "user" "<" "@" "crdgw1" ">"
  49.  
  50. Rule 3 can be given any address at all. It must determine the machine
  51. and domain which corresponds to the address. Determining the machine
  52. can be tricky, because it depends o the address. What it uses to
  53. specify the address is to surround the hostname and @ sign with angle brackets.
  54. It also added a imaginary domain to the hostname to indicate the type
  55. of network it is on. The set of angle brackets is used to "focus" on a machine.
  56.  
  57. Some typical values are:
  58.  
  59.     < @ machine . LOCAL >     => a local host
  60.     < @ machine >        => same as above
  61.     < @ machine . UUCP >    => a machine on the UUCP network
  62.  
  63. The angle brackets indicate the important part - the machine and
  64. perhaps what mail agent to use. However, the username isn't included
  65. in the set of charatcers surrounded by angle brackets. The problem is,
  66. different mailers have the username in a different format. In some
  67. casess, the host is the first word, in others it's the last word.
  68.  
  69. Here is an example of an address going into rule 3 and the expected
  70. output:
  71.  
  72.     Input        Output
  73.     a!b!c!d!user        <@a.UUCP>!b!c!d!user
  74.     user@a.uucp        user<@a.uucp>
  75.     bigvax::user        user<@bigvax.DECNET>
  76.     user%a.com@b.edu    user%a.com<@b.edu>    
  77.     a!b!user@abc.edu    a!b!user<@abc.edu>
  78.     @a:user@b.com        <@a>:user@b.com
  79.  
  80. As you can see, the machine that will accept the message will be
  81. different depending on the address. Ruleset 3 must find the right
  82. machine, and also clean up any addresses if appropriate.
  83. It does it's work by looking for a pattern, and transforming the
  84. address when it matches the pattern.
  85.  
  86. The cleaning up part can be confusing, but typically ruleset 3 calls
  87. other rules to do this. One rule is used to clean up addresses before
  88. the < and > are added. Another rule is used to clean up addresses
  89. after it has been converted into the < @ machine > format.
  90.  
  91. Here is the ease version of the rule that transforms a UUCP address:
  92.  
  93.     if ( exactly_one ! one_or_more )    /* uucphost!user */
  94.         return (RULESET_6 ($2<@$1."uucp">));
  95.  
  96. This transforms the address, but calls ruleset 6, which cleans up the
  97. addresses with < and >. The variables "exactly_one" and "one_or_more"
  98. match that number of tokens, and are replaced by the $1 or $2 on the 
  99. returned rule. ($1 is exactly_one, $2 is one_or_more).
  100.  
  101. Here is a rule in ruleset 6 that looks for an address to the local
  102. domain, and replaces the domain with "LOCAL":
  103.  
  104.     if ( zero_or_more <@ zero_or_more  any_in_mydomainname > zero_or_more )    /* convert local domain */
  105.         retry ($1<@$2"LOCAL">$4);
  106.  
  107. zero_or_more is a pattern, which matches $1, $2, or $4.
  108. any_in_mydomain is a special pattern that matches the domain. It is
  109. not necessary to have a $3 because the domain is known.
  110. So the test of the address user@crdgw1.crd reports this:
  111.  
  112. rewrite: ruleset  3   input: "user" "@" "crdgw1" "." "crd"
  113. rewrite: ruleset  6   input: "user" "<" "@" "crdgw1" "." "crd" ">"
  114. rewrite: ruleset  6 returns: "user" "<" "@" "crdgw1" "." "LOCAL" ">"
  115. rewrite: ruleset  3 returns: "user" "<" "@" "crdgw1" "." "LOCAL" ">"
  116.  
  117. Once ruleset 3 is down, it passes the address to 0.
  118. This eventually gets to the rule:
  119.  
  120. /* deliver to known ethernet hosts explicitly specified in our domain */
  121.     if ( zero_or_more <@ any_in_etc_hosts."LOCAL"> zero_or_more )    /* user@host.sun.com */
  122.         resolve (mailer (ether),
  123.                 host ($2 ),
  124.                 user ($1<@$2>$3));
  125.  
  126. This matches, so the ether mailer is used, and the address is
  127. $1<@2>$3, or in this case:
  128.  
  129.  
  130. rewrite: ruleset  0 returns: $# "ether" $@ "crdgw1" $: "user" "<" "@" "crdgw1" ">"
  131.  
  132. The $#, $@, and $: are sendmail talk for the mailer, machine, and
  133. address. 
  134.  
  135. Still more to come. The specificalion of the mailer is:
  136.  
  137. mailer
  138.     ether {
  139.         Path = "[TCP]",
  140.         Flags = { f_mult, f_strip, f_date, f_from, f_mesg, f_upperu, f_addrw, f_dot },
  141.         Sender = RULESET_11,
  142.         Recipient = RULESET_21,
  143.         Argv = "TCP ${m_rhost}"
  144.     };
  145.  
  146.  
  147. This says the sender's address must go thru rule 11, which means rules
  148. 1, 11, and 4. The recipient's address goes through 2, 21, and 4.
  149.  
  150. To test this, type the address from ruleset 0 and specify either 1,
  151. 11, and 4 or perhaps 2, 21, and 4:
  152.  
  153. > 1,11,4 user@crdgw1
  154. rewrite: ruleset  3   input: "user" "@" "crdgw1"
  155. rewrite: ruleset  6   input: "user" "<" "@" "crdgw1" ">"
  156. rewrite: ruleset  6 returns: "user" "<" "@" "crdgw1" ">"
  157. rewrite: ruleset  3 returns: "user" "<" "@" "crdgw1" ">"
  158. rewrite: ruleset  1   input: "user" "<" "@" "crdgw1" ">"
  159. rewrite: ruleset  1 returns: "user" "<" "@" "crdgw1" ">"
  160. rewrite: ruleset 11   input: "user" "<" "@" "crdgw1" ">"
  161. rewrite: ruleset 11 returns: "user" "<" "@" "crdgw1" ">"
  162. rewrite: ruleset  4   input: "user" "<" "@" "crdgw1" ">"
  163. rewrite: ruleset  9   input: "user" "<" "@" "crdgw1" ">"
  164. rewrite: ruleset  9 returns: "user" "<" "@" "crdgw1" ">"
  165. rewrite: ruleset  4 returns: "user" "@" "crdgw1"
  166.  
  167. As you can see, ruleset 3 is always applied first, which calls 6, 
  168. Then rule 1 is applied, followed by rule 11, and then followed by
  169. rule 4. The end result tells me the From: line would look like
  170. user@crdgw1
  171.  
  172.  
  173. The uucp mailer has a diffent set of rewrite rules.
  174. In sun's sendmail.main.cf, it uses 13 and 23. To test this address,
  175. I typed 1,13,4 and got this:
  176.  
  177. > 1,13,4 user@crdgw1
  178. rewrite: ruleset  3   input: "user" "@" "crdgw1"
  179. rewrite: ruleset  6   input: "user" "<" "@" "crdgw1" ">"
  180. rewrite: ruleset  6 returns: "user" "<" "@" "crdgw1" ">"
  181. rewrite: ruleset  3 returns: "user" "<" "@" "crdgw1" ">"
  182. rewrite: ruleset  1   input: "user" "<" "@" "crdgw1" ">"
  183. rewrite: ruleset  1 returns: "user" "<" "@" "crdgw1" ">"
  184. rewrite: ruleset 13   input: "user" "<" "@" "crdgw1" ">"
  185. rewrite: ruleset  5   input: "user" "<" "@" "crdgw1" ">"
  186. rewrite: ruleset  5 returns: "crdgw1" "!" "user"
  187. rewrite: ruleset 13 returns: "grymoire" "!" "crdgw1" "!" "user"
  188. rewrite: ruleset  4   input: "grymoire" "!" "crdgw1" "!" "user"
  189. rewrite: ruleset  9   input: "grymoire" "!" "crdgw1" "!" "user"
  190. rewrite: ruleset  9 returns: "grymoire" "!" "crdgw1" "!" "user"
  191. rewrite: ruleset  4 returns: "grymoire" "!" "crdgw1" "!" "user"
  192.  
  193. As you can see, it converted the address into a uucp path relative to
  194. my machine.
  195.  
  196. To test these three cases, add the following to your debug.in file:
  197.  
  198. 0    user@crdgw1
  199. 1,11,4    user@crdgw1    From_Ethernet_to_Ethernet
  200. 1,13,4    user@crdgw1    From_Ethernet_to_UUCP
  201.  
  202.