1divert(-1)changequote(<<, >>)<<
2-----------------------------------------------------------------------------
3
4                     FEATURE(domainmap) Macro
5                                       
6   The existing virtusertable feature distributed with sendmail is a good
7   basic approach to virtual hosting, but it is missing a few key
8   features:
9
10    1. Ability to have a different map for each domain.
11    2. Ability to perform virtual hosting for domains which are not in $=w.
12    3. Ability to use a centralized network-accessible database (such as
13       PH) which is keyed on username alone (as opposed to the
14       fully-qualified email address).
15
16   The FEATURE(domainmap) macro neatly solves these problems.
17   
18   The basic syntax of the macro is:
19        FEATURE(domainmap, `domain.com', `map definition ...')dnl
20
21   To illustrate how it works, here is an example:
22        FEATURE(domainmap, `foo.com', `dbm -o /etc/mail/foo-users')dnl
23
24   In this example, mail sent to user@foo.com will be rewritten by the
25   domainmap. The username will be looked up in the DBM map
26   /etc/mail/foo-users, which looks like this:
27        jsmith  johnsmith@mailbox.foo.com
28        jdoe    janedoe@sandbox.bar.com
29
30   So mail sent to jsmith@foo.com will be relayed to
31   johnsmith@mailbox.foo.com, and mail sent to jdoe@foo.com will be
32   relayed to janedoe@sandbox.bar.com.
33   
34   The FEATURE(domainmap) Macro supports the user+detail syntax by
35   stripping off the +detail portion before the domainmap lookup and
36   tacking it back on to the result. Using the example above, mail sent
37   to jsmith+sometext@foo.com will be rewritten as
38   johnsmith+sometext@mailbox.foo.com.
39   
40   If one of the elements in the $=w class (i.e., "local" delivery hosts)
41   is a domain specified in a FEATURE(domainmap) entry, you need to use
42   the LOCAL_USER(username) macro to specify the list of users for whom
43   domainmap lookups should not be done.
44
45   To use this macro, simply copy this file into the cf/feature directory
46   in the sendmail source tree.  For more information, please see the
47   following URL:
48
49      http://www-dev.cites.uiuc.edu/sendmail/domainmap/
50
51   Feedback is welcome.
52
53                                             Mark D. Roth <roth@uiuc.edu>
54
55-----------------------------------------------------------------------------
56>>changequote(`, ')undivert(-1)divert
57
58ifdef(`_DOMAIN_MAP_',`',`dnl
59LOCAL_RULE_0
60# do mapping for domains where applicable
61R$* $=O $* <@ $={MappedDomain} .>	$@ $>Recurse $1 $2 $3	Strip extraneous routing
62R$+ <@ $={MappedDomain} .>		$>DomainMapLookup $1 <@ $2 .>	domain mapping
63
64LOCAL_RULESETS
65###########################################################################
66###   Ruleset DomainMapLookup -- special rewriting for mapped domains   ###
67###########################################################################
68
69SDomainMapLookup
70R $=L <@ $=w .>		$@ $1 <@ $2 .>		weed out local users, in case
71#						Cw contains a mapped domain
72R $+ <@ $+>		$: $1 <@ $2 > <$&{addr_type}>	check if sender
73R $+ <@ $+> <e s>	$#smtp $@ $2 $: $1 @ $2		do not process sender
74ifdef(`DOMAINMAP_NO_REGEX',`dnl
75R $+ <@ $+> <$*>	$: $1 <@ $2> <$2>	find domain
76R $+ <$+> <$+ . $+>	$1 <$2> < $(dequote $3 "_" $4 $) >
77#						change "." to "_"
78R $+ <$+> <$+ .>	$: $1 <$2> < $(dequote "domain_" $3 $) >
79#						prepend "domain_"
80dnl',`dnl
81R $+ <@ $+> <$*>	$: $1 <@ $2> <$2 :NOTDONE:>	find domain
82R $+ <$+> <$+ . :NOTDONE:>	$1 <$2> < $(domainmap_regex $3 $: $3 $) >
83#						change "." and "-" to "_"
84R $+ <$+> <$+>		$: $1 <$2> < $(dequote "domain_" $3 $) >
85#						prepend "domain_"
86dnl')
87R $+ <$+> <$+>		$: $1 <$2> <$3> $1	find user name
88R $+ <$+> <$+> $+ + $*	$: $1 <$2> <$3> $4	handle user+detail syntax
89R $+ <$+> <$+> $+	$: $1 <$2> $( $3 $4 $: <ERROR> $)
90#						do actual domain map lookup
91R $+ <$+> <ERROR>	$#error $@ 5.1.1 $: "550 email address lookup in domain map failed"
92R $+ <@ $+> $* <TEMP> $*	$#dsmtp $@ localhost $: $1 @ $2
93#						queue it up for later delivery
94R $+ + $* <$+> $+ @ $+		$: $1 + $2 <$3> $4 + $2 @ $5
95#						reset original user+detail
96R $+ <$+> $+		$@ $>Recurse $3		recanonify
97
98ifdef(`DOMAINMAP_NO_REGEX',`',`dnl
99LOCAL_CONFIG
100K domainmap_regex regex -a.:NOTDONE: -s1,2 -d_ (.*)[-\.]([^-\.]*)$
101')define(`_DOMAIN_MAP_',`1')')
102
103LOCAL_CONFIG
104C{MappedDomain} _ARG_
105K `domain_'translit(_ARG_, `.-', `__') _ARG2_ -T<TEMP>
106