The examples in this section illustrate how an imaginary ISP company, Example.com, would implement its access control policy.
In addition, you can find ACI examples in the example LDIF file provided with your installation, install_path/ds6/ldif/Example.ldif.
All of the examples explain how to perform a given task by using an LDIF file. The following figure shows the example.com Directory Information Tree in graphical form.
Example.com offers a web hosting service and internet access. Part of Example.com’s web-hosting service is to host the directories of client companies. Example.com actually hosts and partially manages the directories of two medium-sized companies, Company333 and Company999. Example.com also provides internet access to a number of individual subscribers.
Example.com wants to put the following access rules in place:
Grant anonymous read, search, and compare access to the entire Example.com tree for Example.com employees. See Granting Anonymous Access.
Grant write access to Example.com employees for personal information, such as homeTelephoneNumber, and homeAddress. See Granting Write Access to Personal Entries.
Grant Example.com subscribers the right to read the entry dc=example,dc=com for company contact information, but not to read any entries below it. See Granting Access to a Certain Level.
Grant Example.com employees the right to add any role to their entry, except certain critical roles. See Restricting Access to Key Roles.
Grant certain administrators the same rights as the Directory Manager for a suffix. See Granting a Role Full Access to an Entire Suffix.
Grant the Example.com Human Resources group all rights on the entries in the People branch. See Granting a Group Full Access to a Suffix.
Grant all Example.com employees the right to create group entries under the Social Committee branch of the directory, and to delete group entries that an employee owns. See Granting Rights to Add and Delete Group Entries.
Grant all Example.com employees the right to add themselves to group entries under the Social Committee branch of the directory. See Allowing Users to Add or Remove Themselves From a Group.
Grant access to the directory administrator (role) of Company333 and Company999 on their respective branches of the directory tree, with certain conditions. These conditions include SSL authentication, time and date restrictions, and specified location. See Granting Conditional Access to a Group or Role.
Grant individual subscribers access to their own entries. See Granting Write Access to Personal Entries.
Deny individual subscribers access to the billing information in their own entries. See Denying Access.
Grant anonymous access to the world to the individual subscribers subtree, except for subscribers who have specifically requested to be unlisted. If desired, this part of the directory could be a read-only server outside of the firewall, and be updated once a day. See Granting Anonymous Access and Setting a Target Using Filtering.
Most directories are configured to enable you to anonymously access at least one suffix for read, search, or compare. You might want to set these permissions if you are running a corporate personnel directory, such as a phone book that you want employees to be able to search. This is the case at Example.com internally, as shown in ACI “Anonymous Example.com”.
As an ISP, Example.com also wants to advertise the contact information of all of its subscribers by creating a public phone book that is accessible to the world. This is depicted in ACI “Anonymous World”.
In LDIF, to grant read, search, and compare permissions to the entire Example.com tree to Example.com employees, you would write the following statement:
aci: (targetattr !="userPassword")(version 3.0; acl "Anonymous example"; allow (read, search, compare) userdn= "ldap:///anyone") ;) |
This example assumes that the aci is added to the dc=example,dc=com entry. Note that the userPassword attribute is excluded from the scope of the ACI.
Protect attributes that are confidential and attributes that should not be visible using the same syntax used in the example to protect the password attribute, (targetattr !="attribute-name").
In LDIF, to grant read and search access of the individual subscribers subtree to the world, while denying access to information on subscribers who want to be unlisted, you could write the following statement:
aci: (targetfilter= "(!(unlistedSubscriber=yes))") (targetattr="homePostalAddress || homePhone || mail") (version 3.0; acl "Anonymous World"; allow (read, search) userdn="ldap:///anyone";) |
This example assumes that the ACI is added to the ou=subscribers,dc=example, dc=com entry. The example also assumes that every subscriber entry has an unlistedSubscriber attribute that is set to yes or no. The target definition filters out the unlisted subscribers based on the value of this attribute. For details on the filter definition, refer to Setting a Target Using Filtering.
Many directory administrators want to allow internal users to change some but not all of the attributes in their own entry. The directory administrators at Example.com want to allow users to change their own password, home telephone number, and home address, but nothing else. This is depicted in ACI “Write Example.com”.
Example.com also has a policy to let their subscribers update their own personal information in the Example.com tree provided that the subscribers establish an SSL connection to the directory. This is depicted in ACI “Write Subscribers”.
By setting this permission, you are also granting users the right to delete attribute values.
In LDIF, to grant Example.com employees the right to update their home telephone number and home address, you would write the following statement:
aci: (targetattr="homePhone || homePostalAddress")(version 3.0; acl "Write Example.com"; allow (write) userdn="ldap:///self" ;) |
This example assumes that the ACI is added to the ou=People,dc=example,dc=com entry.
By setting this permission, you are also granting users the right to delete attribute values.
In LDIF, to grant Example.com subscribers the right to update their home telephone number, you would write the following statement:
aci: (targetattr="homePhone") (version 3.0; acl "Write Subscribers"; allow (write) userdn= "ldap://self" and authmethod="ssl";) |
This example assumes that the aci is added to the ou=subscribers,dc=example, dc=com entry, and that users must bind using SSL.
Note that Example.com subscribers do not have write access to their home address because they might delete that attribute. The home address is business-critical information that Example.com needs for billing purposes.
You can set the scope of an ACI to affect different levels within your directory tree, to fine-tune the level of access you want to allow. The target ACI scope can be set to one of the following:
The entry itself
The entry itself and all entries one level below
The entry itself and all entries beneath that entry, to an unlimited depth
In LDIF, to grant Example.com subscribers the right to read the entry dc=example,dc=com for company contact information, but not allow access to any entries below it, you would write the following statement:
aci: (targetscope="base") (targetattr="*")(version 3.0; acl "Read Example.com only"; allow (read,search,compare) userdn="ldap:///cn=*,ou=subscribers,dc=example,dc=com";) |
This example assumes that the ACI is added to the dc=example, dc=com entry.
You can use role definitions in the directory to identify functions that are critical to your business, such as the administration of your network and directory.
For example, you might create a superAdmin role by identifying a subset of your system administrators who are available at a particular time of day and day of the week at corporate sites worldwide. Or you might want to create a First Aid role that includes all staff members who have first aid training at a particular site. For information about creating role definitions see Managing Roles.
When a role gives any sort of privileged user rights over critical corporate or business functions, consider restricting access to that role. For example, at Example.com, employees can add any role to their own entry, except the superAdmin role, as shown in the following example.
In LDIF, to grant Example.com employees the right to add any role to their own entry, except the superAdmin role, you would write the following statement:
aci: (targetattr="*") (targattrfilters="add=nsRoleDN: (nsRoleDN !="cn=superAdmin, dc=example, dc=com")") (version 3.0; acl "Roles"; allow (write) userdn= "ldap:///self" ;) |
This example assumes that the ACI is added to the ou=People,dc=example, dc=com entry.
Sometimes it is useful to grant certain users the same rights as the Directory Manager for a suffix. At Example.com, Kirsten Vaughan is an administrator for Directory Server. She has a role of superAdmin. This role has the following advantages:
Better security because administrators binding as themselves can be forced to use strong authentication such as SSL
Better security because the Directory Manager password is known by fewer people
More traceability through logging
Adding Kirsten Vaughan to the cn=Administrators,cn=config group would also grant her the same rights as Directory Manager.
To give a user the same rights as the Directory Manager for the whole server, follow the procedure in To Create an Administration User with Root Access.
In LDIF, to grant the administrator Kirsten Vaughan the same rights as a Directory Manager, use the following statement:
aci: (targetattr="*") (version 3.0; acl "Full Access"; allow (all) groupdn= "ldap:///cn=SuperAdmin,dc=example,dc=com" and authmethod="ssl" ;) |
This example assumes that the ACI is added to the root entry "" (no text).
Most directories have groups that are used to identify certain corporate functions. A group can be given access to all or part of the directory. By applying access rights to a group, you can avoid setting access rights for each member individually. Instead, you grant users access rights by adding them to a group.
For example, when you create a Directory Server instance, an Administrators group cn=Administrators,cn=config with full access to the directory is created by default.
At Example.com, the Human Resources group is allowed full access to the ou=People branch of the directory so that they can update the employee directory, as shown in ACI “HR”.
In LDIF, to grant the HR group all rights to the employee branch of the directory, you would use the following statement:
aci: (targetattr="*") (version 3.0; acl "HR"; allow (all) groupdn= "ldap:///cn=HRgroup,ou=Groups,dc=example,dc=com";) |
This example assumes that the ACI is added to the following entry:
ou=People,dc=example,dc=com |
Some organizations allow employees to create entries in the tree to increase employees' efficiency and to encourage employees to contribute to the corporate dynamics. At Example.com, for example, the social committee is organized into various clubs, such as tennis, swimming, skiing, and role-playing.
Any Example.com employee can create a group entry that represents a new club, as shown in ACI “Create Group”.
Any Example.com employee can become a member of one of these groups, as shown in Allowing Users to Add or Remove Themselves From a Group.
Only the group owner can modify or delete a group entry, as shown in ACI “Delete Group”.
In LDIF, to grant Example.com employees the right to create a group entry under the ou=Social Committee branch, you would write the following statement:
aci: (targetattr="*") (targattrfilters="add=objectClass: (|(objectClass=groupOfNames)(objectClass=top))") (version 3.0; acl "Create Group"; allow (read,search,add) userdn= "ldap:///uid=*,ou=People,dc=example,dc=com") and dns="*.Example.com";) |
This example assumes that the ACI is added to the ou=Social Committee,dc=example,dc=com entry.
This ACI does not grant write permission, which means that the entry creator cannot modify the entry.
Because the server adds the value top behind the scenes, you need to specify objectClass=top in the targattrfilters keyword.
This ACI restricts the client machine to be in the example.comdomain.
In LDIF, to grant Example.com employees the right to modify or delete a group entry of the group to which they belong under the ou=Social Committee branch, you would write the following statement:
aci: (targetattr = "*") (targattrfilters="del=objectClass: (objectClass=groupOfNames)") (version 3.0; acl "Delete Group"; allow (write,delete) userattr="owner#GROUPDN";) |
This example assumes that the aci is added to the ou=Social Committee,dc=example,dc=com entry.
Note that to use DSCC to create this ACI is not very effective because you have to use manual editing mode to create the target filter and to check group ownership.
Many directories set ACIs that allow users to add or remove themselves from groups such as mailing lists.
At Example.com, employees can add themselves to any group entry under the ou=Social Committee subtree, as shown in ACI “Group Members”.
In LDIF, to grant Example.com employees the right to add themselves to a group, you would write the following statement:
aci: (targettattr="member")(version 3.0; acl "Group Members"; allow (selfwrite) (userdn= "ldap:///uid=*,ou=People,dc=example,dc=com") ;) |
This example assumes that the ACI is added to the ou=Social Committee, dc=example,dc=com entry.
In many cases, when you grant a group or role privileged access to the directory, you must ensure that those privileges are protected from intruders trying to impersonate your privileged users. Therefore, in many cases, access control rules that grant critical access to a group or role are often associated with a number of conditions.
Example.com, for example, has created a Directory Administrator role for each of its hosted companies, Company333 and Company999. Example.com wants these companies to be able to manage their own data and implement their own access control rules while securing the data against intruders.
For this reason, Company333 and Company999 have full rights on their respective branches of the directory tree, provided that the following conditions are fulfilled:
The connection is authenticated using a certificate over SSL.
Access is requested between 8:00 and 18:00, Monday through Thursday.
Access is requested from a specified IP address for each company.
These conditions are depicted in one ACI for each company, ACI “Company333” and ACI “Company999”. Because the content of both ACIs is the same, the following examples use the “Company333” ACI only.
In LDIF, to grant Company333 full access to its own branch of the directory under the conditions stated previously, you would write the following statement:
aci: (targetattr = "*") (version 3.0; acl "Company333"; allow (all) (roledn="ldap:///cn=DirectoryAdmin,ou=Company333, ou=corporate clients,dc=example,dc=com") and (authmethod="ssl") and (dayofweek="Mon,Tues,Wed,Thu") and (timeofday >= "0800" and timeofday <= "1800") and (ip="255.255.123.234"); ) |
This example assumes that the ACI is added to the ou=Company333,ou=corporate clients,dc=example,dc=com entry.
If you have already allowed access to a large part of your suffix, you might want to deny access to a smaller part of the suffix beneath the existing ACI.
Denying access should be avoided where possible, because it can lead to surprising or complicated access control behavior. Restrict access by using a combination of scoping, attribute lists, target filters and so on.
Also, deleting a deny access ACI does not remove rights, but instead expands the rights set by other ACIs.
When the Directory Server evaluates access rights, it reads deny rights first, then allow rights.
In the examples that follow, Example.com wants all subscribers to be able to read billing information, such as connection time or account balance, under their own entries. Example.com also explicitly wants to deny write access to that information. The read access is depicted in ACI “Billing Info Read”. The deny access is depicted in ACI “Billing Info Deny”.
In LDIF, to grant subscribers permission to read billing information in their own entry, you would write the following statement:
aci: (targetattr="connectionTime || accountBalance") (version 3.0; acl "Billing Info Read"; allow (search,read) userdn="ldap:///self";) |
This example assumes that the relevant attributes have been created in the schema and that the ACI is added to the ou=subscribers,dc=example,dc=com entry.
In LDIF, to deny subscribers permission to modify billing information in their own entry, you would write the following statement:
aci: (targetattr="connectionTime || accountBalance") (version 3.0; acl "Billing Info Deny"; deny (write) userdn="ldap:///self";) |
This example assumes that the relevant attributes have been created in the schema and that the ACI is added to the ou=subscribers,dc=example,dc=com entry.
The proxy authorization method is a special form of authentication. A user that binds to the directory by using his or her own identity is granted the rights of another user through proxy authorization.
To configure Directory Server to allow proxy requests you must do the following:
Grant the administrators the right to proxy as other users.
Grant your regular users normal access rights as defined in your access control policy.
You can grant proxy rights to any users of the directory except the Directory Manager. In addition, you cannot use the Directory Manager’s DN as a proxy DN. You need to exercise great care when granting proxy rights because you grant the right to specify any DN (except the Directory Manager DN) as the proxy DN. If Directory Server receives more than one proxied authentication control in the same operation, an error is returned to the client application and the operation attempt is unsuccessful.
Example.com wants the client application that binds as MoneyWizAcctSoftware to have the same access rights to the LDAP data as an Accounting Administrator.
The following parameters apply:
The client application’s bind DN is uid=MoneyWizAcctSoftware, ou=Applications,dc=example,dc=com.
The targeted subtree to which the client application is requesting access is ou=Accounting,dc=example,dc=com.
An Accounting Administrator with access permissions to the ou=Accounting,dc=example,dc=com subtree exists in the directory.
For the client application to gain access to the Accounting subtree, by using the same access permissions as the Accounting Administrator, the following must be true:
The Accounting Administrator must have access permissions to the ou=Accounting,dc=example,dc=com subtree. For example, the following ACI grants all rights to the Accounting Administrator entry:
aci: (targetattr="*") (version 3.0; acl "allowAll-AcctAdmin"; allow (all) userdn="ldap:///uid=AcctAdministrator,ou=Administrators, dc=example,dc=com";) |
The following ACI that grants proxy rights to the client application must exist in the directory:
aci: (targetattr="*") (version 3.0; acl "allowproxy- accountingsoftware"; allow (proxy) userdn= "ldap:///uid=MoneyWizAcctSoftware,ou=Applications, dc=example,dc=com";) |
With this ACI in place, the MoneyWizAcctSoftware client application can bind to the directory and then send an LDAP command, such as ldapsearch or ldapmodify, that requires the access rights of the proxy DN.
In this example, if the client wanted to perform an ldapsearch command, the command would include the following controls:
$ ldapsearch -D "uid=MoneyWizAcctSoftware,ou=Applications,dc=example,dc=com" -w - \ -Y "dn: uid=AcctAdministrator,ou=Administrators,dc=example,dc=com" ... |
If the client wanted to perform an ldapmodify command, the command would include the following controls:
$ ldapmodify -h hostname -p port \ -D "uid=MoneyWizAcctSoftware,ou=Applications,dc=example,dc=com" -w - \ -Y"dn: uid=AcctAdministrator,ou=Administrators,dc=example,dc=com" dn: uid=AcctAdministrator,ou=Administrators,dc=example,dc=com changetype: modify delete: userpassword - add: userpassword userpassword: admin1 |
Note that the client binds as itself, but is granted the privileges of the proxy entry. The client does not need the password of the proxy entry.
If you want to set access controls that allow access to a number of entries that are spread across the directory, you might want to use a filter to set the target.
In LDIF, to use a filter to allow all users in HR access to employee entries, you would write the following statement:
aci: (targetattr="*") (targetfilter=(objectClass=employee)) (version 3.0; acl "HR access to employees"; allow (all) groupdn= "ldap:///cn=HRgroup,ou=People,dc=example,dc=com";) |
This example assumes that the ACI is added to the ou=People,dc=example,dc=com entry.
Because search filters do not directly name the object for which you are managing access, try not to allow or deny access to the wrong objects. Unintentionally allowing or denying access to the wrong objects becomes more of a risk as your directory becomes more complex. Additionally, filters can make it difficult for you to troubleshoot access control problems within your directory.
DNs that contain commas require special treatment within your LDIF ACI statements. In the target and bind rule portions of the ACI statement, commas must be escaped by a single backslash (\). The following example illustrates this syntax:
dn: o=Example.com Bolivia\, S.A. objectClass: top objectClass: organization aci: (target="ldap:///o=Example.com Bolivia\,S.A.") (targetattr="*") (version 3.0; acl "aci 2"; allow (all) groupdn = "ldap:///cn=Directory Administrators, o=Example.com Bolivia\, S.A.";) |