Terry Gardner passed away in December, 2013.  There will be no new posts to this blog, but I will leave the blog up because it is useful to others.  Signed,

Denise, Terry’s wife.

Aside | Posted on by | Leave a comment

LDAP: Hardening Server Security (so administrators can sleep at night)

Client Connections

  • Limit the total number of concurrent sessions to the server and limit the number of concurrent sessions per client
  • Set size-limit, lookthrough-limit, and time-limit per client appropriate to client requirements (be aware of the server’s default settings, often these settings are not conducive to a hardened server)
  • Limit the time a connection can be unused, that is, open but no requests (idle-timeout). Hint: some load-balancers insist on leaving health-check connections open – administrators can use client connection policies and connection criteria to permit load-balancers to leave connections open indefinitely (no idle-timeout)
  • Use Client Connection Policies to configure address-based authentication, that is, know each and every client by IP address range or domain and create a client connection policy that will terminate all unknown client connections immediately
  • Create a Log Publisher for each IP address range or domain – this allows administrators to rapidly locate connection activity. See this example.
  • Use SSL or TLS for client connections and reject non-secure connections from clients – configure the server to permit only the StartTLS Extended Operation on a non-secure connection.
  • Use a separate physical network to connect for administrative sessions and use client connect criteria and policies to enforce administrative activity on the administrative network
  • Use a separate physical network for replication sessions
  • Use secure connections for replication traffic
  • Use third-party certificates
  • Reject all operations that are unauthenticated – this is better than simply disallowing anonymous BIND operations
  • Reject all requests on the non-secure network except for the StartTLS Extended Request
  • Ensure that selected administrators are trained and certificated on the procedure used for disconnecting clients
  • Reject requests that would result in an unindexed search; consider deploying a directory server farm for data mining operations that is separate from main-line client LDAP traffic.
  • Use Client Connection Policies to:
    • restrict operations clients are allowed to perform
    • restrict request controls and extended operations clients are allowed to use
    • restrict authentication types and SASL mechanisms
    • restrict the types of search filters
    • enforce a minimum substring length
    • reject requests that would result in an unindexed search
    • restrict access to portions of the Directory Information Tree (DIT)
    • to blacklist IP addresses that conduct denial-of-service attacks
    • restrict operation-rates

Java Updates

Oracle makes critical patch updates to the Java platform from time to time.
Check the critical patch update website or subscribe to email or receive an RSS feed.
Do not permit servers with known bad JVM versions to participate in main-line LDAP traffic.


  • Reject LDAPv2 except for legacy applications which do not support LDAPv3; consider upgrading those applications to a version which uses LDAPv3
  • Use SHA-2 with a 512-bit digest for password digests
  • Reject all operations on an unauthenticated session except for the StartTLS Extended Request
  • Disable (or reject) all SASL mechanisms except for EXTERNAL and GSSAPI. This includes DIGEST-MD5, which is a weak scheme which requires the directory server have access to the clear text password, meaning the password must be stored in the clear (horrors) or be encrypted with a reversible encryption (almost as bad)
  • Reject Simple BIND requests which have no password since no authentication takes place
  • Reject Simple BIND requests which have a null DN and a null password since no authentication takes place
  • Reject Simple BIND requests have a null DN and a non-null password since no authentication takes place
  • Reject attempts to use pre-encoded passwords – the only exception is the use of external software which is capable of managing password history and password quality. As of 2013, the professional-quality UnboundID Directory Server is still the best option for low-level password management
  • Do not allow weak encoding schemes for password storage, deny requests to use reversible storage schemes for password storage
  • Suppress failure or explanatory text in BIND results unless users are prevented from seeing diagnostic/explanatory text by some other means, such as a web front end
  • Reject proxied authentication if that feature is not required
  • Use strict password validators
  • Use account expiration
  • Use password history
  • Use the Password Modify Extended Request to change passwords
  • Consider modifying the Default Password Policy to be more restrictive, creating a new default password policy, or using the Secure Password Policy as the default

Administrative Accounts

Root DN (root user) accounts have an extensive set of privileges in the default distribution of the server products; therefore the root DN account(s) should not be used in normal operation except where a task cannot be performed by an administrator account.

