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.
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.
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.
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.
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.
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.
dsconfig
batch-file with all necessary configuration instructions for use in building new serversaudit-data-security
frequently to: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 |
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.
A connection from an LDAP comprises:
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.
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.
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:
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.
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:10.1.1.0/24 \ --set included-client-address:10.1.0.0/24 \ --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"
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
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 \ --trustAll 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
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.
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
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:
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";)'
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," + "dc=example,dc=com","first","last","password"); Entry second = LDAPTestUtils.generateUserEntry("second","ou=people," + "dc=example,dc=com","first","last","password"); 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 = MultiUpdateErrorBehavior.CONTINUE_ON_ERROR; final MultiUpdateExtendedRequest req = new MultiUpdateExtendedRequest(errorBehavior, new AddRequest(dc), new AddRequest(people), new AddRequest(first), new AddRequest(second)); MultiUpdateExtendedResult result = (MultiUpdateExtendedResult) ldapConnection.processExtendedOperation(req); if(result.getResultCode().equals(ResultCode.SUCCESS)) { switch(result.getChangesApplied()) { case NONE: // There were no changes applied. break; case ALL: // All parts of the update succeeded. break; case PARTIAL: // At least one update succeeded, and at least one failed. break; } }
The code sample above attempts to create two entries and the superiors of those entries:
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.