head 1.2; access; symbols perseant-exfatfs-base-20250801:1.2 perseant-exfatfs-base-20240630:1.2 cjep_sun2x:1.2.0.44 cjep_sun2x-base:1.2 cjep_staticlib_x-base1:1.2 cjep_staticlib_x:1.2.0.42 cjep_staticlib_x-base:1.2 phil-wifi-20200421:1.2 phil-wifi-20200411:1.2 phil-wifi-20200406:1.2 pgoyette-compat-merge-20190127:1.2 pgoyette-compat-20190127:1.2 pgoyette-compat-20190118:1.2 pgoyette-compat-1226:1.2 pgoyette-compat-1126:1.2 pgoyette-compat-1020:1.2 pgoyette-compat-0930:1.2 pgoyette-compat-0906:1.2 pgoyette-compat-0728:1.2 pgoyette-compat-0625:1.2 pgoyette-compat-0521:1.2 pgoyette-compat-0502:1.2 pgoyette-compat-0422:1.2 pgoyette-compat-0415:1.2 pgoyette-compat-0407:1.2 pgoyette-compat-0330:1.2 pgoyette-compat-0322:1.2 pgoyette-compat-0315:1.2 pgoyette-compat:1.2.0.40 pgoyette-compat-base:1.2 perseant-stdc-iso10646:1.2.0.38 perseant-stdc-iso10646-base:1.2 prg-localcount2-base3:1.2 prg-localcount2-base2:1.2 prg-localcount2-base1:1.2 prg-localcount2:1.2.0.36 prg-localcount2-base:1.2 pgoyette-localcount-20170426:1.2 bouyer-socketcan-base1:1.2 pgoyette-localcount-20170320:1.2 bouyer-socketcan:1.2.0.34 bouyer-socketcan-base:1.2 pgoyette-localcount-20170107:1.2 pgoyette-localcount-20161104:1.2 localcount-20160914:1.2 pgoyette-localcount-20160806:1.2 pgoyette-localcount-20160726:1.2 pgoyette-localcount:1.2.0.32 pgoyette-localcount-base:1.2 netbsd-5-2-3-RELEASE:1.2 netbsd-5-1-5-RELEASE:1.2 yamt-pagecache-base9:1.2 yamt-pagecache-tag8:1.2 tls-earlyentropy:1.2.0.28 tls-earlyentropy-base:1.2 riastradh-xf86-video-intel-2-7-1-pre-2-21-15:1.2 riastradh-drm2-base3:1.2 netbsd-5-2-2-RELEASE:1.2 netbsd-5-1-4-RELEASE:1.2 netbsd-5-2-1-RELEASE:1.2 netbsd-5-1-3-RELEASE:1.2 agc-symver:1.2.0.30 agc-symver-base:1.2 tls-maxphys-base:1.2 yamt-pagecache-base8:1.2 netbsd-5-2:1.2.0.26 yamt-pagecache-base7:1.2 netbsd-5-2-RELEASE:1.2 netbsd-5-2-RC1:1.2 yamt-pagecache-base6:1.2 yamt-pagecache-base5:1.2 yamt-pagecache-base4:1.2 netbsd-5-1-2-RELEASE:1.2 netbsd-5-1-1-RELEASE:1.2 yamt-pagecache-base3:1.2 yamt-pagecache-base2:1.2 yamt-pagecache:1.2.0.24 yamt-pagecache-base:1.2 bouyer-quota2-nbase:1.2 bouyer-quota2:1.2.0.22 bouyer-quota2-base:1.2 matt-nb5-pq3:1.2.0.20 matt-nb5-pq3-base:1.2 netbsd-5-1:1.2.0.18 netbsd-5-1-RELEASE:1.2 netbsd-5-1-RC4:1.2 netbsd-5-1-RC3:1.2 netbsd-5-1-RC2:1.2 netbsd-5-1-RC1:1.2 netbsd-5-0-2-RELEASE:1.2 netbsd-5-0-1-RELEASE:1.2 jym-xensuspend-nbase:1.2 netbsd-5-0:1.2.0.16 netbsd-5-0-RELEASE:1.2 netbsd-5-0-RC4:1.2 netbsd-5-0-RC3:1.2 netbsd-5-0-RC2:1.2 jym-xensuspend:1.2.0.14 jym-xensuspend-base:1.2 netbsd-5-0-RC1:1.2 netbsd-5:1.2.0.12 netbsd-5-base:1.2 mjf-devfs2:1.2.0.10 mjf-devfs2-base:1.2 yamt-pf42-base4:1.2 yamt-pf42-base3:1.2 hpcarm-cleanup-nbase:1.2 yamt-pf42-base2:1.2 yamt-pf42:1.2.0.8 yamt-pf42-base:1.2 keiichi-mipv6:1.2.0.6 keiichi-mipv6-base:1.2 cube-autoconf:1.2.0.4 cube-autoconf-base:1.2 hpcarm-cleanup:1.2.0.2 hpcarm-cleanup-base:1.2 netbsd-1-5-PATCH003:1.1.1.1 PFIX-20010228-pl08:1.1.1.2 netbsd-1-5-PATCH002:1.1.1.1 PFIX-20010228-pl04:1.1.1.2 netbsd-1-5-PATCH001:1.1.1.1 PFIX-20010228-pl03:1.1.1.2 PFIX-20010228-pl02:1.1.1.2 PFIX-20010228-pl01:1.1.1.2 PFIX-20010228:1.1.1.2 PFIX-19991231-pl12:1.1.1.1 netbsd-1-5-RELEASE:1.1.1.1 netbsd-1-5-BETA2:1.1.1.1 netbsd-1-5-BETA:1.1.1.1 netbsd-1-5-ALPHA2:1.1.1.1 netbsd-1-5:1.1.1.1.0.2 netbsd-1-5-base:1.1.1.1 PFIX-19991231-pl08:1.1.1.1 PFIX-19991231-pl07:1.1.1.1 PFIX-19991231-pl06:1.1.1.1 VENEMA:1.1.1; locks; strict; comment @# @; 1.2 date 2002.02.02.23.27.35; author perry; state dead; branches; next 1.1; 1.1 date 2000.04.30.18.52.26; author perry; state Exp; branches 1.1.1.1; next ; 1.1.1.1 date 2000.04.30.18.52.26; author perry; state Exp; branches; next 1.1.1.2; 1.1.1.2 date 2001.03.13.17.45.19; author itojun; state Exp; branches; next ; desc @@ 1.2 log @not part of release 1.1.2 @ text @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. @ 1.1 log @Initial revision @ text @@ 1.1.1.1 log @Initial import of raw distribution from Weitse Venema @ text @@ 1.1.1.2 log @postfix release-20010228 @ text @a0 12 LDAP SUPPORT IN POSTFIX ======================= Postfix can use an LDAP directory as a source for any of its lookups: aliases, virtual, canonical, etc. This allows you to keep information for your mail service in a replicated network database with fine-grained access controls. By not storing it locally on the mail server, the administrators can maintain it from anywhere, and the users can control whatever bits of it you think appropriate. You can have multiple mail servers using the same information, without the hassle and delay of having to copy it to each. d10 1 a10 9 (http://www.openldap.org), something like this in the top level of your Postfix source tree should work: % make tidy % make makefiles CCARGS="-I/usr/local/include -DHAS_LDAP" \ AUXLIBS="-L/usr/local/lib -lldap -L/usr/local/lib -llber" On Solaris 2.x you may have to specify run-time link information, otherwise ld.so will not find some of the shared libraries: d13 2 a14 3 % make makefiles CCARGS="-I/usr/local/include -DHAS_LDAP" \ AUXLIBS="-L/usr/local/lib -R/usr/local/lib -lldap \ -L/usr/local/lib -R/usr/local/lib -llber" d16 1 a16 1 The 'make tidy' command is needed only if you have previously built a18 4 Instead of '/usr/local' specify the actual locations of your LDAP include files and libraries. Be sure to not mix LDAP include files and LDAP libraries of different versions!! d24 2 a25 2 doesn't support Kerberos binds to the LDAP server anyway. Sorry about the bother. d29 2 a30 2 have, and you may need to use the appropriate linker option (e.g. '-R') so the executables can find it at runtime. d32 2 a33 2 CONFIGURING LDAP LOOKUPS ======================== d42 3 a44 3 definition and an underscore. 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: d51 1 a51 3 trying them in order should the first one fail. It should also be possible to give each server in the list a different port, by naming them like "ldap.your.com:1444". d57 1 a57 1 search_base (No default; you must configure this.) a69 8 domain (Default is to ignore this.) This is a list of domain names, paths to files, or dictionaries. If specified, only lookups for the domains on this list will be performed. This means that the LDAP map won't get searched for 'user', nor will it get searched for any domain not listed. This can significantly reduce the query load on the LDAP server. ldapsource_domain = postfix.org, hash:/etc/postfix/searchdomains d71 1 a71 1 The attribute(s) Postfix will read from any directory entries d73 1 a73 10 ldapsource_result_attribute = mailbox,maildrop special_result_attribute (No default) The attribute(s) of directory entries that can contain DNs or URLs. If found, a recursive subsequent search is done using their values. ldapsource_special_result_attribute = member scope (sub) The LDAP search scope: sub, base, or one. These translate into LDAP_SCOPE_SUBTREE, LDAP_SCOPE_BASE, and LDAP_SCOPE_ONELEVEL. a80 7 If you do need to bind, you might consider configuring Postfix to connect to the local machine on a port that's an SSL tunnel to your LDAP server. If your LDAP server doesn't natively support SSL, put a tunnel (wrapper, proxy, whatever you want to call it) on that system too. This should prevent the password from traversing the network in the clear. d88 1 a88 1 use this, you probably want to make main.cf readable only by a91 26 cache (no) Whether to use a client-side cache for the LDAP connection. See ldap_enable_cache(3). It's off by default. cache_expiry (30 seconds) If the client-side cache is enabled, cached results will expire after this many seconds. cache_size (32768 bytes) If the client-side cache is enabled, this is its size in bytes. dereference (0) When to dereference LDAP aliases. (Note that this has nothing do with Postfix aliases.) The permitted values are those legal for the OpenLDAP/UM LDAP implementations: 0 never 1 when searching 2 when locating the base object for the search 3 always See ldap.h or the ldap_open(3) or ldapsearch(1) man pages for more information. And if you're using an LDAP package that has other possible values, please bring it to the attention of the postfix-users@@postfix.org mailing list. d95 2 a96 5 EXAMPLES ======== ALIASES ------- d98 2 a99 2 Here's a basic example for using LDAP to look up aliases. Assume that in main.cf, you have these configuration parameters defined: a112 52 VIRTUAL DOMAINS/ADDRESSES ------------------------- If you want to keep information for virtual lookups in your directory, it's only a little more complicated. First you need to make sure Postfix knows about the virtual domain. An easy way to do that is to add the domain to the mailacceptinggeneralid attribute of some entry in the directory. Next you'll want to make sure all of your virtual recipients' mailacceptinggeneralid attributes are fully qualified with their virtual domains. Finally, if you want to designate a directory entry as the default user for a virtual domain, just give it an additional mailacceptinggeneralid (or the equivalent in your directory) of "@@virtual.dom". That's right, no user part. If you don't want a catchall user, omit this step and mail to unknown users in the domain will simply bounce. If you're using a version of Postfix newer than 19991226, that should do it. If not, you also need to add your virtual domains to relay_domains. Simply add "$virtual_maps" to your relay_domains line. Then you can use the same map you use to find virtual recipients to determine if a domain is a valid virtual domain and should be allowed to relay. In summary, you might have a catchall user for a virtual domain that looks like this: dn: cn=defaultrecipient, dc=fake, dc=dom objectclass: top objectclass: virtualaccount cn: defaultrecipient owner: uid=root, dc=someserver, dc=isp, dc=dom 1 -> mailacceptinggeneralid: fake.dom 2 -> mailacceptinggeneralid: @@fake.dom 3 -> maildrop: realuser@@real.dom 1: Postfix knows fake.dom is a valid virtual domain when it looks for this and gets something (the maildrop) back. 2: This causes any mail for unknown users in fake.dom to go to this entry ... 3: ... and then to its maildrop. Normal users might simply have one mailacceptinggeneralid and maildrop, e.g. "normaluser@@fake.dom" and "normaluser@@real.dom". OTHER USES ---------- Other common uses for LDAP lookups include rewriting senders and recipients with Postfix' canonical lookups, for example in order to make mail leaving your site appear to be coming from "First.Last@@site.dom" instead of "userid@@site.dom". a115 5 - The bits of schema and attribute names used in this document are just examples. There's nothing special about them, other than that some are the defaults in the LDAP configuration parameters. You can use whatever schema you like, and configure Postfix accordingly. d120 4 a123 5 - An entry can have an arbitrary number of mailacceptinggeneralids or maildrops. Maildrops can also be comma-separated lists of addresses. They will all be found and returned by the lookups. 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): d138 5 a142 12 maildrops other than mail addresses are pretty useless, because Postfix can't know how to set the ownership for program or file delivery. Your query_filter should probably look something like this: virtual_query_filter = (&(mailacceptinggeneralid=%s)(!(|(maildrop="*|*")(maildrop="*:*")(maildrop="*/*")))) - And for that matter, even for aliases, you may not want users able to specify their maildrops as programs, includes, etc. This might be particularly pertinent on a "sealed" server where they don't have local UNIX accounts, but exist only in LDAP and Cyrus. You might allow the fun stuff only for directory entries owned by an administrative account: d144 5 a148 1 local_query_filter = (&(mailacceptinggeneralid=%s)(|(!(maildrop="*|*")(maildrop="*:*")(maildrop="*/*"))(owner=cn=root, dc=your, dc=com))) d152 41 a192 18 require some thought on your part to implement safely, considering the ramifications of this type of delivery. 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. - LDAP lookups are slower than local DB or DBM lookups. For most sites they won't be a bottleneck, but it's a good idea to know how to tune your directory service. FEEDBACK ======== If you have questions, send them to postfix-users@@postfix.org. Please include relevant information about your Postfix setup: LDAP-related output from postconf, which LDAP libraries you built with, and which directory server you're using. If your question involves your directory contents, please include the applicable bits of some directory entries. d197 7 a203 14 Manuel Guesdon: Spotted a bug with the ldapsource_timeout attribute. John Hensley: Multiple LDAP sources with more configurable attributes. Carsten Hoeger: Search scope handling. LaMont Jones: Domain restriction, URL and DN searches, multiple result attributes. Mike Mattice: Alias dereferencing control. Hery Rakotoarisoa: Patches for LDAPv3 updating. Prabhat K Singh: Wrote the initial Postfix LDAP lookups and connection caching. Keith Stevenson: RFC 2254 escaping in queries. Samuel Tardieu: Noticed that searches could include wildcards, prompting the work on RFC 2254 escaping in queries. Spotted a bug in binding. And of course Wietse. @