Furthermore, root user accounts are not replicated whereas administrator accounts created in a replicated backend can be used on each server in a replicated topology.

The number of administrators with root user DNs and passwords should be as small as is practicable.

  • Configure administrator accounts with privilege levels appropriate to need.
  • Create groups for administrator accounts to make the task of specifying access controls easier.
  • Select a small number of users who may hold passwords for any root DN accounts.
  • Use a strict password policy for all users.
  • Reject all BIND requests that specify a root DN from all but IP address range or domain.

LDAP Servers which do not have sufficient granularity of privileges and access controls should be avoided, or at least not used in professional, mission-critical environments.

Backups and Exports

  • Digitally sign and encrypt all backups.
  • Digitally sign and encrypt all LDIF exports.
  • Reserve the backup, import, and export privileges for all accounts but a select few.

LDAP Servers which do not have the capability of digitally signing exports and backups should be avoided, or at least not used in professional, mission-critical environments. Under what circumstances would an operator be safe in importing an exported LDIF file when the server could not verify the contents by signature? Probably only the initial import when first installing the server or migrating away from some other server, any other time is just too dangerous because the data cannot be trusted.

  • Create a dsconfig batch-file with all necessary configuration instructions for use in building new servers
  • Consume all administrative alerts and notifications; do not ignore alerts and notifications
  • use audit-data-security frequently to:
    • report accounts with expired passwords
    • report accounts with multiple passwords
    • report accounts holding privileges
    • report disabled accounts
    • report entries with access control information
    • report locked accounts
    • report weakly encoded passwords
  • Use configuration server groups to ensure configurations are constant in a group of servers
  • Consider encrypting Directory Server data, especially if the data is subject to regulatory restrictions
  • If encrypting data, consider the limitations on encrypted data, for example, index key values are not encrypted – do not index attributes with sensitive data
  • Consider using sensitive attributes for those attribute values requiring additional protection
  • limit the scope of access control instructions
  • use global access controls only when there is no other way to solve a problem


term description
size-limit the maximum number of objects to return in a search request
lookthrough-limit the maximum number of objects the directory server will examine in the course of executing a search request
time-limit the maximum amount of time the server will spend processing a request
connection criteria an object used to classify LDAP client connections according to the properties of the search
client connection policy an object used to constrain LDAP clients and set resources limitations
StartTLS Extended Operation an LDAP extension used to promote a non-secure connection to a secure connection

Further Reading

Posted in computing, LDAP, UnboundID | Tagged , | 2 Comments

LDAP: Client Connection Policies


A Client Connection Policy controls the portions of the DIT a client can access and resource limits on what clients can do with data stored on the server. Clients are subject to one Client Connection Policy at a given time. Servers are distributed with a default Client Connection Policy. Groups of users or clients can be subject to a client connection policy, which reduces the amount of configuration required.

This article will describe LDAP client connections, authentication using LDAP, connection criteria, and client connection policies. An example is given at the end.

Client Connections

A connection from an LDAP comprises:

  • the IP address of the client
  • the connection handler handling the connection from the client
  • the protocol in use by the client
  • the communication security level
  • the authentication type
  • the authentication security level
  • the SASL mechanism if the authentication type is SASL
  • the base object above the authenticated distinguished name
  • the distinguished name of a group of which the authenticated client distinguished name is a member
  • filters which match the distinguished name of authenticated clients
  • privileges held by an authenticated client


Clients authenticate to Directory Server using the BIND operation. All connections are unauthenticated when they are first established. The authorization state of a connection is changed using the BIND operation. When a BIND operation is received, the Directory Server resets the authorization state of a connection. After a BIND operation is successful, the authorization state of the connection is set to that associated with the BIND distinguished name. Subsequent BIND operations on the connection immediately reset the authorization state to unauthenticated. If clients use LDAPv2, BIND must be the first operation on a connection and no subsequent BIND operations are allowed. LDAPv3 allows multiple BIND operations, subject to certain conditions. All new code should use LDAPv3.

