You are on page 1of 29

Using Exim with LDAP

Douglas Gray Stephens


Senior Directory Architect
Schlumberger
Topics
• What is LDAP;
• What is LDAP designed for;
• How is LDAP integrated into Exim;
• Case study of using Exim with LDAP;
• How to trouble shoot Exim with LDAP;

2 DGS
23 Feb 2005
What is LDAP
• Light weight Directory Access Protocol;
• (X.500 is DAP, so more heavy weight);
• Communications protocol :
– no specification for back end server system;
• Standards based;
• Defacto standard for internet white pages (c.f. http for
on line documents).
• Current version is LDAPv3 (ratified in 2000)
3 DGS
23 Feb 2005
What is LDAP designed for
• Systems where there are few writes, but many reads;
• Storing any data;
• Fast response for queries;
• Redundancy (i.e automatic fail over);

4 DGS
23 Feb 2005
What is LDAP not designed for
• It is not a relational database;
• Is not efficient for systems with frequent writes;
• Server may return unexpected (e.g. no) results if
attribute not indexed.

5 DGS
23 Feb 2005
How is data stored in LDAP (DIT)

dc =com

dc =compa ny1 dc =c ompa ny2

ou=people ou=pa ge r ou=lis t ...... l=c a mbridge l=hous ton. l=london

cn=Douglas Gra y Ste phens

c n=J ohn Smith

c n=J ohn Smith2

6 DGS
23 Feb 2005
LDAP searches
• Require
– Server to search (where to look);
– Search root (part of DIT to start searching from);
– Scope (how far to look ─ base, one level, or sub tree);
– Filter (what to look for);
– Attribute(s) to return;

10 DGS
23 Feb 2005
LDAP search example
• E.g. ldapsearch –h myhost:389
–b dc=company1,dc=com
–s sub
“(cn=douglas gray stephens)”
cn sn givenname mail
– Returns
dn: cn=Douglas Gray Stephens,ou=employee,dc=company1,dc=com
cn: Douglas Gray Stephens
cn: Douglas Gray-Stephens
cn: Grey Stevens
sn: Gray Stephens
givenName: Douglas
mail: dgs1@skibass.org

11 DGS
23 Feb 2005
LDAP filters
• Components of filter nested within brackets “(…..)”;
• Items can be ANDed together (with “&”);
• Items can be ORed together (with “|”);
• Items can be negated (with “!”);
• Searches can include wild cards (with “*”);
• RFC 2254 gives full details.

12 DGS
23 Feb 2005
LDAP filter example
• E.g. “(&(mail=*)(c=gb)(!(l=london))(cn=douglas*))”
• Means
– Find all records with an mail attribute
– that are in the United Kingdom (GB)
– and are do not have London as the city
– and have a common name starting with douglas

13 DGS
23 Feb 2005
LDAP URLs
• An LDAP URL begins with the protocol prefix "ldap" and is
defined by the following grammar, as defined in RFC 2255:
<ldapurl> ::= "ldap://" [ <host:port> ] "/" <dn> [ "?" <attributes>
[ "?" <scope> "?" <filter> ] ]
<host:port> ::= <hostname> [ ":" <portnumber> ]
<dn> ::= a string as defined in RFC 2253
<attributes> ::= NULL | <attributelist>
<attributelist> ::= <attributetype>
| <attributetype> [ "," <attributelist> ]
<attributetype> ::= a string as defined in RFC 1777
<scope> ::= "base" | "one" | "sub"
<filter> ::= a string as defined in RFC 2254

14 DGS
23 Feb 2005
LDAP URL example
• ldap://server1 server2:387/dc=com?cn,mail?sub?(&(cn=douglas*)(l=cambridge))
• Specifies that
– there are two servers to try (server1, then server2). Note the
second server is on a non standard port (387);
– a search root of “dc=com”;
– attributes “cn” and “mail” should be returned;
– the sub tree should be searched;
– using a filter “(&(cn=douglas*)(l=cambridge))”;

