An Access Control Instruction or ACI is a set of rules placed on the directory or a subset of the directory. The rules are evaluated by the server and either allow or deny permissions to a client request. Permissions are for instance read, write, search and compare.
ACIs can also be placed on individual entries in the directory, or on configuration and other administrative tasks.
An ACI consists of three parts:
A target, specifying for what object, object attribute(s), or group of objects and attributes the access is being controlled.
The permissions outline which specific right is being granted or denied.
Bind rules specify who can access the controlled attribute or object, when they can do it and where they can do it from.
We will discuss each in the next sections.
ACIs are set using the special "aci" attribute. This can be set on every entry in the directory, regardless of whether it is defined for the object class used for the entry.
ACIs can be managed by editing the LDIF information for the entry. In LDIF format, an ACI looks like this:
aci: (target="ldap:///uid=mmichiel,dc=example,dc=com")(targetattr=*) (version 3.0; aci "aci1"; allow (write) userdn="ldap:///self";)
The version string identifier is required.
When an LDAP request comes in, this procedure is started:
The ACIs for the requested entry and all ACIs from that entry back up to the root are collected.
ACIs that don't apply are discarded.
Allow rules are separated from deny rules.
The request is evaluated against each applying deny rule.
If all deny tests are passed and the request still lives, it is checked against all allow rules. First matching rule is applied.
ACIs apply to a target and all of its children. Thus, ACIs are most often placed at branch points in the directory tree. It is advised not to place them on individual entries.
Wildcards are accepted, but cannot be specified in the suffix portion (dc= of the distinguished name.
Additionally, one or more attributes included in the target entry may be targetted. This is useful for allowing or denying access to partial information stored in an entry. The attributes specifying name, telephone number, E-mail address and such may be publicly accessible, while access to home address, password and other sensitive data is protected.
If no attributes are specified, the ACI is set on the entry itself, but not on particular attributes contained in this entry. This might be used to provide add and delete access rights to an entire entry, instead of access rights to particular attributes contained in the entry being controlled.
The target attribute can be equal or not equal to a specific attribute, using the = and != operators. Attributes should be recognized members of the directory schema, although they don't necessarily have to be allowed by the object class(es) of the targetted entry.
In addition to explicitly targetted entries and attributes, LDAP filters can be used to target a group of entries and/or attributes matching a certain criterion. See the Section called The ldapsearch tool in Chapter 3.
Permissions specify the type of access the ACI grants or denies. The various operations that can be assigned are called rights. Permissions are of the form:
allow|deny(rights)
The rights can be read, write, add, delete, compare, selfwrite, proxy, or all. Multiple rights can be specified separated by commas.
It is generally better to explicitly allow access to entries in the lower levels than to deny over a broader range higher up in the directory tree.
Use permissions sparingly in order to avoid confusion.
If two permissions exist in conflict with eachother, the permission that denies access always takes precedence over the permission that would grant the access.
The following list discusses the rights in detail:
read: indicates whether the data may be read.
write: indicates change, creation and delete permission. This does not include deletion of the entry itself.
search: differs from read in that the latter allows for data to be viewed if it is returned as part of a search operation. This is useful for creating "unresolvable" searches: you could for instance allow searching for people and include their telephone number in the result of a search, but it is not possible to search telephone numbers and link them with people.
compare: implies the ability to search, but the actual search result is not returned. Rather, a Boolean value, indicating the result of the search, is returned. This is commonly used for password authentication.
selfwrite: only for group management, allows users to subscribe themselves to or from a group.
proxy: indicated whether the specified entry can access the target with the rights of another entry.
add: if this right is granted, child entries can be created.
delete: allows users to delete the targetted entry.
Binding means logging in or authenticating to the directory. The identity of the user requesting access, the authentication method used, the time when the request occurs and the location from which the request is received define whether access is granted or denied. Every ACI has a bind rule that controls the conditions under which the ACI can be applied.
Bind rules use one of two possible patterns:
keyword = "expression"
keyword != "expression"
The expressions must evaluate true for the rule to be applied.
A bind rule can be configured so that the ACI only applies if the bind DN matches a DN in a specific attribute of the targetted directory.
Binding to users is done using the userdn keyword:
userdn = "ldap:///keyword"
The keyword can have the following values:
uid=: e.g. uid=*,dc=example,dc=com
self: the rule is true if the bind DN is the same as the entry for which access is requested.
all: everyone who has successfully bound to the directory server is granted the specified permission.
anyone: allows anonymous access.
parent: true if the bind DN is the immediate parent entry.
Binding as a member of a group is done specifying the groupdn keyword:
groupdn = "ldap:///cn=Administrators, dc=example,dc=com
Binding from a specific host is done using the ip keyword:
ip="192.168.21.*"
Individual IP addresses may be specified.
For binding from a specific domain, use the dns keyword:
dns="*.example.com"
Or use the != operator to exclude domains from binding:
dns!="*.evil.com"