All uncompleted operations must complete or be ABANDONed before a BIND request will be processed by the server. Clients are prohibited from transmitting requests until the BIND operation completes. Servers are prohibited from processing requests before a BIND completes.
Multiple BIND requests are required for multi-stage BIND operations

For more information, see: LDAP: Authentication Best Practices.

Connection Criteria

A connection which matches user-defined criteria is said to meet the connection criteria. The collection of user-defined criteria is known as a Connection Criteria object. Clients connections which meet no defined collection of criteria are subject to the default Client Connection Policy because the default Client Connection Policy has no Connection Criteria object assigned. A collection of criteria is specified by creating a Connection Criteria object and setting properties of the object; or by setting properties of an existing Connection Criteria. Connection Criteria objects are created, deleted, or modified using the dsconfig command line tool or the Web Console.

Client Connection Policies

A Connection Criteria object uses known client connection parameters to classify a client connection. Client connections are subject to a given Client Connection Policy if the client connection matches the Connection Criteria object assigned to the policy; the connection may be said to “meet connection criteria”.

Client Connection Policies are assigned when:

  • A client connects
  • A BIND request is received from the client
  • The client use the StartTLS extended request to promote a non-secure connection to a secure connection


Administrators desire to classify connections from an application called “Email Application”. The source IP addresses of all application instances are 10.1.1.* and 10.1.0.*. The application uses SSL to connect to the server and authenticates with a simple BIND operation that uses a single distinguished name, that is, all instances of the application use one distinguished name to authenticate.

Create the Connection Criteria

Use dsconfig to create a Connection Criteria object which matches the connection parameters described above for the email application, that is, the source IP addresses (the IP addresses from which email application LDAP connections originate), the fact that the applications always use secure connections (SSL), the fact that the applications always use a simple BIND operation using a known DN:

$ dsconfig create-connection-criteria                      \
   --criteria-name "Email Application Connection Criteria" \
   --type simple                                           \
   --set "description:Connections which meet these criteria are connections from one of the Email Application instances."                              \
   --set included-client-address:               \
   --set included-client-address:               \
   --set communication-security-level:secure-only          \
   --set user-auth-type:simple                             \
   --set authentication-security-level:secure-only         \
   --set "included-user-base-dn:cn=Email Applications,ou=Applications,o=servers"

Create the Client Connection Policy

Administrators wish to restrict the Email Application to BIND, SEARCH, and COMPARE operations and to restrict the maximum number of entries the application can retrieve with one request to 100. A Client Connection Policy is used to constrain the application. The client connection policy below allows only BIND, COMPARE, and SEARCH operations, and restricts the clients which match the specified client connection policy (created above and referenced in the client connection policy) to 100 entries per search request.

dsconfig create-client-connection-policy                              \
  --policy-name "Email Application Client Connection Policy"          \
  --set "description:Restrictions on the Email Application instances" \
  --set enabled:true                                                  \
  --set evaluation-order-index:100                                    \
  --set "connection-criteria:Email Application Connection Criteria"   \
  --set allowed-operation:bind                                        \
  --set allowed-operation:compare                                     \
  --set allowed-operation:search                                      \
  --set allowed-auth-type:simple                                      \
  --set maximum-search-size-limit:100

test the new Client Connection Policy

Use ldapsearch to authenticate and search. Note that the parameters to the ldapsearch command match the parameters that will be used by the email applications.

$ ldapsearch -h ldap.example.com                                  \
             -p 1636                                              \
             -D 'cn=email applications,ou=applications,o=servers' \
             --useSSL --trustAll -b '' -s base '(&)' 1.1

View the results in the access log:

BIND RESULT conn=54 op=0 msgID=1 version="3" dn="cn=email applications,ou=applications,o=servers" authType="SIMPLE" resultCode=0 etime=1.377 authDN="cn=email applications,ou=applications,o=servers" clientConnectionPolicy="Email Application Client Connection Policy"

Attempt to modify an entry. The client connection policy will prevent the user with the authorization state associated with the email application from modifying an entry.

$ ldapmodify -h ldap.example.com                                  \
             -p 1636                                              \
             -D 'cn=email applications,ou=applications,o=servers'  \
             -w 'password'                                        \
             --useSSL                                             \
dn: cn=admin,o=servers
changetype: modify
add: description
description: some text.
# Processing MODIFY request for cn=admin,o=servers
The client connection policy associated with the client connection does not allow modify operations to be processed
Result Code:  50 (Insufficient Access Rights)
Diagnostic Message:  The client connection policy associated with the client connection does not allow modify operations to be processed
Posted in computing, LDAP, UnboundID | Tagged , , , | Leave a comment

LDAP: Administrative users


In an UnboundID LDAP directory server, the “Root DN” (root user) accounts have an extensive set of privileges in the default distribution of the server products; therefore the root DN account(s) should not be used in normal operation except where a task can only be performed by an root user. The number of administrators with root user DNs and passwords should be as small as is practicable.

An “administrative account” or “administrative user” is a distinguished name which has access and privileges beyond those granted to other users. Typically, an administrative user has access to all attributes of all entries on the server, including the administrative sections of the server. Administrative accounts are superior to root DN accounts because they are replicated and because they can be restricted by privilege assignment. For example, an administrative user can be created that has the privilege of “backup”, but no other privileges. The UnboundID product suite uses this extremely flexible access and privilege mechanism instead of a simplistic brute force access control system.

Root user accounts are not replicated whereas administrator accounts created in a replicated backend can be used on each server in a replicated topology. This is a tremendous disadvantage of a Root DN.

LDIF for an Administrative User


Following is an example LDIF for an administrative account/user. This example uses the naming context c=us. The DN of this administrative user is cn=admin,c=us. It makes no difference what the DN of the administrative user is, as long as it is hosted in a replicated backend. The password is a horrible one, I trust you’ll use a password generator to generate a better one. The server will encrypt the password or create a cryptographic hash when the entry is added with ldapmodify. How the password is hashed or encrypted is decided by the password policy to which the user is subject.

The administrative user given below has a number of privileges that will prove useful when operating the server. For example, this administrative user has the privilege of reading and writing the configuration of the server – a must when tasked with operating the server. The UnboundID Directory Server supports “privileges” which are required to perform certain tasks and are a adjunct to access controls. Access controls must also exist as a complement to privileges. This is far more flexible model than the brute force model used in other directory servers.

dn: cn=admin,c=us
changetype: add
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetOrgPerson
cn: admin
sn: admin
userPassword: password
ds-privilege-name: backend-backup
ds-privilege-name: backend-restore
ds-privilege-name: config-read
ds-privilege-name: config-write
ds-privilege-name: jmx-notify
ds-privilege-name: jmx-read
ds-privilege-name: jmx-write
ds-privilege-name: ldif-export
ds-privilege-name: ldif-import
ds-privilege-name: lockdown-mode
ds-privilege-name: password-reset
ds-privilege-name: privilege-change
ds-privilege-name: soft-delete-read
ds-privilege-name: unindexed-search
ds-privilege-name: update-schema


Next, create the LDIF change records for a group the members of which are administrative users. Grouping users together by type is an effective technique and makes creating access control easier. The DN of the group for administrators is give as cn=Directory Administrators,ou=groups,c=us, of course, this is an arbitrary name.

dn: ou=groups,c=us
changetype: add
objectClass: top
objectClass: organizationalUnit
ou: groups
userPassword: password

dn: cn=Directory Administrators,ou=groups,c=us
changetype: add
objectClass: top
objectClass: groupOfUniqueNames
cn: Directory Administrators
uniqueMember: cn=admin,c=us

Access Controls

Create an LDIF change records containing access controls that are necessary for an administrative user. For the bind rule, use the DN of the group given above. This will cause the access controls created to apply to all members of the group. Only users requiring administrative access should be members of the group because the access controls grant access to all attributes of all entries. The controls listed are:

dn: c=us
changetype: modify
add: aci
aci: (targetattr="*||+")
 (version 3.0;
 acl "Access to all attributes by members of the Directory Administrators group.";
 allow(all) groupdn="ldap:///cn=directory administrators,ou=groups,c=us";)