15 DGS
23 Feb 2005
Building Exim
• Requires that the LDAP libraries be available
– OpenLDAP (http://www.openldap.org/);
– SunOne (previously Netscape/iPlanet) (
http://www.sun.com/software/products/directory_srvr_
ee/
)
• Specify in Makefile
LOOKUP_LDAP=yes
LDAP_LIB_TYPE=OPENLDAP1/OPENLDAP2/NETSCAPE/SOLARIS
LOOKUP_INCLUDE=-I /???/include
LOOKUP_LIBS=-L/???/lib -lldap -llber
17 DGS
23 Feb 2005
Configuring Exim
• Location of LDAP servers
ldap_default_servers = “\
localhost::389 : \
server1::389 : \
server2::387”

• Some router/transport commands to make use of


LDAP (use anywhere that you would use the exim
lookup functionality).

18 DGS
23 Feb 2005
LDAP lookups in Exim
• Types of lookups:
– ldap requires the result to contain just one entry;
if there are more, it gives an error.
– ldapdn also requires the result to contain just one
entry, but it is the Distinguished Name that is returned
rather than any attribute values.
– ldapm permits the result to contain more than one
entry;
the attributes from all of them are returned;
each entry in result string is on a separate line;
19 DGS
23 Feb 2005
LDAP lookup results
• ldap:///o=base?attr1?sub?(uid=frederic)
value1.1, value1.2
• ldap:///o=base?attr2?sub?(uid=frederic)
value two
• ldap:///o=base?attr1,attr2?sub?(uid=frederic)
attr1="value1.1, value1.2" attr2="value two"
• ldap:///o=base?objectclass,cn,sn?sub?(uid=frederic)
objectClass="top, person" cn=“Frederic Smith, Fred Smith" sn=“Smith“
• ldapm:///o=base??sub?(uid=fred*)
objectClass="top,person" attr1="value1.1, value1.2" attr2="value two“
objectClass="top,person" …. Etc. for the second match

20 DGS
23 Feb 2005
Case study
• Objective
– Look up names in LDAP and forward to appropriate
person;
– Handle instance when multiple matches;
– Handle instance when there is no email address;
– Enable user to control lookup options (so limiting
spam).

21 DGS
23 Feb 2005
Details of mail handling
• Addresses of the form uid@company.com will always
be sent to only one person, since a uid is by definition
unique within the directory.;
• Addresses of the form abc.efg_hij-
mno@company.com will be processed according to
the following rules.
– Forward to record that matches uid and has email address
– Forward to record that matches the common name(s)
– Forward to record that givename/surname
– Forward to a record that contains all the words in the common name(s)
– If record does not have email address, return phone number
– If there are 2 to 5 matches, give more details to sender
– If there are more than 5 matches, bounce message

22 DGS
23 Feb 2005
Mail processing
• For a single match, the message is forwarded to that
address;
• For 2 to 5 matches, the message is bounced back to
the sender along with details of the matches. The
sender is asked to try again.
• For more than 5 matches, the message is bounced
back to the sender. The sender is asked to be more
specific about the address.

23 DGS
23 Feb 2005
Message flow
Loop through series of Zero or more than one
LDAP lookups matches is failure for
ldapm lookup

Perl code alias_bounce


handles
• no matches Perl code ldap_one sets
• 2 to 5 matches
• more than 5 matches new_address and status
•No email address
(snail mail details)

24 DGS
23 Feb 2005
Exim Global parameters
• ldap_default_servers = “server1 server2:387”
• What should be returned:
Perl function that builds up
LDAP_URL = ldap:///dc=comany1,dc=com?uid,mail,cn,ou,telephonenumber,o?
an LDAP filter
sub?
• Search definitions for different lookups:
– MAIL_UID_MATCH = &(mail=*)(uid=${perl{punc_to_dash}{$local_part
– MAIL_CN_MATCH = &(mail=*)(cn=${perl{punc_to_spc}{$local_part}})
– MAIL_GIVENNAME_SN_MATCH = &(mail=*)(${perl{givenname_sn_match}
{$local_part}})
– MAIL_CN_WORDS_MATCH = &(mail=*)(${perl{cn_match}{$local_part}})

25 DGS
23 Feb 2005
LDAP router example
company1_user:
driver = redirect Returns mail address when one match
allow_defer
allow_fail
condition = "${perl{ldap_who} \
{${lookup ldapm {LDAP_URL(MAIL_UID_MATCH)}{$value} \
{${lookup ldapm {LDAP_URL(MAIL_CN_MATCH)} {$value} \
{${lookup ldapm {LDAP_URL(MAIL_GIVENNAME_SN_MATCH)}
{$value} \
{${lookup ldapm {LDAP_URL(MAIL_CN_WORDS_MATCH)} {$value} \
{DUNNO}}}}}}}}}}"
data = ${perl{new_address}}
domains = company1.com
headers_add = "X-LDAP-Alias: V LDAP_ALIAS_VERSION. Sent to
$local_part@$domain resolving to ${perl{new_address}}"
retry_use_local_part
26 DGS
23 Feb 2005
Bounce router

