home *** CD-ROM | disk | FTP | other *** search
- An introduction to Sendmail Rules
- Copyright 1991, All rights reserved
- Bruce Barnett
-
- First of all, sendmail is easy to learn, once you learned all
- about electronic mail. Figuring out how to handle the address
-
- bigvax::a!b!another.domain!c%d%domain.com@another.domain
-
- is much more challenging. Here's the scoop.
-
- When sendmail gets a, address, it always passes it to rule 3.
-
- Rule 3 with transform the address, and eventually sent it to
- rule 0.
-
- Rule 0 makes the final decision, and selects three things:
-
- The address
- The Machine to send the address to
- The mailer to use.
- This could be UUCP, ethernet, DECNet,
- a local user, a program, etc.
-
- Once the above has been decided on, the address is transformed
- in the following way:
-
- Ruleset 1 is applied to the From: line
- Ruleset 2 is applied to the To: and Cc: line
-
- Each mailer then applies a rule. These rules are other unique
- for each mailer.
-
- Finally ruleset 4 is applied.
-
-
- Now let's go through an example in detail.
-
- grymoire% /usr/lib/sendmail -bt -C/etc/sendmail.cf
- ADDRESS TEST MODE
- Enter <ruleset> <address>
- > 0 user@crdgw1.crd # <---- I typed this line here
- rewrite: ruleset 3 input: "user" "@" "crdgw1" "." "crd"
- rewrite: ruleset 6 input: "user" "<" "@" "crdgw1" "." "crd" ">"
- rewrite: ruleset 6 returns: "user" "<" "@" "crdgw1" "." "LOCAL" ">"
- rewrite: ruleset 3 returns: "user" "<" "@" "crdgw1" "." "LOCAL" ">"
- rewrite: ruleset 0 input: "user" "<" "@" "crdgw1" "." "LOCAL" ">"
- rewrite: ruleset 0 returns: $# "ether" $@ "crdgw1" $: "user" "<" "@" "crdgw1" ">"
- >
-
- Rule 3 can be given any address at all. It must determine the machine
- and domain which corresponds to the address. Determining the machine
- can be tricky, because it depends o the address. What it uses to
- specify the address is to surround the hostname and @ sign with angle brackets.
- It also added a imaginary domain to the hostname to indicate the type
- of network it is on. The set of angle brackets is used to "focus" on a machine.
-
- Some typical values are:
-
- < @ machine . LOCAL > => a local host
- < @ machine > => same as above
- < @ machine . UUCP > => a machine on the UUCP network
-
- The angle brackets indicate the important part - the machine and
- perhaps what mail agent to use. However, the username isn't included
- in the set of charatcers surrounded by angle brackets. The problem is,
- different mailers have the username in a different format. In some
- casess, the host is the first word, in others it's the last word.
-
- Here is an example of an address going into rule 3 and the expected
- output:
-
- Input Output
- a!b!c!d!user <@a.UUCP>!b!c!d!user
- user@a.uucp user<@a.uucp>
- bigvax::user user<@bigvax.DECNET>
- user%a.com@b.edu user%a.com<@b.edu>
- a!b!user@abc.edu a!b!user<@abc.edu>
- @a:user@b.com <@a>:user@b.com
-
- As you can see, the machine that will accept the message will be
- different depending on the address. Ruleset 3 must find the right
- machine, and also clean up any addresses if appropriate.
- It does it's work by looking for a pattern, and transforming the
- address when it matches the pattern.
-
- The cleaning up part can be confusing, but typically ruleset 3 calls
- other rules to do this. One rule is used to clean up addresses before
- the < and > are added. Another rule is used to clean up addresses
- after it has been converted into the < @ machine > format.
-
- Here is the ease version of the rule that transforms a UUCP address:
-
- if ( exactly_one ! one_or_more ) /* uucphost!user */
- return (RULESET_6 ($2<@$1."uucp">));
-
- This transforms the address, but calls ruleset 6, which cleans up the
- addresses with < and >. The variables "exactly_one" and "one_or_more"
- match that number of tokens, and are replaced by the $1 or $2 on the
- returned rule. ($1 is exactly_one, $2 is one_or_more).
-
- Here is a rule in ruleset 6 that looks for an address to the local
- domain, and replaces the domain with "LOCAL":
-
- if ( zero_or_more <@ zero_or_more any_in_mydomainname > zero_or_more ) /* convert local domain */
- retry ($1<@$2"LOCAL">$4);
-
- zero_or_more is a pattern, which matches $1, $2, or $4.
- any_in_mydomain is a special pattern that matches the domain. It is
- not necessary to have a $3 because the domain is known.
- So the test of the address user@crdgw1.crd reports this:
-
- rewrite: ruleset 3 input: "user" "@" "crdgw1" "." "crd"
- rewrite: ruleset 6 input: "user" "<" "@" "crdgw1" "." "crd" ">"
- rewrite: ruleset 6 returns: "user" "<" "@" "crdgw1" "." "LOCAL" ">"
- rewrite: ruleset 3 returns: "user" "<" "@" "crdgw1" "." "LOCAL" ">"
-
- Once ruleset 3 is down, it passes the address to 0.
- This eventually gets to the rule:
-
- /* deliver to known ethernet hosts explicitly specified in our domain */
- if ( zero_or_more <@ any_in_etc_hosts."LOCAL"> zero_or_more ) /* user@host.sun.com */
- resolve (mailer (ether),
- host ($2 ),
- user ($1<@$2>$3));
-
- This matches, so the ether mailer is used, and the address is
- $1<@2>$3, or in this case:
-
-
- rewrite: ruleset 0 returns: $# "ether" $@ "crdgw1" $: "user" "<" "@" "crdgw1" ">"
-
- The $#, $@, and $: are sendmail talk for the mailer, machine, and
- address.
-
- Still more to come. The specificalion of the mailer is:
-
- mailer
- ether {
- Path = "[TCP]",
- Flags = { f_mult, f_strip, f_date, f_from, f_mesg, f_upperu, f_addrw, f_dot },
- Sender = RULESET_11,
- Recipient = RULESET_21,
- Argv = "TCP ${m_rhost}"
- };
-
-
- This says the sender's address must go thru rule 11, which means rules
- 1, 11, and 4. The recipient's address goes through 2, 21, and 4.
-
- To test this, type the address from ruleset 0 and specify either 1,
- 11, and 4 or perhaps 2, 21, and 4:
-
- > 1,11,4 user@crdgw1
- rewrite: ruleset 3 input: "user" "@" "crdgw1"
- rewrite: ruleset 6 input: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 6 returns: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 3 returns: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 1 input: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 1 returns: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 11 input: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 11 returns: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 4 input: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 9 input: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 9 returns: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 4 returns: "user" "@" "crdgw1"
-
- As you can see, ruleset 3 is always applied first, which calls 6,
- Then rule 1 is applied, followed by rule 11, and then followed by
- rule 4. The end result tells me the From: line would look like
- user@crdgw1
-
-
- The uucp mailer has a diffent set of rewrite rules.
- In sun's sendmail.main.cf, it uses 13 and 23. To test this address,
- I typed 1,13,4 and got this:
-
- > 1,13,4 user@crdgw1
- rewrite: ruleset 3 input: "user" "@" "crdgw1"
- rewrite: ruleset 6 input: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 6 returns: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 3 returns: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 1 input: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 1 returns: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 13 input: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 5 input: "user" "<" "@" "crdgw1" ">"
- rewrite: ruleset 5 returns: "crdgw1" "!" "user"
- rewrite: ruleset 13 returns: "grymoire" "!" "crdgw1" "!" "user"
- rewrite: ruleset 4 input: "grymoire" "!" "crdgw1" "!" "user"
- rewrite: ruleset 9 input: "grymoire" "!" "crdgw1" "!" "user"
- rewrite: ruleset 9 returns: "grymoire" "!" "crdgw1" "!" "user"
- rewrite: ruleset 4 returns: "grymoire" "!" "crdgw1" "!" "user"
- >
-
- As you can see, it converted the address into a uucp path relative to
- my machine.
-
- To test these three cases, add the following to your debug.in file:
-
- 0 user@crdgw1
- 1,11,4 user@crdgw1 From_Ethernet_to_Ethernet
- 1,13,4 user@crdgw1 From_Ethernet_to_UUCP
-
-