1 | divert(-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.cso.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 | |
---|
58 | ifdef(`_DOMAIN_MAP_',`',`dnl |
---|
59 | LOCAL_RULE_0 |
---|
60 | # do mapping for domains where applicable |
---|
61 | R$* $=O $* <@ $={MappedDomain} .> $@ $>Recurse $1 $2 $3 Strip extraneous routing |
---|
62 | R$+ <@ $={MappedDomain} .> $>DomainMapLookup $1 <@ $2 .> domain mapping |
---|
63 | |
---|
64 | LOCAL_RULESETS |
---|
65 | ########################################################################### |
---|
66 | ### Ruleset DomainMapLookup -- special rewriting for mapped domains ### |
---|
67 | ########################################################################### |
---|
68 | |
---|
69 | SDomainMapLookup |
---|
70 | R $=L <@ $=w .> $@ $1 <@ $2 .> weed out local users, in case |
---|
71 | # Cw contains a mapped domain |
---|
72 | R $+ <@ $+> $: $1 <@ $2 > <$&{addr_type}> check if sender |
---|
73 | R $+ <@ $+> <e s> $#smtp $@ $2 $: $1 @ $2 do not process sender |
---|
74 | ifdef(`DOMAINMAP_NO_REGEX',`dnl |
---|
75 | R $+ <@ $+> <$*> $: $1 <@ $2> <$2> find domain |
---|
76 | R $+ <$+> <$+ . $+> $1 <$2> < $(dequote $3 "_" $4 $) > |
---|
77 | # change "." to "_" |
---|
78 | R $+ <$+> <$+ .> $: $1 <$2> < $(dequote "domain_" $3 $) > |
---|
79 | # prepend "domain_" |
---|
80 | dnl',`dnl |
---|
81 | R $+ <@ $+> <$*> $: $1 <@ $2> <$2 :NOTDONE:> find domain |
---|
82 | R $+ <$+> <$+ . :NOTDONE:> $1 <$2> < $(domainmap_regex $3 $: $3 $) > |
---|
83 | # change "." and "-" to "_" |
---|
84 | R $+ <$+> <$+> $: $1 <$2> < $(dequote "domain_" $3 $) > |
---|
85 | # prepend "domain_" |
---|
86 | dnl') |
---|
87 | R $+ <$+> <$+> $: $1 <$2> <$3> $1 find user name |
---|
88 | R $+ <$+> <$+> $+ + $* $: $1 <$2> <$3> $4 handle user+detail syntax |
---|
89 | R $+ <$+> <$+> $+ $: $1 <$2> $( $3 $4 $: <ERROR> $) |
---|
90 | # do actual domain map lookup |
---|
91 | R $+ <$+> <ERROR> $#error $@ 5.1.1 $: "550 email address lookup in domain map failed" |
---|
92 | R $+ <@ $+> $* <TEMP> $* $#dsmtp $@ localhost $: $1 @ $2 |
---|
93 | # queue it up for later delivery |
---|
94 | R $+ + $* <$+> $+ @ $+ $: $1 + $2 <$3> $4 + $2 @ $5 |
---|
95 | # reset original user+detail |
---|
96 | R $+ <$+> $+ $@ $>Recurse $3 recanonify |
---|
97 | |
---|
98 | ifdef(`DOMAINMAP_NO_REGEX',`',`dnl |
---|
99 | LOCAL_CONFIG |
---|
100 | K domainmap_regex regex -a.:NOTDONE: -s1,2 -d_ (.*)[-\.]([^-\.]*)$ |
---|
101 | ')define(`_DOMAIN_MAP_',`1')') |
---|
102 | |
---|
103 | LOCAL_CONFIG |
---|
104 | C{MappedDomain} _ARG_ |
---|
105 | K `domain_'translit(_ARG_, `.-', `__') _ARG2_ -T<TEMP> |
---|