unknownuser:
driver = accept
retry_use_local_part
transport = uid_bounce
no_verify

27 DGS
23 Feb 2005
Bounce transport
uid_bounce:
driver = autoreply
from = Comapny1 Mail Server <mailer-daemon@org.com>
headers = "X-LDAP-To: bouncing ${local_part}@${domain} ($
{perl{failure_reason}})\n\
Mime-Version: 1.0\nContent-Type: multipart/mixed; boundary=\"$
{perl{mime_boundary}}\""
log = "/var/spool/exim/log/bouncelog"
once = "/var/spool/exim/db/bounce/${local_part}"
once_repeat = 1w
return_message
subject = "Unable to deliver to ${local_part}@${domain}"
text = ${perl{mime_bounce}{${domain}}}
to = $sender_address
transport_filter = "/etc/exim/close_mime ${perl{mime_boundary}}"

28 DGS
23 Feb 2005
Sample too many matches
From: Company1 Mail Server <mailer-daemon@slb.com>
Subject: Unable to deliver to few@company1.com

……

To help you locate the correct individual, selected fields from the possible matches are
included below. The uid field is the only onemguaranteed unique within a given
community.

Name : Andy Few


Uid : AFew1
Email : aFew1@london.company1.com
Organisation : Company1
City : london

Name : Alex Few


Uid : afew2
Email : afew2@cambridge.company1.com
Organisation : Company1
City : cambridge

29 DGS
23 Feb 2005
Example with no email address
From: Company1 Mail Server <mailer-daemon@slb.com>
Subject: Unable to deliver to dages1@company1.com

Dear email sender,

This message has been automatically generated because I, the email server, found a
single match looking for <dages1@company1.com> but that match contained no
forwarding email address and was thus undeliverable. The details of this match are as
follows:

Name : Dark Ages


Uid : dages1
Organisation : Company1
City : Oxford
Tel : +44 1865 1234567

30 DGS
23 Feb 2005
Trouble shooting
• Test out address resolution
– exim -bt dgraystephens@company1.com
dgs1@skibass.org
<-- dgraystephens@company1.com
router = perimeter_routes, transport = remote_smtp
host mail-relay.slb.com [163.184.1.20]
host mail-relay.slb.com [134.32.26.55]
host mail-relay.slb.com [163.187.152.23]
host mail-relay.slb.com [163.188.150.130]

31 DGS
23 Feb 2005
Trouble shooting (cont)
• Additional debugging
exim -d+lookup -bt dgraystephens@company1.com
Shows details including LDAP calls
database lookup required for
……..
perform_ldap_search: ldapm URL = "ldap:///dc=company1,dc=com?
uid,mail,cn,ou,telephonenumber,o?sub?(&(mail=*)(uid=dgraystephens))" server=localhost
port=389 sizelimit=0 timelimit=0 tcplimit=-1
after ldap_url_parse: host=localhost port=389
ldap_initialize with URL ldap://localhost:389/
……
ldap_parse_result yielded 0: Success
LDAP search: returning: cn="Douglas Gray Stephens, Douglas Gray-Stephens, Grey Stevens"
mail="dgs1@skibass.org" o="Company1" ou="Core services" uid="dgraystephens"
telephoneNumber="44 1223 325295 “
Check LDAP server logs for connection details
32 DGS
23 Feb 2005
Controlling fuzzy logic or spam
• Fuzzy logic is good when there is no spam
• If spam is an issue, then enable users to opt in or out
• Add new component to searches, e.g.
MAIL_CN_MATCH = &(mail=*)(cn=${perl{punc_to_spc}
{$local_part}})
becomes
MAIL_CN_MATCH = &(mail=*)(cn=${perl{punc_to_spc}
{$local_part}})(!(description=exclude:cn))

33 DGS
23 Feb 2005

You might also like