1 ### router/900_exim4-config_local_user
2 #################################
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
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
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
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).
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.
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.
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.
56 LDAPURL=LDAPSERVER/LDAPBASE
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
63 ADDR=${quote_ldap:${local_part}@${domain}}
65 debug_print = "R: ldap_lookup_virtual for $local_part@$domain: Finding person or group with (alternate) email address $local_part@$domain"
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
77 cannot_route_message = "Unknown address"
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
83 LOCALPART=${quote_ldap:${local_part}}
85 debug_print = "R: ldap_lookup_real for $local_part@$domain: Finding user with uid $local_part"
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
97 cannot_route_message = "Unknown user"
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.
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
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"
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}} \
116 # Then, forward to the other mailHost
117 route_data = ${extract{mailHost}{$address_data}}
118 transport = remote_smtp
120 # Forward the mail to any mailForwardingAddresses configured
121 DELIVER_HERE=${if eqi{${extract{mailHost}{$address_data}}}{$primary_hostname}{true}{false}}
123 debug_print = "R: ldap_person_forward for $local_part@$domain: Forwarding to any mailForwardingAddresses"
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
133 # Deliver the mail locally if the mailHost points to us.
135 debug_print = "R: ldap_person_local for $local_part@$domain: Doing local delivery if the mailHost is us"
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
147 # If any of the two above routers accepted the message, processing will
150 # Forward the mail to any full members (uniqueMember) configured
152 debug_print = "R: ldap_group_member for $local_part@$domain: Forwarding to any uniqueMembers"
154 # Lookup the mail address (if any) of each member. This gracefully ignores
155 # any members without an email address.
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...)
161 {${extract{uniqueMember}{$address_data}}} \
165 {${lookup ldap {LDAPSERVER/$item?mail?base?}}} \
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}}
175 # Forward the mail to any mail-only members (rfc822member) configured
177 debug_print = "R: ldap_group_address for $local_part@$domain: Forwarding to any rfc822members"
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.
184 # vim: set sts=2 expandtab sw=2 ai: