exim: Completely review the exim configuration.
[matthijs/servers/drsnuggles.git] / etc / exim4 / conf.d / router / 30_ldap
1 ### router/900_exim4-config_local_user
2 #################################
3
4 # These routers deal with mail meant for virtual_domains and real_domains.
5 # The targets for addresses in these domains and hosts are taken from
6 # the LDAP server.
7 #
8 # The first two routers check the LDAP directory to find an object to
9 # which the mail should be delivered. The first one works on
10 # virtual_domains, and finds an object based on the mail or
11 # alternateMailAddress attributes. For example, info@stdin.nl might be
12 # resolved by that one. The second one works on real_domains and finds an
13 # object based its uid (i.e., username). For example,
14 # matthijs@login.drsnuggles.stderr.nl might be resolved by the second
15 # router.
16 #
17 # The next set of routers works when a person is retrieved. They handle
18 # forwarding the mail to another mail server when the mailHost attribute
19 # is set but it is not us, forwarding the email to any
20 # mailForwardingAddresses in the object or delivering the mail locally
21 # when the mailHost is set. Note that both either or both of the last
22 # two routers can apply. If none of these three apply, routing continues
23 # to the last set. Local delivery works by redirecting to username@localhost
24 # and redirecting to the local_delivery router. This allows for a number of
25 # different routers (put after the local_delivery router) to handle the
26 # local_delivery. This is also the only way to get to any routers after the
27 # ones in this file!
28 #
29 # The last two routers work when a group is retrieved. They handle
30 # forwarding the mail to any members, both rfc822members (ie, addresses)
31 # and uniqueMembers (ie, other LDAP objects).
32 #
33 # Note that this distinction between persons and groups is not made by
34 # looking at the object classes, but at the attributes. Any object that
35 # has a mailHost and/or mailForwardingAddresses is treated as a person,
36 # meaning that only these two attributes are processed. Any object that
37 # has neither of these attributes is assumed to be a group and has its
38 # rfc822members and uniqueMembers processed. Any object that has none of
39 # these properties, will cause a delivery failure.
40 #
41 # Note also that only the first two routers have the domains
42 # precondition set, to differentiate between virtual_domains and
43 # real_domains. Assuming that the routers in this file will only be called for
44 # virtual_domains and real_domains, exactly one of these two routers will be
45 # called. If the lookup fails, the more option ensures that the rest of the
46 # routers are not called.
47 #
48 # The routers in this file assume that the url to LDAP server is defined
49 # as LDAPSERVER and the base dn is defined as LDAPBASE. No assumptions
50 # are made about the structure of the LDAP directory, so any object that
51 # has the mail or mailForwardingAddress attributes is considered a
52 # valid target for email, anywhere in the directory. These routers do
53 # assume that a single email address is listed only once. If not, mails
54 # to the address will be deferred.
55
56 LDAPURL=LDAPSERVER/LDAPBASE
57
58 # This router looks up an object in the ldap directory using its mail and
59 # alternateMailAddress attributes, for any domains in virtual_domains.
60 # This handles email addresses in "virtual" domains, since the object
61 # found does not need to actually have a username (it can even be a
62 # group).
63 ADDR=${quote_ldap:${local_part}@${domain}}
64 ldap_lookup_virtual:
65   debug_print = "R: ldap_lookup_virtual for $local_part@$domain: Finding person or group with (alternate) email address $local_part@$domain" 
66   driver = redirect
67   domains = +virtual_domains
68   address_data = ${lookup ldap {LDAPURL?uid,mailHost,mailForwardingAddress,rfc822member,uniqueMember?sub?(|(mail=ADDR)(mailAlternateAddress=ADDR))}{$value}fail}
69   # Noop, this router just needs to pass its preconditions, evaluate
70   # address_data and then pass control to ldap_person_other_mailhost below
71   data = ${local_part}@${domain}
72   redirect_router=ldap_person_other_mailhost
73   # If no objects are found and the address_data expansion is forced to fail,
74   # stop processing. Note that this setting does not apply when the domains
75   # precondition fails.
76   more = false
77   cannot_route_message = "Unknown address"
78
79 # This router looks up an object in the ldap directory using its uid
80 # (username) attribute, for any hosts in real_domains. This handles email
81 # addresses of actual users in this domain, i.e., objects that have uid
82 # property.
83 LOCALPART=${quote_ldap:${local_part}}
84 ldap_lookup_real:
85   debug_print = "R: ldap_lookup_real for $local_part@$domain: Finding user with uid $local_part"
86   driver = redirect
87   domains = +real_domains
88   address_data = ${lookup ldap {LDAPURL?uid,mailHost,mailForwardingAddress?sub?(uid=LOCALPART)}{$value}fail}
89   # Noop, this router just needs to pass its preconditions, evaluate
90   # address_data and then pass control to ldap_person_other_mailhost below
91   data = ${local_part}@${domain}
92   redirect_router=ldap_person_other_mailhost
93   # If no objects are found and the address_data expansion is forced to fail,
94   # stop processing. Note that this setting does not apply when the domains
95   # precondition fails.
96   more = false
97   cannot_route_message = "Unknown user"
98
99 # If the person has a mailhost configured, and it's not us, forward to
100 # that mailhost. If this router accepts, no others will be tried. This
101 # means we're also not processing any mailForwardingAddresses, assuming
102 # that the host forwarded to will do this.
103 #
104 # This entry is mostly future-compatible, since at the time of writing
105 # there are no other mailservers using the same LDAP directory. But it
106 # looks cool!
107 ldap_person_other_mailhost:
108   debug_print = "R: ldap_person_other_mailhost for $local_part@$domain: Forwarding to a mailHost if it is not us"
109   driver = manualroute
110   condition = ${if and { \
111     # If mailhost is not empty
112     {!eqi{${extract{mailHost}{$address_data}}}{}} \
113     # And mailhost is not this host
114     {!eqi{${extract{mailHost}{$address_data}}}{$primary_hostname}} \
115   }}
116   # Then, forward to the other mailHost
117   route_data = ${extract{mailHost}{$address_data}}
118   transport = remote_smtp
119
120 # Forward the mail to any mailForwardingAddresses configured
121 DELIVER_HERE=${if eqi{${extract{mailHost}{$address_data}}}{$primary_hostname}{true}{false}}
122 ldap_person_forward:
123   debug_print = "R: ldap_person_forward for $local_part@$domain: Forwarding to any mailForwardingAddresses"
124   driver = redirect
125   data = ${extract{mailForwardingAddress}{$address_data}}
126   # Pass the message to the ldap_person_local router as well, so we can support both
127   # local delivery and forwarding. However, only set unseen to yes if we know
128   # the ldap_person_local will accept it.  Just putting unseen = yes here doesn't
129   # work because if there is no local delivery, an error message is generated
130   # even when the email was forwarded succesfully.
131   unseen = DELIVER_HERE
132
133 # Deliver the mail locally if the mailHost points to us.
134 ldap_person_local:
135   debug_print = "R: ldap_person_local for $local_part@$domain: Doing local delivery if the mailHost is us"
136   driver = redirect
137   # Lookup if there is a user that has the target email address in either his
138   # mail attribute, or one of his mailAlternateAddresses and also has his
139   # mailstore on this host as its mailhost.
140   condition = DELIVER_HERE
141   # Forward the email to username@localhost. There is a separate set of routers
142   # that explicitly handles the localhost "domain", and has support for things
143   # like .forward files, procmail, etc.
144   data = ${extract{uid}{$address_data}}@localhost
145   redirect_router = local_delivery
146
147 # If any of the two above routers accepted the message, processing will
148 # stop here!
149
150 # Forward the mail to any full members (uniqueMember) configured
151 ldap_group_member:
152   debug_print = "R: ldap_group_member for $local_part@$domain: Forwarding to any uniqueMembers"
153   driver = redirect
154   # Lookup the mail address (if any) of each member. This gracefully ignores
155   # any members without an email address.
156   data = ${map \
157     # Since multipe attributes are separated by ", ", we replace ", " by "\n"
158     # and use that as a list separator (fortunately it's not just ",", as the
159     # documentation suggests, since then we would have had one big dn...)
160     {<\n ${sg \
161       {${extract{uniqueMember}{$address_data}}} \
162       {, } \
163       {\n} \
164     }} \
165     {${lookup ldap {LDAPSERVER/$item?mail?base?}}} \
166   }
167   # Pass the message to the ldap_group_address router as well, so we can support both
168   # addresses (rfc822member) and dns (uniqueMember) in a group.
169   # However, only set unseen to yes if we know the ldap_group_address will
170   # accept it.  Just putting unseen = yes here doesn't work because if there is
171   # no local delivery, an error message is generated even when the email was
172   # already forwarded succesfully.
173   unseen = ${if !eqi{${extract{rfc822member}{$address_data}}}{}{true}{false}}
174
175 # Forward the mail to any mail-only members (rfc822member) configured
176 ldap_group_address:
177   debug_print = "R: ldap_group_address for $local_part@$domain: Forwarding to any rfc822members"
178   driver = redirect
179   data = ${extract{rfc822member}{$address_data}}
180   cannot_route_message = "Recipient is not set up for mail reception"
181   # If this router did not match, stop processing.
182   more = false
183
184 # vim: set sts=2 expandtab sw=2 ai: