204 lines
7.7 KiB
Plaintext
204 lines
7.7 KiB
Plaintext
|
BUILDING WITH LDAP SUPPORT
|
||
|
==========================
|
||
|
|
||
|
You need to have LDAP libraries and include files installed somewhere on
|
||
|
your system, and you need to configure the Postfix Makefiles
|
||
|
accordingly.
|
||
|
|
||
|
If you're using the libraries from the UM distribution
|
||
|
(http://www.umich.edu/~dirsvcs/ldap/ldap.html) or OpenLDAP
|
||
|
(http://www.openldap.org), something like this should work:
|
||
|
|
||
|
% make tidy
|
||
|
% make makefiles CCARGS="-I/some/where/include -DHAS_LDAP" \
|
||
|
AUXLIBS="/some/where/libldap.a /some/where/liblber.a"
|
||
|
|
||
|
The `make tidy' command is needed only if you have previously built
|
||
|
Postfix without LDAP support.
|
||
|
|
||
|
If your LDAP libraries were built with Kerberos support, you'll also
|
||
|
need to include your Kerberos libraries in this line. Note that the KTH
|
||
|
Kerberos IV libraries might conflict with Postfix's lib/libdns.a, which
|
||
|
defines dns_lookup. If that happens, you'll probably want to link with
|
||
|
LDAP libraries that lack Kerberos support just to build Postfix, as it
|
||
|
doesn't yet support Kerberos binds to the LDAP server anyway. Sorry
|
||
|
about the bother.
|
||
|
|
||
|
If you're using one of the Netscape LDAP SDKs, you'll need to change the
|
||
|
AUXLIBS line to point to libldap10.so or libldapssl30.so or whatever you
|
||
|
have, and you may need to use the -R option so the executables can find
|
||
|
it at runtime.
|
||
|
|
||
|
USING LDAP LOOKUPS
|
||
|
==================
|
||
|
|
||
|
In order to use LDAP lookups, define at least one LDAP source as a table
|
||
|
lookup in main.cf, for example:
|
||
|
|
||
|
alias_maps = hash:/etc/aliases, ldap:ldapsource
|
||
|
|
||
|
Each LDAP source can have the following parameters, which should be
|
||
|
prefixed in main.cf with the name you've given the source in its
|
||
|
definition. To continue the example, the first parameter below,
|
||
|
"server_host", would be defined in main.cf as "ldapsource_server_host".
|
||
|
Defaults are given in parentheses:
|
||
|
|
||
|
server_host (localhost)
|
||
|
The name of the host running the LDAP server, e.g.
|
||
|
ldapsource_server_host = ldap.your.com
|
||
|
It should be possible with all the libraries mentioned above to
|
||
|
specify multiple servers separated by spaces, with the libraries
|
||
|
trying them in order should the first one fail.
|
||
|
|
||
|
server_port (389)
|
||
|
The port the LDAP server listens on, e.g.
|
||
|
ldapsource_server_port = 778
|
||
|
|
||
|
search_base (no default)
|
||
|
The base at which to conduct the search, e.g.
|
||
|
ldapsource_search_base = dc=your, dc=com
|
||
|
|
||
|
timeout (10 seconds)
|
||
|
The number of seconds a search can take before timing out, e.g.
|
||
|
ldapsource_timeout = 5
|
||
|
|
||
|
query_filter (mailacceptinggeneralid=%s)
|
||
|
The RFC2254 filter used to search the directory, where %s is a
|
||
|
substitute for the address Postfix is trying to resolve, e.g.
|
||
|
ldapsource_query_filter = (&(mail=%s)(paid_up=true))
|
||
|
|
||
|
result_attribute (maildrop)
|
||
|
The attribute Postfix will read from any directory entries
|
||
|
returned by the lookup, to be resolved to an email address.
|
||
|
ldapsource_result_attribute = mailbox
|
||
|
|
||
|
bind (yes)
|
||
|
Whether or not to bind to the LDAP server. Newer LDAP
|
||
|
implementations don't require clients to bind, which saves
|
||
|
time. Example:
|
||
|
ldapsource_bind = no
|
||
|
|
||
|
bind_dn ("")
|
||
|
If you do have to bind, do it with this distinguished name.
|
||
|
Example:
|
||
|
ldapsource_bind_dn = uid=postfix, dc=your, dc=com
|
||
|
|
||
|
bind_pw ("")
|
||
|
The password for the distinguished name above. If you have to
|
||
|
have this, you probably want to make main.cf readable only by
|
||
|
the Postfix user. Example:
|
||
|
ldapsource_bind_pw = postfixpw
|
||
|
|
||
|
Don't use quotes in these variables; at least, not until the Postfix
|
||
|
configuration routines understand how to deal with quoted strings.
|
||
|
|
||
|
EXAMPLE
|
||
|
=======
|
||
|
|
||
|
Here's a basic example. In main.cf, you have these configuration
|
||
|
parameters defined:
|
||
|
|
||
|
alias_maps = hash:/etc/aliases, ldap:ldapsource
|
||
|
ldapsource_server_host = ldap.my.com
|
||
|
ldapsource_search_base = dc=my, dc=com
|
||
|
|
||
|
Upon receiving mail for a local address "ldapuser" that isn't found in
|
||
|
the /etc/aliases database, Postfix will search the LDAP server listening
|
||
|
at port 389 on ldap.my.com. It will bind anonymously, search for any
|
||
|
directory entries whose mailacceptinggeneralid attribute is "ldapuser",
|
||
|
read the "maildrop" attributes of those found, and build a list of their
|
||
|
maildrops, which will be treated as RFC822 addresses to which the
|
||
|
message will be delivered.
|
||
|
|
||
|
NOTES AND THINGS TO THINK ABOUT
|
||
|
===============================
|
||
|
|
||
|
- You probably want to make sure that mailacceptinggeneralids are
|
||
|
unique, and that not just anyone can specify theirs as postmaster or
|
||
|
root, say.
|
||
|
|
||
|
- An entry can have an arbitrary number of maildrops. Maildrops can also
|
||
|
be comma-separated lists of addresses. For example, you could define
|
||
|
an entry intended for use as a mailing list that looks like this
|
||
|
(Warning! Schema made up just for this example):
|
||
|
|
||
|
dn: cn=Accounting Staff List, dc=my, dc=com
|
||
|
cn: Accounting Staff List
|
||
|
o: my.com
|
||
|
objectclass: maillist
|
||
|
mailacceptinggeneralid: accountingstaff
|
||
|
mailacceptinggeneralid: accounting-staff
|
||
|
maildrop: mylist-owner
|
||
|
maildrop: an-accountant
|
||
|
maildrop: some-other-accountant
|
||
|
maildrop: this, that, theother
|
||
|
|
||
|
- If you use an LDAP map for lookups other than aliases, you may have to
|
||
|
make sure the lookup makes sense. In the case of virtual lookups,
|
||
|
maildrops like "|/some/program" are pretty useless. Your query_filter
|
||
|
should probably look something like this:
|
||
|
|
||
|
virtual_query_filter =
|
||
|
(&(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*"))))
|
||
|
|
||
|
- And for that matter, you may not want users able to specify their
|
||
|
maildrops as programs, particularly if they'd be executed on the
|
||
|
server. A safer local query_filter could look something like:
|
||
|
|
||
|
local_query_filter = (&(mailacceptinggeneralid=%s)(|(!(maildrop="*|*"))(owner=cn=root, dc=your, dc=com)))
|
||
|
|
||
|
So that if the object had a program as its maildrop and weren't owned
|
||
|
by "cn=root" it wouldn't be returned as a valid local user. This will
|
||
|
probably require some thought on your part to implement safely,
|
||
|
considering the ramifications of includes and programs. You may decide
|
||
|
it's not worth the bother to allow any of that nonsense in LDAP
|
||
|
lookups, ban it in the query_filter, and keep things like majordomo
|
||
|
lists in local alias databases.
|
||
|
|
||
|
- It's not yet known how all this scales, but LDAP lookups are much more
|
||
|
expensive than checking a DB file. If you anticipate a lot of lookups,
|
||
|
it may pay to plan your directory to reduce the number of lookups. For
|
||
|
instance, rather than having a bunch of objects that serve as aliases
|
||
|
to just one object, you could simply add their mailacceptinggeneralids
|
||
|
to the target object. This:
|
||
|
|
||
|
dn: uid=firstlast, dc=your, dc=com
|
||
|
maildrop: firstlast@mailbox.your.com
|
||
|
mailacceptinggeneralid: firstlast
|
||
|
mailacceptinggeneralid: First.Last
|
||
|
mailacceptinggeneralid: F.Last
|
||
|
|
||
|
Not this:
|
||
|
|
||
|
dn: uid=firstlast, dc=your, dc=com
|
||
|
maildrop: firstlast@mailbox.your.com
|
||
|
mailacceptinggeneralid: firstlast
|
||
|
|
||
|
dn: cn=First.Last, dc=your, dc=com
|
||
|
maildrop: firstlast
|
||
|
mailacceptinggeneralid: First.Last
|
||
|
|
||
|
dn: cn=F.Last, dc=your, dc=com
|
||
|
maildrop: firstlast
|
||
|
mailacceptinggeneralid: F.Last
|
||
|
|
||
|
Any performance reports will be much appreciated on the postfix-users
|
||
|
list.
|
||
|
|
||
|
UPDATE: At Merit, I've seen over 150000 deliveries per day with no
|
||
|
noticeable delay from our OpenLDAP server. I'd now recommend not
|
||
|
resorting to the above unless you anticipate much more traffic than
|
||
|
that. It makes management of your directory less intuitive, which is
|
||
|
probably not worth the reduction in lookups.
|
||
|
|
||
|
CREDITS
|
||
|
=======
|
||
|
|
||
|
Support for LDAP was initially written by Prabhat K Singh of VSNL,
|
||
|
Bombay, India, and then hideously bloated by John Hensley to support
|
||
|
multiple sources and more configurable attributes. The caching bits were
|
||
|
initially worked out by Prabhat, then munged to support the multiple
|
||
|
sources. Other contributions have been submitted to move toward better
|
||
|
support of Netscape/LDAPv3 libraries, and any other improvements are of
|
||
|
course welcome.
|