S 4.387 Secure assignment of access rights to OpenLDAP
Initiation responsibility: IT Security Officer, Head of IT
Implementation responsibility: Administrator
The proper assignment and correct implementation of access rights are essential prerequisites to ensuring information security. Whenever a user directs an operation towards an object in the directory service, it must be decided if executing this operation is permitted. The authorisation concept must be defined within the framework of safeguard S 2.405 Drawing up a security policy for the use of directory services. The rules and regulations specified in this safeguard must be implemented technically in OpenLDAP. General information on this topic can also be found in safeguard S 4.309 Setting up access authorisations for directory services. The LDAP standard only states that access control is to be carried out and defines server responses within the framework of the standard if operations are denied due to insufficient authorisations. However, the LDAP standard does not include any specification on how access control is to be implemented specifically; this depends to a large extent on the directory service used. The assignment of access rights in OpenLDAP is therefore addressed comprehensively in this safeguard.
Access control lists in OpenLDAP
In OpenLDAP, access control lists (ACLs) are maintained in the form of directives in the configuration. For each operation triggered by a user, it is determined if this operation is covered by a directive.
An access directive has the following syntax:
access to [target object]
by [user] [scope of authorisations]
by [user] [scope of authorisations]
...
Among other things, suffixes, objects or attributes can be specified as target object. Even the result of a LDAP search or specific attribute assignments can be defined. In this respect, almost any level of detail and combinations are possible, which cannot be addressed in this safeguard. Particularly worth mentioning, however, is the target object * that comprises all possible target objects of the directory service.
User
Among others, OpenLDAP provides the following entries as users:
- * for all users of the directory service including unauthenticated users
- anonymus for unauthenticated users
- users for authenticated users (for information on the differentiation of authenticated and unauthenticated users, see S 4.388 Secure authentication to OpenLDAP)
- self for users who have carried out a "bind" with the identity of the target object
- Distinguished names (DNs) for fully qualified users or regular terms
- Attribute filters to grant access to an object, for which the user has been entered in an attribute, for example as superior of an employee
- Group attributes, to control access rights using static or dynamic group memberships
- IP entries for all users whose client is connected from a specified IP address space or with a specified domain.
Although accepted by OpenLDAP, access control should under no circumstances be carried out on the basis of IP addresses, since IP addresses can be easily forged.
Scope of authorisations
OpenLDAP knows the following values as scope of authorisations:
- none: no access authorisation
- disclose: Existence check for error tracking
- auth: possibility of performing a "bind" as target object
- compare: performing comparisons
- search: applying search filters to the target object
- read: read access to the target object
- write: write access to the target object (change, rename, delete)
- manage: full access including the rights required to access operational attributes
In addition, there are also special authorisations such as "selfwrite". This special authorisation makes it possible to only write one's own DN, for example, to maintain separate group memberships. Each scope of authorisations automatically includes all aforementioned scopes of authorisations. Thus, a read authorisation also grants the rights to carry out "disclose", "auth", "compare" and "search" actions. In general, this is useful and the use of "access levels" is sufficient in most cases. Otherwise, authorisations can be assigned in a more detailed manner deploying privilege operators.
Several "by" clauses
Within an access directive, any number of "by" clauses might follow upon each other. The evaluation within a directive is stopped as soon as a corresponding "by" clause is found. This is the case as soon as a user mentioned in the "by" clause corresponds to or includes the requesting user. A classic access directive is for example:
access to *
by self write
by anonymus auth
by group.exact="CN=admin, ou=groups, DC=bsi, DC=federal, DC=de" write
by users read
Using this directive, each user can change their own entry, an anonymous user can use each entry to authenticate themselves; members of the administrator group can change entries and an authenticated user can read all entries. The last "by" clause might also be "by * read" and would have the same effect. Since the second "by" clause already applies to unauthenticated users, the fourth clause is always only checked for authenticated users who are not administrators. If the first and fourth "by" clause were exchanged, there would be no write privileges to entries, since the "group" clause as well as the "self" clause following the "users" clause would no longer be processed. If no user information provided in a directive applies to a requesting user, this user is not granted any authorisation. During the evaluation, every directive is treated as if it concludes with the "by * none" clause even if it is not stated there.
Several access directives
Any number of access directives might follow upon each other. The directives are processed in the order listed. An ACL is no longer evaluated as soon as an applicable directive has been found. A directive is considered to be applicable if the requested target object corresponds to the object from the directive or if it is included in such object. For example, the directives
access to dn.subtree="DC=grundschutz, DC=bsi, DC=federal, DC=de"
by users write
access to dn.subtree="DC=bsi, DC=federal, DC=de"
by users read
cause that authenticated users can read all contents of the fictitious subdirectories "bsi.bund.de" and are allowed to access the contents of "grundschutz.bsi.bund.de" with write privileges. If the directives were stated in the reverse order, there would be no write privilege, as an operation with the "DC=grundschutz" target object is already a subset of the "DC=bsi, DC=federal, DC=de" object. If no target object information in any directive applies to a requested target object, then no authorisation to the target object is granted either. During the evaluation, every access control list is treated as if it concludes the "access to * by * none" directive even if it is not stated there.
Order and control flags
These examples make clear that the order of ACL entries is of great importance. The general rule is to define special rights first and general rights last.
If it is still necessary to continue to evaluate the authorisations after an applicable rule has been found, this can be accomplished using the "continue" (for checking other "by" clauses within a directive) and "break" (for checking other directives) control flags. The control flags should be used very sparingly, as they result in complicated access control lists. It must be taken into account that another applicable rule replaces the rights that have already been granted. The "continue" control flag can actually always be avoided by planning the ACL correctly. It is only required when the "privilege" operators are deployed.
The "break" control flag is suitable for placing an extensive authorisation for special users at the beginning of an ACL. For example, the following directive grants a user deployed for replication purposes read privileges to the entire directory whilst the directive is "overread" for all other users:
access to *
by dn.exact="[DN of the replication user]" read
by * break
ACL in the slapd-config
The syntax described so far applies to the configuration using the "slapd.conf" configuration file. IF the "slapd-config" database is used, the following applies accordingly:
olcAccess: {n}to [target object]
by [user] [scope of authorisations]
by [user] [scope of authorisations]
...
The optional index {n} controls the order of the entries, which cannot result from their positions in the file as compared to the "slapd.conf" configuration file, since the "olcAccess" directory service objects are at the same level. Without using an index, the configuration-internal order and thus the effectiveness of the entries is unpredictable.
Global and database-specific ACLs
Access control lists can be defined globally and at the database level. The connections must be taken into account correctly when implementing OpenLDAP. Database directives take precedence over global directives. Here, the global access control list is added to the database-specific access control list and the entire list for evaluation is concluded by the "access to * by * none" directive even if it was not entered. Special directives at the beginning of a global ACL are thus often not implemented as desired when combined with a database-specific access control list.
Access rights via group memberships
The assignment of authorisations via group memberships makes it possible to separate the access right management and the technical maintenance of the slapd server using organisational safeguards. To manage access rights, it is only necessary to change the group objects; accessing the configuration itself is no longer required.
If access rights are managed via group memberships, the following aspects must be taken into consideration:
- In version 2.4, OpenLDAP does not reverse any access rights when there are groups within groups. As a potential solution, OpenLDAP offers the "set" concept. As long as "sets" are classified as experimental in version 2.4, they should not be used in production environments.
- It is recommended to use the "memberof" (member of) overlay. If a DN is assigned to a group object, the "memberof" overlay ensures that the corresponding feature is also documented as operational attribute for DN. This prevents complex search operations within the access control framework.
In OpenLDAP, it is possible to store access rights for the respective user using the "Access Control Information" (ACI) mechanism for the management of access rights that was also separated from the configuration. ACI, however, is a very complex mechanism in the configuration, as every user must be set up individually. In addition, the syntax of the mechanism has not been standardised yet and the mechanism in version 2.4 has only an experimental status. As long as ACI has an experimental status, it should not be used.
Testing access authorisations
Every change to the access control list should subsequently be tested using the "slapacl" tool. Using the tool, a user and an operation are specified and "slapacl" then determines if this operation can be performed successfully by the specified user without actually performing the operation. This test should be carried out in particular when the access is to be denied. The "slapacl" tool checks the authorisations against the "slapd.conf" configuration file. However, the changed access control list is only effective after the slapd server has been started or restarted. Thus, the slapd server should always be used when using the slap* tools. Even if the use of the slap* tools does not have a technical impact, results might result in incorrect conclusions whilst the slapd server is running.
It is recommended to derive test cases form the authorisation concept and to test them using the "slapacl"
- when the access control lists were changed substantially,
- when new backends, databases or suffixes were defined or
- when OpenLDAP was updated.
No restriction of the rootDN
In general, the ACLs do not apply to the rootDN of a database. If it is still included in access control lists, this merely results in additional administrative work and a loss of performance. On the other hand, it must be taken into account that not using access control lists results in only the "rootDN" having access to the directory service in OpenLDAP. Without using access control lists, a default setting applies granting all users, even anonymous users, a read privilege to all contents of the directory service. Under all circumstances, ACLs should be used.
Complexity of access authorisations
Access control lists can be controlled regarding various individual aspects and may vary greatly in terms of complexity. Administrators should make themselves familiar with the extensive sample configurations in the OpenLDAP Administrator's Guide which is available free of charge. However, we must point out that the "access levels" referred to in this safeguard have been proven and are generally sufficient to implement access rights. Especially regular terms and search filters must be handled carefully, as their definitions are often not restricted sufficiently and thus grant access rights accidentally. In addition, they restrict the data processing speed regarding access, since testing them consumes resources. The more extensive the access rights in the slapd server configuration are, the more important extensive tests using the "slapacl" tool are. If errors occur again and again, the design of the access rights should be revised in general.
Review questions:
- Is an authorisation concept for the access to objects in OpenLDAP implemented technically?
- Are the relationships between global and database-specific ACLs are taken into account correctly when implementing OpenLDAP?