In 2006 Ludo helped me
compose a list of LDAP best practices for a developer guide I was
writing for Sun. This chapter of the guide was removed before
When Developing Specify LDAP v3
Many client libraries default to LDAP v2, but you can elect to use
v3. To benefit from LDAP v3 features, you can set up the connection,
authenticate explicitly using LDAP v3.
With JNDI, you could use LDAP v3 as shown here.
Hashtable env = new Hashtable();
InitialLdapContext ctx = new InitialLdapContext(env, null);
With the Mozilla LDAP C SDK, you could use LDAP v3 as shown
int version = LDAP_VERSION3;
ldap_set_option( NULL, LDAP_OPT_PROTOCOL_VERSION, &version );
Mozilla LDAP C SDK uses LDAP v3 by default.
With the Mozilla LDAP Java SDK, you could use LDAP v3 as shown
LDAPConnection ld = new LDAPConnection();
ld.setOption(LDAPv3.PROTOCOL_VERSION, new Integer(3));
When Developing Authenticate Correctly
LDAP v3, you connect, then you bind and perform LDAP operations, then
unbind and disconnect. The bind is the authentication operation in
application can hold onto a connection but change the authentication
by using the bind operation again.
Some directories do not allow anonymous access, even for reads. When
you build your application, keep the option that allows users to
to the directory. Furthermore, the information sent across the network
be sensitive. You can protect sensitive data by allowing the
secure the connection by using Secure Sockets Layer (SSL) or Start
Layer Security (TLS).
If your application needs to authenticate, obtain a regular account
to authenticate with the directory, rather than using the directory
account (such as cn=Directory Manager). When you
as directory superuser, you bypass normal access control mechanisms.
Bypassing normal access control renders auditing directory access more
When authenticating, have your application use SSL or SASL DIGEST
to avoid sending passwords over the network in clear text. Furthermore,
using password-based authentication, have your application check
policy controls, especially to determine when a password must be
When Developing Limit Connection Overhead
A new connection requires system resources. The LDAP model allows
to reuse connections by binding again with a different identity on the
connection. Thus, you can avoid the costs of new connections,
negotiated connections such as connections that use SSL, by reusing
Your application can use a pool of connections, rebinding when
Your application can alternatively use the proxy authorization control
remain authenticated as the application but perform operations on
a particular user.
When establishing a connection, your application can provide
server host names and port numbers to facilitate failover that is
to the application. You can also set time limits for LDAP operations to
When finished with a connection, your application should perform an
When Developing Handle Potential Inactivity Timeouts
Most network equipment can use timeouts to drop stale connections,
the equipment keeps a maximum number of connections that are available.
If your application pools connections or opens connections for
search, than guard against timeouts that drop those connections. Use
occasionally to reset inactivity timers present in the network.
Alternatively, if you have control over the connection, consider
inactivity time outs for your applications that need to keep persistent
open. Load balancers and proxy software often use inactivity timeouts.
When Developing Retrieve Entries Intelligently
LDAP servers typically respond quickly to requests for entries.
Yet, the server can respond most quickly when your application
it to do only necessary work. If you need to read only a few attributes
an entry, request each attribute explicitly. Avoid reading the entire
then parsing the entire entry to obtain the required data.
Furthermore, when you do request attributes in an entry, retrieve
the required attributes at once. Each new request involves a new
on the server.
If any of the attributes that you require are operational
you must request those attributes specifically. With Sun Directory
are identifiable in the directory schema by their USAGE,
which is directoryOperation or dsaOperation.
When retrieving entries and attributes, recognize that you might not
have access to all the attributes that exist.
When Developing Write Simple, Conforming LDAP Filters
The best filters use attributes that are indexed according to the
the attributes are indexed. For example, if employeeNumber is
indexed for equality, your filter should be an equality filter such as (employeeNumber=12345).
Do not use a substring filter instead.
Avoid deeply nested complex filters when you can. When you must use
complex filters, place the most specific filters first to narrow the
of candidate entries the directory must check. For best results, use not,
!, only with and, &, for example (&(cn=Barbara)(!(sn=Jensen))).
When you use not with or in a filter,
the directory must construct a candidate list of everything except what
When Developing Make Modifications Specific
Modifications are atomic on the entry to which the modifications
When modifying multivalued attributes, delete and replace specific
Do not replace an entire list of multiple values to change only a few
Replacing specific values is particularly good practice when the
be replicated across a set of servers.
Moreover, when you have very large values to store in an attribute,
a reference to the data instead of storing the data object.
When Developing Trust Result Codes
LDAP replication trades tight consistency across replica servers
for very high performance, availability, and scalability. By allowing loose
consistency of data across sets of replica servers, individual
servers can respond very quickly to your application. Yet, data
is not instantaneous. A short but detectable delay can ensue after a
returns success for a write operation, but before the effects are seen
Therefore, when your application receives a result code from an LDAP
to indicate that an operation was successful, your application should
the result code. When application requests are balanced across
from another replica might result in errors due to a slight delay in
Directory administrators can get around applications that do not
result codes for example by configuring Sun Directory Proxy Server to
affinity, which routes operations from the same client to the same
When Developing Limit Dealings With Groups and Roles
When you want to know whether an account belongs to a group or a
read only the necessary attribute values. Do not read the entire list
For static groups, Sun
Directory Server and OpenDS offer
the isMemberOf attribute on the user entry. With
Sun Directory Server 5.x versions, compare the DN of the account to the
attribute of the group, such as (uniquemember=uid=bjensen,ou=people,dc=example,dc=com). Or use a filter to find all the static groups to which a user belongs, such as (&(member=uid=bjensen,ou=people,dc=example,dc=com)(objectclass=groupofnames)).
For dynamic groups, do the
Read the URL from the group definition.
Examine the host, DN, and scope of the URL.
Apply the filter part of the URL to the entry for the account.
For Sun Directory Server roles, compare the DN of
the role to the nsRole attribute
of the entry for the account, such as (nsrole=cn=management,ou=people,dc=example,dc=com).
When Developing Read the DSE
The root DSE is the entry that is retrieved by ldapsearch -b
"" -s base "(objectclass=\*)"
. The root DSE describes server
The root DSE contains information about supported LDAP protocol
naming contexts (suffixes), LDAPv3 controls, LDAPv3 extensions, and
mechanisms. The root DSE can contain information about the server
Some directory administrators protect access to the root DSE. Yet,
might read the root DSE to confirm that the server in fact supports
required by applications.
When Developing Use Resource-Intensive Features Sparingly
Directories offer powerful features that can nevertheless place a
load on the server. Two such features are persistent search, and
Persistent search lets you start a search that does not stop when
but instead allows you to receive updates when entries are modified. To
this feature, the server must handle your search when anything happens
an entry in its scope.
Server-side sorting requires that the server sort the entries that
returned during a search. Instead of returning entries as quickly as
the server must therefore get the list to return, and sort the list.
When Developing Avoid Hard Coding Information About Data
The container entry for a subtree might be not be identical on
directories. Rather than hard code the container entry throughout your
locate the container entry. Then navigate beneath the container entry
Object classes and attribute types for the same information can also
differ from directory to directory. Use configuration files, properties
or other easily modifiable variables rather than hard coding object
and attribute type identifiers into your application.
Be aware as well that object class and attribute type identifiers
are not case-sensitive in LDAP. Your application should
that inetOrgPerson and inetorgperson are
equivalent, as are isMemberOf and ismemberof.
When Developing Define Schemas Only When Necessary
Schemas define the object classes and attribute types that are
by the directory. If your application can use a standard schema, use
schema. LDAP server schemas typicall define numerous standard
object classes, and attribute types.
When you must define your own schema objects, follow these
Extend existing object classes by using AUXILIARY
Create new attributes rather than redefining existing attributes.
Other applications might depend on existing attributes to keep
their existing semantics.
Obtain new object identifiers for the schema elements you
define, rather than reusing existing object identifiers.
Obtain new names for the schema elements you define, rather
than reusing existing names.
Update schema over LDAP if you can.
When Developing Handle Referrals
LDAPv3 allows directories that are unable to handle your request to
refer your application to other directories. Your application should
When following referrals, realize that authentication procedures
not be exactly the same on different directories. Also, directories
to each other could potentially cause a referral loop. With the Mozilla
Directory SDKs, you can limit referral hops to prevent your
application from being referred endlessly from one directory to another
The JNDI interface enables you to follow referrals automatically.
When Developing Treat a Directory as a Directory
A directory is typically a repository for identity data, and for
that you expect to keep for awhile and read often. You might typically
relational databases better adapted to hold transient data such as
keys and presence information, or voluminous accumulated data such as
When Troubleshooting Check Result Codes
When an LDAP request from your application fails on the server, the
server sends back a result code, and possibly an explanatory message.
application should check the result codes, and for explanatory
failure result codes include the following, which are expressed as
values. Others result codes are defined as well.
LDAP operations error. The server encountered an error while
processing your request.
No such object. The entry is not present on the server. Also,
no referral is defined for the entry.
Invalid credentials. Your application failed to authenticate
LDAP unwilling to perform. The directory does not support
the request. Alternatively, the directory is not currently in a state
to complete your request. For example, the directory might be in
mode when your application requests a modification.
Object class violation. Your write request would cause an
entry to no longer conform to the schema defined for the directory.
Already exists. Your application is requesting to add an entry
that has the same DN as an entry already present in the directory.
RFC 4511 defines
LDAP error codes.
When Troubleshooting Check Server Log Files
OpenDS and Sun Directory Server log messages related to server
operation in its instance-path/logs/errors
file. If you have access
to this file, you might find useful troubleshooting information there.
When debugging your application against Sun Directory Server, you can
adjust the log level using the dsconf set-log-prop error level:your-setting
command. Log level settings are explained
in the log(5dsconf) man
page. If you use OpenDS, see https://www.opends.org/wiki/page/HowToConfigureLogsWithDsconfig.
When Troubleshooting Inspect Network Packets
Although LDAP is not a textual protocol, tools such as snoop(1M),
ethereal, and tcpdump can decode the packets,
sometimes providing you with important debugging information. SLAMD
also provides an LDAP decoder to display LDAP packets in human-readable
(How many of those rules did I break in Java, PHP, and Python? ;-)