aci: (targetcontrol="1.2.840.113556.1.4.319||2.16.840.1.113730.3.4.9||1.2.840.113556.1.4.473")
 (version 3.0;
 acl "Access to selected controls for cn=admin,c=us";
 allow (read) groupdn="ldap:///cn=directory administrators,ou=groups,c=us";)

Next, the global access controls. These access controls allow administrative users to view entries in operational sections of the server. Use dsconfig to add these global access controls. The operational servers to which access is allowed are:

  • config – the configuration of this server
  • tasks – tasks that can be added to the server for execution
  • monitor – real-time operational data, for example, number of BIND operations performed
  • schema – The server schema in which are defined attribute types and object classes recognized by the server
  • alerts – administrative alerts generated by the server; these alerts are used by operators to respond to events associated with the operation and status of the server
dsconfig set-access-control-handler-prop \
 --add global-aci:'(target="ldap:///cn=config")(targetattr="*")(version 3.0; acl "Allow access to the config tree by cn=admin,c=us"; allow(all) groupdn="ldap:///cn=directory administrators,ou=groups,c=us";)' \
 --add global-aci:'(target="ldap:///cn=tasks")(targetattr="*")(version 3.0; acl "Allow access to the tasks tree by cn=admin,c=us"; allow(all) groupdn="ldap:///cn=directory administrators,ou=groups,c=us";)' \
 --add global-aci:'(target="ldap:///cn=monitor")(targetattr="*")(version 3.0; acl "Allow access to the monitor tree by cn=admin,c=us"; allow(all) groupdn="ldap:///cn=directory administrators,ou=groups,c=us";)' \
 --add global-aci:'(target="ldap:///cn=schema")(targetattr="*||+")(version 3.0; acl "Allow access to the schema tree by cn=admin,c=us"; allow(all) groupdn="ldap:///cn=directory administrators,ou=groups,c=us";)' \
 --add global-aci:'(target="ldap:///cn=alerts")(targetattr="*")(version 3.0; acl "Allow access to the alerts tree by cn=admin,c=us"; allow(all) groupdn="ldap:///cn=directory administrators,ou=groups,c=us";)'
Posted in computing, LDAP, UnboundID | Tagged , , , , | Leave a comment

LDAP: The MultiUpdateExtendedRequest

The UnboundID Directory Server supports an extended request called the MultiUpdateExtendedRequest. This extended request packages multiple updates in a single request and provides control over the behavior of the server when errors arise during the processing of the extended request. Examine the following code sample:

// exception handling is not shown
Entry first = LDAPTestUtils.generateUserEntry("first","ou=people," +

Entry second = LDAPTestUtils.generateUserEntry("second","ou=people," +

final String[] dc = {
  "dn: dc=example,dc=com",
  "objectClass: top",
  "objectClass: extensibleObject",
  "objectClass: domain",
  "dc: example",

final String[] people = {
  "dn: ou=people,dc=example,dc=com",
  "objectClass: top",
  "objectClass: organizationalUnit",
  "ou: people",

final MultiUpdateErrorBehavior errorBehavior =
final MultiUpdateExtendedRequest req =
  new MultiUpdateExtendedRequest(errorBehavior,
           new AddRequest(dc),
           new AddRequest(people),
           new AddRequest(first),
           new AddRequest(second));
MultiUpdateExtendedResult result = (MultiUpdateExtendedResult)
if(result.getResultCode().equals(ResultCode.SUCCESS)) {
  switch(result.getChangesApplied()) {
  case NONE:
    // There were no changes applied.
  case ALL:
    // All parts of the update succeeded.
  case PARTIAL:
    // At least one update succeeded, and at least one failed.

The code sample above attempts to create two entries and the superiors of those entries:

  • dc=example,dc=com
  • ou=people,dc=example,dc=com
  • cn=first,ou=people,dc=example,dc=com
  • cn=second,ou=people,dc=example,dc=com

The error behavior is set to CONTINUE_ON_ERROR which causes the requests to continue when any of them fails. This acts like the –continueOnError flag to ldapmodify, or -c in the legacy OpenLDAP ldapmodify tool.

Posted in Java, LDAP, UnboundID, UnboundID LDAP SDK | Tagged , | Leave a comment