1
<!doctype html public "-//W3C//DTD HTML 4.01 Transitional//EN"
2
"http://www.w3.org/TR/html4/loose.dtd">
8
<title>Postfix LDAP Howto</title>
10
<meta http-equiv="Content-Type" content="text/html; charset=us-ascii">
16
<h1><img src="postfix-logo.jpg" width="203" height="98" ALT="">Postfix LDAP Howto</h1>
20
<h2>LDAP Support in Postfix</h2>
22
<p> Postfix can use an LDAP directory as a source for any of its
23
lookups: aliases(5), virtual(5), canonical(5), etc. This allows
24
you to keep information for your mail service in a replicated
25
network database with fine-grained access controls. By not storing
26
it locally on the mail server, the administrators can maintain it
27
from anywhere, and the users can control whatever bits of it you
28
think appropriate. You can have multiple mail servers using the
29
same information, without the hassle and delay of having to copy
32
<p> Topics covered in this document:</p>
36
<li><a href="#build">Building Postfix with LDAP support</a>
38
<li><a href="#config">Configuring LDAP lookups</a>
40
<li><a href="#example_alias">Example: aliases</a>
42
<li><a href="#example_virtual">Example: virtual domains/addresses</a>
44
<li><a href="#other">Other uses of LDAP lookups</a>
46
<li><a href="#hmmmm">Notes and things to think about</a>
48
<li><a href="#feedback">Feedback</a>
50
<li><a href="#credits">Credits</a>
54
<h2><a name="build">Building Postfix with LDAP support</a></h2>
56
<p> Note 1: Postfix no longer supports the LDAP version 1 interface.
59
<p> Note 2: to use LDAP with Debian GNU/Linux's Postfix, all you
60
need is to install the postfix-ldap package and you're done. There
61
is no need to recompile Postfix. </p>
63
<p> You need to have LDAP libraries and include files installed
64
somewhere on your system, and you need to configure the Postfix
65
Makefiles accordingly. </p>
67
<p> For example, to build the OpenLDAP libraries for use with
68
Postfix (i.e. LDAP client code only), you could use the following
73
% ./configure --without-kerberos --without-cyrus-sasl --without-tls \
74
--without-threads --disable-slapd --disable-slurpd \
75
--disable-debug --disable-shared
79
<p> If you're using the libraries from the UM distribution
80
(http://www.umich.edu/~dirsvcs/ldap/ldap.html) or OpenLDAP
81
(http://www.openldap.org), something like this in the top level of
82
your Postfix source tree should work: </p>
87
% make makefiles CCARGS="-I/usr/local/include -DHAS_LDAP" \
88
AUXLIBS="-L/usr/local/lib -lldap -L/usr/local/lib -llber"
92
<p> On Solaris 2.x you may have to specify run-time link information,
93
otherwise ld.so will not find some of the shared libraries: </p>
98
% make makefiles CCARGS="-I/usr/local/include -DHAS_LDAP" \
99
AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lldap \
100
-L/usr/local/lib -R/usr/local/lib -llber"
104
<p> The 'make tidy' command is needed only if you have previously
105
built Postfix without LDAP support. </p>
107
<p> Instead of '/usr/local' specify the actual locations of your
108
LDAP include files and libraries. Be sure to not mix LDAP include
109
files and LDAP libraries of different versions!! </p>
111
<p> If your LDAP libraries were built with Kerberos support, you'll
112
also need to include your Kerberos libraries in this line. Note
113
that the KTH Kerberos IV libraries might conflict with Postfix's
114
lib/libdns.a, which defines dns_lookup. If that happens, you'll
115
probably want to link with LDAP libraries that lack Kerberos support
116
just to build Postfix, as it doesn't support Kerberos binds to the
117
LDAP server anyway. Sorry about the bother. </p>
119
<p> If you're using one of the Netscape LDAP SDKs, you'll need to
120
change the AUXLIBS line to point to libldap10.so or libldapssl30.so
121
or whatever you have, and you may need to use the appropriate linker
122
option (e.g. '-R') so the executables can find it at runtime. </p>
124
<h2><a name="config">Configuring LDAP lookups</a></h2>
126
<p> In order to use LDAP lookups, define an LDAP source
127
as a table lookup in main.cf, for example: </p>
131
alias_maps = hash:/etc/aliases, ldap:/etc/postfix/ldap-aliases.cf
135
<p> The file /etc/postfix/ldap-aliases.cf can specify a great number
136
of parameters, including parameters that enable LDAP SSL and
137
STARTTLS. For a complete description, see the ldap_table(5) manual
140
<h2><a name="example_alias">Example: local(8) aliases</a></h2>
142
<p> Here's a basic example for using LDAP to look up local(8)
143
aliases. Assume that in main.cf, you have: </p>
147
alias_maps = hash:/etc/aliases, ldap:/etc/postfix/ldap-aliases.cf
151
<p> and in ldap:/etc/postfix/ldap-aliases.cf you have: </p>
155
server_host = ldap.my.com
156
search_base = dc=my, dc=com
160
<p> Upon receiving mail for a local address "ldapuser" that isn't
161
found in the /etc/aliases database, Postfix will search the LDAP
162
server listening at port 389 on ldap.my.com. It will bind anonymously,
163
search for any directory entries whose mailacceptinggeneralid
164
attribute is "ldapuser", read the "maildrop" attributes of those
165
found, and build a list of their maildrops, which will be treated
166
as RFC822 addresses to which the message will be delivered. </p>
168
<h2><a name="example_virtual">Example: virtual domains/addresses</a></h2>
170
<p> If you want to keep information for virtual lookups in your
171
directory, it's only a little more complicated. First, you need to
172
make sure Postfix knows about the virtual domain. An easy way to
173
do that is to add the domain to the mailacceptinggeneralid attribute
174
of some entry in the directory. Next, you'll want to make sure all
175
of your virtual recipient's mailacceptinggeneralid attributes are
176
fully qualified with their virtual domains. Finally, if you want
177
to designate a directory entry as the default user for a virtual
178
domain, just give it an additional mailacceptinggeneralid (or the
179
equivalent in your directory) of "@virtual.dom". That's right, no
180
user part. If you don't want a catchall user, omit this step and
181
mail to unknown users in the domain will simply bounce. </p>
183
<p> In summary, you might have a catchall user for a virtual domain
184
that looks like this: </p>
188
dn: cn=defaultrecipient, dc=fake, dc=dom
190
objectclass: virtualaccount
192
owner: uid=root, dc=someserver, dc=isp, dc=dom
193
1 -> mailacceptinggeneralid: fake.dom
194
2 -> mailacceptinggeneralid: @fake.dom
195
3 -> maildrop: realuser@real.dom
201
<dd> <p> 1: Postfix knows fake.dom is a valid virtual domain when
202
it looks for this and gets something (the maildrop) back. </p>
204
<dd> <p> 2: This causes any mail for unknown users in fake.dom to
205
go to this entry ... </p>
207
<dd> <p> 3: ... and then to its maildrop. </p>
211
<p> Normal users might simply have one mailacceptinggeneralid and
212
maildrop, e.g. "normaluser@fake.dom" and "normaluser@real.dom".
215
<h2><a name="other">Other uses of LDAP lookups</a></h2>
217
Other common uses for LDAP lookups include rewriting senders and
218
recipients with Postfix's canonical lookups, for example in order
219
to make mail leaving your site appear to be coming from
220
"First.Last@site.dom" instead of "userid@site.dom".
222
<h2><a name="hmmmm">Notes and things to think about</a></h2>
226
<li> <p> The bits of schema and attribute names used in this document are just
227
examples. There's nothing special about them, other than that some are
228
the defaults in the LDAP configuration parameters. You can use
229
whatever schema you like, and configure Postfix accordingly. </p>
231
<li> <p> You probably want to make sure that mailacceptinggeneralids are
232
unique, and that not just anyone can specify theirs as postmaster or
235
<li> <p> An entry can have an arbitrary number of mailacceptinggeneralids or
236
maildrops. Maildrops can also be comma-separated lists of addresses.
237
They will all be found and returned by the lookups. For example, you
238
could define an entry intended for use as a mailing list that looks
239
like this (Warning! Schema made up just for this example): </p>
243
dn: cn=Accounting Staff List, dc=my, dc=com
244
cn: Accounting Staff List
246
objectclass: maillist
247
mailacceptinggeneralid: accountingstaff
248
mailacceptinggeneralid: accounting-staff
249
maildrop: mylist-owner
250
maildrop: an-accountant
251
maildrop: some-other-accountant
252
maildrop: this, that, theother
256
<li> <p> If you use an LDAP map for lookups other than aliases, you may have to
257
make sure the lookup makes sense. In the case of virtual lookups,
258
maildrops other than mail addresses are pretty useless, because
259
Postfix can't know how to set the ownership for program or file
260
delivery. Your query_filter should probably look something like this: </p>
264
query_filter = (&(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))))
268
<li> <p> And for that matter, even for aliases, you may not want users able to
269
specify their maildrops as programs, includes, etc. This might be
270
particularly pertinent on a "sealed" server where they don't have
271
local UNIX accounts, but exist only in LDAP and Cyrus. You might allow
272
the fun stuff only for directory entries owned by an administrative
274
so that if the object had a program as its maildrop and weren't owned
275
by "cn=root" it wouldn't be returned as a valid local user. This will
276
require some thought on your part to implement safely, considering the
277
ramifications of this type of delivery. You may decide it's not worth
278
the bother to allow any of that nonsense in LDAP lookups, ban it in
279
the query_filter, and keep things like majordomo lists in local alias
284
query_filter = (&(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))(owner=cn=root, dc=your, dc=com)))
288
<li> <p> LDAP lookups are slower than local DB or DBM lookups. For most sites
289
they won't be a bottleneck, but it's a good idea to know how to tune
290
your directory service. </p>
292
<li> <p> Multiple LDAP maps share the same LDAP connection if they differ
293
only in their query related parameters: base, scope, query_filter, and
294
so on. To take advantage of this, avoid spurious differences in the
295
definitions of LDAP maps: host selection order, version, bind, tls
296
parameters, ... should be the same for multiple maps whenever possible. </p>
300
<h2><a name="feedback">Feedback</a></h2>
302
<p> If you have questions, send them to postfix-users@postfix.org. Please
303
include relevant information about your Postfix setup: LDAP-related
304
output from postconf, which LDAP libraries you built with, and which
305
directory server you're using. If your question involves your directory
306
contents, please include the applicable bits of some directory entries. </p>
308
<h2><a name="credits">Credits</a></h2>
312
<li>Manuel Guesdon: Spotted a bug with the timeout attribute.
314
<li>John Hensley: Multiple LDAP sources with more configurable attributes.
316
<li>Carsten Hoeger: Search scope handling.
318
<li>LaMont Jones: Domain restriction, URL and DN searches, multiple result
321
<li>Mike Mattice: Alias dereferencing control.
323
<li>Hery Rakotoarisoa: Patches for LDAPv3 updating.
325
<li>Prabhat K Singh: Wrote the initial Postfix LDAP lookups and connection caching.
327
<li>Keith Stevenson: RFC 2254 escaping in queries.
329
<li>Samuel Tardieu: Noticed that searches could include wildcards, prompting
330
the work on RFC 2254 escaping in queries. Spotted a bug
333
<li>Sami Haahtinen: Referral chasing and v3 support.
335
<li>Victor Duchovni: ldap_bind() timeout. With fixes from LaMont Jones:
336
OpenLDAP cache deprecation. Limits on recursion, expansion
337
and query results size. LDAP connection sharing for maps
338
differing only in the query parameters.
340
<li>Liviu Daia: Support for SSL/STARTTLS. Support for storing map definitions in
341
external files (ldap:/path/ldap.cf) needed to securely store
342
passwords for plain auth.
346
And of course Wietse.