Administrator’s Guide
Red Hat Directory Server                                                            

Previous
Contents
Index
Next

Chapter 6

Managing Access Control


Red Hat Directory Server (Directory Server) provides you with the ability to control access to your directory. This chapter describes the access control mechanism.

This section includes the following topics:

To take full advantage of the power and flexiblity of the access control mechanism, while you are in the planning phase for your directory deployment, you should define an access control strategy as an integral part of your overall security policy. Refer to Red Hat Directory Server Deployment Guide for tips on planning your access control strategy.

Access Control Principles

The mechanism by which you define access is called access control. When the server receives a request, it uses the authentication information provided by the user in the bind operation and the access control instructions (ACIs) defined in the server to allow or deny access to directory information. The server can allow or deny permissions such as read, write, search, and compare. The permission level granted to a user may be dependent on the authentication information provided.

Using access control, you can control access to the entire directory, a subtree of the directory, specific entries in the directory (including entries defining configuration tasks), or a specific set of entry attributes. You can set permissions for a specific user, all users belonging to a specific group or role, or all users of the directory. Finally, you can define access for a specific location such as an IP address or a DNS name.

ACI Structure

Access control instructions are stored in the directory as attributes of entries. The aci attribute is an operational attribute; it is available for use on every entry in the directory, regardless of whether it is defined for the object class of the entry. It is used by the Directory Server to evaluate what rights are granted or denied when it receives an LDAP request from a client. The aci attribute is returned in an ldapsearch operation if specifically requested.

The three main parts of an ACI statement are:

The permission and bind rule portions of the ACI are set as a pair, also called an Access Control Rule (ACR). The specified permission is granted or denied depending on whether the accompanying rule is evaluated to be true.

ACI Placement

If an entry containing an ACI does not have any child entries, the ACI applies to that entry only. If the entry has child entries, the ACI applies to the entry itself and all entries below it. As a direct consequence, when the server evaluates access permissions to any given entry, it verifies the ACIs for every entry between the one requested and the directory suffix, as well as the ACIs on the entry itself.

The aci attribute is multi-valued, which means that you can define several ACIs for the same entry or subtree.

You can create an ACI on an entry that does not apply directly to that entry but to some or all of the entries in the subtree below it. The advantage of this is that you can place at a high level in the directory tree a general ACI that effectively applies to entries more likely to be located lower in the tree. For example, at the level of an organizationalUnit entry or a locality entry, you could create an ACI that targets entries that include the inetorgperson object class.

You can use this feature to minimize the number of ACIs in the directory tree by placing general rules at high level branch points. To limit the scope of more specific rules, you should place them as close as possible to leaf entries.

Note

ACIs placed in the root DSE entry apply only to that entry.


ACI Evaluation

To evaluate the access rights to a particular entry, the server compiles a list of the ACIs present on the entry itself and on the parent entries back up to the top level entry stored on the Directory Server. ACIs are evaluated across all of the databases for a particular Directory Server but not across Directory Servers.

The evaluation of this list of ACIs is done based on the semantics of the ACIs, not on their placement in the directory tree. This means that ACIs that are close to the root of the directory tree do not take precedence over ACIs that are closer to the leaves of the directory tree.

The precedence rule that applies is that ACIs that deny access take precedence over ACIs that allow access. Between ACIs that allow access, union semantics apply, so there is no precedence.

For example, if you deny write permission at the directory's root level, then none of the users can write to the directory, regardless of the specific permissions you grant them. To grant a specific user write permissions to the directory, you have to restrict the scope of the original denial for write permission so that it does not include the user.

ACI Limitations

When creating an access control policy for your directory service, you need to be aware of the following restrictions:

However, you can do value matching of values stored in the target entry with values stored in the entry of the bind user (for example, using the userattr keyword). Access will be evaluated normally even if the bind user does not have an entry on server that holds the ACI.
For more information on how to chain access control evaluation, see "Database Links and Access Control Evaluation," on page 123.
If you create target filters or bind rules that depend on the value of attributes generated by CoS, the access control rule will not work. For more information on CoS, see Chapter 5, "Advanced Entry Management."

Default ACIs

When you install the Directory Server, the following default ACIs apply to your directory information stored in the userRoot database:

Whenever you create a new database in the directory, the top entry has the default ACIs listed above.

The NetscapeRoot subtree has its own set of default ACIs:

The following sections explain how to modify these default settings to suit the needs of your organization.

Creating ACIs Manually

You can create access control instructions manually using LDIF statements and add them to your directory tree using the ldapmodify utility. The following sections explain in detail how to create the LDIF statements.

Tip

LDIF ACI statements can be very complex. However, if you are setting access control for a large number of directory entries, using LDIF is the preferred method over using the Console because of the time it can save.

To familiarize yourself with LDIF ACI statements, however, you may want to use the Directory Server Console to set the ACI and then click the Edit Manually button on the Access Control Editor. This shows you the correct LDIF syntax. If your operating system allows it, you can even copy the LDIF from the Access Control Editor and paste it into your LDIF file.


The ACI Syntax

The aci attribute uses the following syntax:

aci: (target)(version 3.0;acl "name";permission bind_rules;)
 

where

You can have multiple permission-bind rule pairs for each target. This allows you to set multiple access controls for a given target efficiently. For example:

target(permission bind_rule)(permission bind_rule)...
 

If you have several ACRs in one ACI statement, the syntax is of the form:

aci: (target)(version 3.0;acl "name";permission bind_rule; permission 
bind_rule; ... permission bind_rule;)
 

Example ACI

The following is an example of a complete LDIF ACI:

aci: 
(target="ldap:///uid=bjensen,dc=example,dc=com")(targetattr=*)

(version 3.0;acl "aci1";allow (write) userdn="ldap:///self";)
 

In this example, the ACI states that the user bjensen has rights to modify all attributes in her own directory entry.

The following sections describe the syntax of each portion of the ACI in more detail.

Defining Targets

The target identifies to what the ACI applies. If the target is not specified, the ACI applies to the entry containing the aci attribute and to the entries below it.

A target can be:

The general syntax for a target is:

(keyword = "expression")
 
(keyword != "expression")
 

where:

The quotation marks ("") around expression are required. What you use for expression is dependent upon the keyword that you supply.

The following table lists each keyword and the associated expressions:

Table 6-1 LDIF Target Keywords  
Keyword
Valid Expressions
Wildcard
Allowed?
ldap:///distinguished_name
yes
attribute
yes
LDAP_filter
yes
LDAP_operation:LDAP_filter
yes

In all cases, you must keep in mind that when you place an ACI on an entry, if it is not a leaf entry, the ACI also applies to all entries below it. For example, if you target the entry ou=accounting,dc=example,dc=com, the permissions you set will apply to all entries in the accounting branch of the example.com tree.

As a counter example, if you place an ACI on the ou=accounting,dc=example,dc=com entry, you cannot target the uid=sarette,ou=people,dc=example,dc=com entry because it is not located under the accounting tree.

Be wary of using != when specifying an attribute you want to deny. ACLs are logically ORed, which means that if you created two ACLs

acl1: ( target=...)( targetattr!=a )(version 3.0; acl 
"name";allow (...)..
 
acl2: ( target=...)( targetattr!=b )(version 3.0; acl 
"name";allow (...)..
 

the result would be to allow all values of the target attribute. The first ACL (acl1) will allow b and the second ACL (acl2) will allow a. The result of these two ACLs will be the same as the one resulting from using an ACL of the form:

acl3: ( targetattr="*" ) allow (...) ...
 

Notice that nothing is denied. This could give rise to security problems.

When you want to deny access to a particular attribute, use deny in the permissions clause rather than using allow with ( targetattr != value ). For example, usages such as these are recommended:

acl1: ( target=...)( targetattr=a )(version 3.0; acl "name";deny 
(...)..
 
acl2: ( target=...)( targetattr=b )(version 3.0; acl "name";deny 
(...)..
 

Targeting a Directory Entry

To target a directory entry (and the entries below it), you must use the target keyword.

The target keyword can accept a value of the following format:

target="ldap:///distinguished_name"
 

This identifies the distinguished name of the entry to which the access control rule applies. For example:

(target = "ldap:///uid=bjensen,dc=example,dc=com")
 
Note

If the DN of the entry to which the access control rule applies contains a comma, you must escape the comma with a single backslash (\). For example:

(target="ldap:///uid=lfuentes,dc=example.com 
Bolivia\,S.A.")
 

You can also use a wildcard when targeting a distinguished name using the target keyword. The wildcard indicates that any character or string or substring is a match for the wildcard. Pattern matching is based on any other strings that have been specified with the wildcard.

The following are legal examples of wildcard usage:

Matches every entry in the entire example.com tree that has the uid attribute in the entry's RDN.
Matches every entry directly under the example.com node with a uid ending in Anderson.
Matches every entry directly under the example.com node with a uid beginning with C and ending with A.

Depending on the position of the wildcard, it can apply to the full DN, not only to attribute values. Therefore, the wildcard can be used as a substitute for portions of the DN. For example, uid=andy*,dc=example,dc=com targets all the directory entries in the entire example.com tree with a matching uid attribute and not just the entries that are immediately below the dc=example,dc=com node. In other words, this target matches with longer expressions such as uid=andy,ou=eng,dc=example,dc=com , or uid=andy,ou=marketing,dc=example,dc=com.

Some other valid examples follow:

Matches every entry in the entire example.com tree that has the uid attribute in the entry's RDN.
Matches every entry in the example.com tree whose distinguished name contains the uid and ou attributes. Thus:
uid=fchen,ou=Engineering,dc=example,dc=com
or
uid=claire,ou=Engineering,ou=people,dc=example,dc=com
would match, but the following would not:
uid=bjensen,dc=example,dc=com
ou=Engineering,dc=example,dc=com
Note

You cannot use wildcards in the suffix part of a distinguished name. That is, if your directory uses the suffixes c=US and c=GB, then you cannot use the following target to reference both suffixes:

(target="ldap:///dc=example,c=*").
 

Neither can you use a target such as uid=bjensen,dc=*.com.


Targeting Attributes

In addition to targeting directory entries, you can also target one or more attributes included in the targeted entries. This is useful when you want to deny or allow access to partial information about an entry. For example, you could allow access to only the common name, surname, and telephone number attributes of a given entry. Or you could deny access to sensitive information such as passwords.

You can specify that the target is equal or is not equal to a specific attribute. The attributes you supply do not need to be defined in the schema. This absence of schema checking makes it possible to implement an access control policy when you set up your directory service for the first time, even if the ACLs you create do not apply to the current directory content.

To target attributes, you use the targetattr keyword. The keyword uses the following syntax:

(targetattr = "attribute")
 

You can target multiple attributes by using the targetattr keyword with the following syntax:

(targetattr = "attribute1 || attribute2 ... || attributen")
 

Where attribute is the name of the attribute you want to target.

For example, to target the common name attribute you would use:

(targetattr = "cn")
 

To target an entry's common name, surname, and uid attributes, you would use the following:

(targetattr = "cn || sn || uid")
 

The attributes specified in the targetattr keyword apply to the entry that the ACI is targeting and to all the entries below it. If you target the password attribute on the entry uid=bjensen,ou=Marketing,dc=example,dc=com, only the password attribute on the bjensen entry is affected by the ACI because it is a leaf entry.

If, however, you target the tree's branch point ou=Marketing,dc=example,dc=com, then all the entries beneath the branch point that can contain a password attribute are affected by the ACI.

Targeting Both an Entry and Attributes

By default, the entry targeted by an ACI containing a targetattr keyword is the entry on which the ACI is placed. That is, if you put the ACI

aci: (targetattr = "uid")(access_control_rules;)
 

on the ou=Marketing, dc=example,dc=com entry, then the ACI applies to the entire Marketing subtree. However, you can also explicitly specify a target using the target keyword as follows:

aci: (target="ldap:///ou=Marketing, 
dc=example,dc=com")(targetattr="uid") (access_control_rules;)
 

The order in which you specify the target and the targetattr keywords is not important.

Targeting Entries or Attributes Using LDAP Filters

You can use LDAP filters to target a group of entries that match certain criteria. To do this, you must use the targetfilter keyword with an LDAP filter.

The syntax of the targetfilter keyword is:

(targetfilter = "LDAP_filter")
 

where LDAP_filter is a standard LDAP search filter. For more information on the syntax of LDAP search filters, see Appendix B, "Finding Directory Entries."

For example, suppose that all entries in the accounting department include the attribute-value pair ou=accounting, and all entries in the engineering department include the attribute-value pair ou=engineering subtree. To target all the entries in the accounting and engineering branches of the directory tree, you could use the following filter:

(targetfilter = "(|(ou=accounting)(ou=engineering))")
 

This type of filter targets whole entries. You can associate the targetfilter and the targetattr keywords to create ACIs that apply to a subset of attributes in the targeted entries.

The following LDIF example allows members of the Engineering Admins group to modify the departmentNumber and manager attributes of all entries in the Engineering business category. This example uses LDAP filtering to select all entries with businessCategory attributes set to Engineering:

dn: dc=example,dc=com

objectClass: top

objectClass: organization

aci: (targetattr="departmentNumber || manager")

(targetfilter="(businessCategory=Engineering)")

(version 3.0; acl "eng-admins-write"; allow (write)

groupdn ="ldap:///cn=Engineering Admins, dc=example,dc=com";)
 
Tip

Although using LDAP filters can be useful when you are targeting entries and attributes that are spread across the directory, the results are sometimes unpredictable because filters do not directly name the object for which you are managing access. The set of entries targeted by a filtered ACI is likely to change as attributes are added or deleted. Therefore, if you use LDAP filters in ACIs, you should verify that they target the correct entries and attributes by using the same filter in an ldapsearch operation.


Targeting Attribute Values Using LDAP Filters

You can use access control to target specific attribute values. This means that you can grant or deny permissions on an attribute if that attribute's value meets the criteria defined in the ACI. An ACI that grants or denies access based on an attribute's value is called a value-based ACI.

For example, you might grant all users in your organization permission to modify the nsRoleDN attribute in their own entry. However, you would also want to ensure that they do not give themselves certain key roles, such as "Top Level Administrator." LDAP filters are used to check that the conditions on attribute values are satisfied.

To create a value-based ACI, you must use the targattrfilters keyword with the following syntax:

(targattrfilters="add=attr1:F1 && attr2:F2... && attrn:Fn,del=attr1:F1 
&& attr2:F2 ... && attrn:Fn")
 

where:

When creating an entry, if a filter applies to an attribute in the new entry, then each instance of that attribute must satisfy the filter. When deleting an entry, if a filter applies to an attribute in the entry, then each instance of that attribute must also satisfy the filter.

When modifying an entry, if the operation adds an attribute, then the add filter that applies to that attribute must be satisfied; if the operation deletes an attribute, then the delete filter that applies to that attribute must be satisfied. If individual values of an attribute already present in the entry are replaced, then both the add and delete filters must be satisfied.

For example consider the following attribute filter:

(targattrfilters="add=nsroleDN:(!(nsRoleDN=cn=superAdmin)) && 
telephoneNumber:(telephoneNumber=123*)")
 

This filter can be used to allow users to add any role (nsRoleDN attribute) to their own entry, except the superAdmin role. It also allows users to add a telephone number with a 123 prefix.

Note

You cannot create value-based ACIs from the Server Console.


Targeting a Single Directory Entry

Targeting a single directory entry is not straightforward because it goes against the design philosophy of the access control mechanism. However, it can be done:

You can use the targetattr keyword to specify an attribute that is only present in the entry you want to target, and not in any of the entries below your target. For example, if you want to target ou=people,dc=example,dc=com, and there aren't any organizational units (ou) defined below that node, you could specify an ACI that contains:

targetattr=ou
 

A safer method is to use the targetfilter keyword and to specify explicitly an attribute value that appears in the entry alone. For example, during the installation of the Directory Server, the following ACI is created:

aci: (targetattr="*")(targetfilter=(o=NetscapeRoot))(version 
3.0; acl "Default anonymous access"; allow (read, search) 
userdn="ldap:///anyone";)
 

This ACI can apply only to the o=NetscapeRoot entry.

The risk associated with these method is that your directory tree might change in the future, and you would have to remember to modify this ACI.

Defining Permissions

Permissions specify the type of access you are allowing or denying. You can either allow or deny permission to perform specific operations in the directory. The various operations that can be assigned are known as rights.

There are two parts to setting permissions:

Allowing or Denying Access

You can either explicitly allow or deny access permissions to your directory tree. For more guidelines on when to allow and when to deny access, refer to the Red Hat Directory Server Deployment Guide.

Note

From the Server Console, you cannot explicitly deny access, only grant permissions.


Assigning Rights

Rights detail the specific operations a user can perform on directory data. You can allow or deny all rights, or you can assign one or more of the following rights:

Rights are granted independently of one another. This means, for example, that a user who is granted add rights can create an entry but cannot delete it if delete rights have not been specifically granted. Therefore, when planning the access control policy for your directory, you must ensure that you grant rights in a way that makes sense for users. For example, it doesn't usually make sense to grant write permission without granting read and search permissions.

Note

The proxy mechanism is very powerful and must be used sparingly. Proxy rights are granted within the scope of the ACL, and there is no way to restrict who an entry that has the proxy right can impersonate-that is, when you grant a user proxy rights, that user has the ability to proxy for any user under the target; there is no way to restrict the proxy rights to only certain users. For example, if an entity has proxy rights to the dc=example,dc=com tree, that entity can do anything. So, make sure you set the proxy ACI at the lowest possible level of the DIT; see "Proxied Authorization ACI Example," on page 266.

For a general overview, see "Proxy Authentication" in chapter 7, "Designing a Secure Directory,"in the Red Hat Directory Server Deployment Guide.


Rights Required for LDAP Operations

This section describes the rights you need to grant to users depending on the type of LDAP operation you want to authorize them to perform.

The permissions you need to set up to allow users to search the directory are more readily understood with an example. Consider the following ldapsearch operation:

% ldapsearch -h host -s base -b "uid=bkolics,dc=example,dc=com" 
objectclass=* mail
 

The following ACI is used to determine whether user bkolics can be granted access:

aci: (targetattr = "mail")(version 3.0; acl "self access to 
mail"; allow (read, search) userdn = "ldap:///self";)
 

The search result list is empty because this ACI does not grant access to the objectclass attribute. If you want the search operation described above to be successful, you must modify the ACI to read as follows:

aci: (targetattr = "mail || objectclass")(version 3.0; acl "self 
access to mail"; allow (read, search) userdn = "ldap:///self";)
 

Permissions Syntax

In an ACI statement, the syntax for permissions is:

allow|deny (rights)
 

where rights is a list of 1 to 8 comma-separated keywords enclosed within parentheses. Valid keywords are read, write, add, delete, search, compare, selfwrite, proxy, or all.

In the following example, read, search, and compare access is allowed, provided the bind rule is evaluated to be true:

aci:  (target="ldap:///dc=example,dc=com") (version 3.0;acl 
"example";

allow (read, search, compare) bind_rule;)
 

Access Control and the modrdn Operation

To explicitly deny modrdn rights using ACIs, you must target the relevant entries but omit the targetattr keyword. For example, to prevent the cn=helpDeskGroup,ou=groups,o=example.com group from renaming any entries in the set specified by the pattern cn=*,ou=people,o=example.com, you would add the following ACI:

aci: (target="ldap:///cn=*,ou=people,o=example.com")

(version 3.0; acl "Deny modrdn rights to the helpDeskGroup";

deny(write) 
groupdn="ldap:///cn=helpDeskGroup,ou=groups,o=example.com";)
 

Bind Rules

Depending on the ACIs defined for the directory, for certain operations, you need to bind to the directory. Binding means logging in or authenticating yourself to the directory by providing a bind DN and password, or, if using SSL, a certificate. The credentials provided in the bind operation and the circumstances of the bind determine whether access to the directory is allowed or denied.

Every permission set in an ACI has a corresponding bind rule that details the required credentials and bind parameters.

Bind rules can be simple. For example, a bind rule can simply state that the person accessing the directory must belong to a specific group. Bind rules can also be more complex. For example, a bind rule can state that a person must belong to a specific group and must log in from a machine with a specific IP address, between 8 a.m. and 5 p.m.

Bind rules define who can access the directory, when, and from where. More specifically, bind rules can specify:

Additionally, bind rules can be complex constructions that combine these criteria by using Boolean operators. See "Using Boolean Bind Rules," on page 241, for more information.

Bind Rule Syntax

Whether access is allowed or denied depends on whether an ACI's bind rule is evaluated to be true. Bind rules use one of the two following patterns:

keyword = "expression";
 
keyword != "expression";
 

where equal (=) indicates that keyword and expression must match in order for the bind rule to be true, and not equal (!=) indicates that keyword and expression must not match in order for the bind rule to be true.

Note

The timeofday keyword also supports the inequality expressions (<, <=, >, >=). This is the only keyword that supports these expressions.


The quotation marks ("") around expression and the delimiting semicolon (;) are required. The expressions you can use depend on the associated keyword.

The following table lists each keyword and the associated expressions. It also indicates whether wildcard characters are allowed in the expression.

Table 6-2 LDIF Bind Rule Keywords  
Keyword
Valid Expressions
Wildcard Allowed?
ldap:///distinguished_name
ldap:///all
ldap:///anyone
ldap:///self
ldap:///parent
ldap:///suffix??sub?(filter)
yes, in DN only
ldap:///DN || DN
no
ldap:///DN || DN
no
attribute#bindType or
attribute#value
no
IP_address
yes
DNS_host_name
yes
sun
mon
tue
wed
thu
fri
sat
no
0 - 2359
no
none
simple
ssl
sasl authentication_method
no

The sections that follow contain further detail on bind rule syntax for each keyword.

Defining User Access - userdn Keyword

User access is defined using the userdn keyword. The userdn keyword requires one or more valid distinguished names in the following format :

userdn = "ldap:///dn [|| ldap:///dn]...[||ldap:///dn]"
 

where dn can be a DN or one of the expressions anyone, all, self, or parent:

userdn = "ldap:///anyone" - defines anonymous access
 
userdn = "ldap:///all" - defines general access
 
userdn = "ldap:///self" - defines self access
 
userdn = "ldap:///parent" - defines access for the parent entry
 

The userdn keyword can also be expressed as an LDAP filter of the form:

ldap:///suffix??sub?(filter)
 
Note

If a DN contains a comma, the comma must be preceded by a backslash (\) escape character.


Anonymous Access (anyone Keyword)

Granting anonymous access to the directory means that anyone can access it without providing a bind DN or password and regardless of the circumstances of the bind. You can limit anonymous access to specific types of access (for example, access for read or access for search) or to specific subtrees or individual entries within the directory.

From the Server Console, you define anonymous access through the Access Control Editor. See "Creating ACIs from the Console," on page 242.

General Access (all Keyword)

You can use bind rules to indicate that a permission applies to anyone who has successfully bound to the directory; that is, all authenticated users. This allows general access while preventing anonymous access.

From the Server Console, you define general access on the Access Control Editor. For more information, see "Creating ACIs from the Console," on page 242.

Self Access (self Keyword)

Specifies that users are granted or denied access to their own entries. In this case, access is granted or denied if the bind DN matches the DN of the targeted entry.

From the Server Console, you set up self access on the Access Control Editor. For more information, see "Creating ACIs from the Console," on page 242.

Parent Access (parent Keyword)

Specifies that users are granted or denied access to the entry only if their bind DN is the parent of the targeted entry.

You cannot set up parent access control using the Server Console.

LDAP URLs

You can dynamically target users in ACIs using a URL with a filter as follows:

userdn = "ldap:///<suffix>??sub?(filter)"
 

For example, all users in the accounting and engineering branches of the example.com tree would be granted or denied access to the targeted resource dynamically based on the following URL:

userdn = "ldap:///dc=example,dc=com??sub?(|(ou=engineering)

(ou=accounting))"
 
Note

Do not specify a hostname or port number within the LDAP URL. LDAP URLs always apply to the local server.


For more information about LDAP URLs, see Appendix C, "LDAP URLs."

Wildcards

You can also specify a set of users by using the wildcard character (*). For example, specifying a user DN of uid=u*,dc=example,dc=com indicates that only users with a bind DN beginning with the letter u will be allowed or denied access based on the permissions you set.

From the Server Console, you set user access from the Access Control Editor. For more information, see "Creating ACIs from the Console," on page 242.

Examples

This section contains examples of the userdn syntax.

userdn = "ldap:///uid=*,dc=example,dc=com";
 
The bind rule is evaluated to be true if the user binds to the directory using any distinguished name of the specified pattern. For example, both of the following bind DNs would be evaluated to be true:
uid=ssarette,dc=example,dc=com

uid=tjaz,ou=Accounting,dc=example,dc=com
 
whereas the following bind DN would be evaluated to be false:
cn=Babs Jensen,dc=example,dc=com
 
userdn="ldap:///uid=bj,c=example.com || 
ldap:///uid=kc,dc=example,dc=com";
 
The bind rule is evaluated to be true if the client binds as either of the two supplied distinguished names.
userdn != "ldap:///uid=*,ou=Accounting,dc=example,dc=com";
 
The bind rule is evaluated to be true if the client is not binding as a UID-based distinguished name in the accounting subtree. This bind rule only makes sense if the targeted entry is not under the accounting branch of the directory tree.
userdn = "ldap:///self";
 
The bind rule is evaluated to be true if the user is accessing the entry represented by the DN with which the user bound to the directory. That is, if the user has bound as uid=ssarette, dc=example,dc=com and the user is attempting an operation on the uid=ssarette,dc=example,dc=com entry, then the bind rule is true.
If you want to grant all users in the example.com tree write access to their userPassword attribute, you would create the following ACI on the dc=example,dc=com node.
aci: (targetattr = "userPassword") (version 3.0; acl 
"write-self"; allow (write) userdn = "ldap:///self";)
 
userdn = "ldap:///all";
 
The bind rule is evaluated to be true for any valid bind DN. To be true, a valid distinguished name and password must have been presented by the user during the bind operation.
For example, if you want to grant read access to the entire tree to all authenticated users, you would create the following ACI on the dc=example,dc=com node:
aci:(version 3.0; acl "all-read"; allow (read) 
userdn="ldap:///all";)
 
userdn = "ldap:///anyone";
 
The bind rule is evaluated to be true for anyone; use this keyword to provide anonymous access to your directory.
For example, if you want to allow anonymous read and search access to the entire example.com tree, you would create the following ACI on the dc=example,dc=com node:
aci: (version 3.0; acl "anonymous-read-search"; allow (read, 
search) userdn = "ldap:///anyone";)
 
userdn = "ldap:///parent";
 
The bind rule is evaluated to be true if the bind DN is the parent of the targeted entry.
For example, if you want to grant write access to every user's child entries, you would create the following ACI on the dc=example,dc=com node:
aci:(version 3.0; acl "parent access"; allow (write) 
userdn="ldap:///parent";)
 
userdn = "ldap:///dc=example,dc=com???(|(ou=engineering)

(ou=sales))";
 
The bind rule is evaluated to be true if the user belongs to the engineering or sales subtree.

Defining Group Access - groupdn Keyword

Members of a specific group can access a targeted resource. This is known as group access. Group access is defined using the groupdn keyword to specify that access to a targeted entry will be granted or denied if the user binds using a DN that belongs to a specific group.

The groupdn keyword requires one or more valid distinguished names in the following format :

groupdn="ldap:///dn [|| ldap:///dn]...[|| ldap:///dn]"
 

The bind rule is evaluated to be true if the bind DN belongs to the named group.

Note

If a DN contains a comma, the comma must be escaped by a backslash (\).


From the Server Console, you can define specific groups using the Access Control Editor. For more information, see "Creating ACIs from the Console," on page 242.

Examples

This section contains examples of the groupdn syntax.

groupdn = "ldap:///cn=Administrators,dc=example,dc=com";
 
The bind rule is evaluated to be true if the bind DN belongs to the Administrators group. If you wanted to grant the Administrators group permission to write to the entire directory tree, you would create the following ACI on the dc=example,dc=com node:
aci: (version 3.0; acl "Administrators-write"; allow (write) 
groupdn="ldap:///cn=Administrators,dc=example,dc=com";)
 
groupdn = "ldap:///cn=Administrators,dc=example,dc=com" || 
"ldap:///cn=Mail Administrators,dc=example,dc=com";
 
The bind rule is evaluated to be true if the bind DN belongs to either the Administrators or the Mail Administrators group.

Defining Role Access - roledn Keyword

Members of a specific role can access a targeted resource. This is known as role access. Role access is defined using the roledn keyword to specify that access to a targeted entry will be granted or denied if the user binds using a DN that belongs to a specific role.

The roledn keyword requires one or more valid distinguished names in the following format :

roledn = "ldap:///dn [|| ldap:///dn]... [|| ldap:///dn]"
 

The bind rule is evaluated to be true if the bind DN belongs to the specified role.

Note

If a DN contains a comma, the comma must be escaped by a backslash (\).


The roledn keyword has the same syntax and is used in the same way as the groupdn keyword.

Defining Access Based on Value Matching

You can set bind rules to specify that an attribute value of the entry used to bind to the directory must match an attribute value of the targeted entry.

For example, you can specify that the bind DN must match the DN in the manager attribute of a user entry in order for the ACI to apply. In this case, only the user's manager would have access to the entry.

This example is based on DN matching. However, you can match any attribute of the entry used in the bind with the targeted entry. For example, you could create an ACI that allowed any user whose favoriteDrink attribute is beer to read all the entries of other users that have the same value for favoriteDrink.

Using the userattr Keyword

The userattr keyword can be used to specify which attribute values must match between the entry used to bind and the targeted entry. You can specify:

The LDIF syntax of the userattr keyword is as follows:

userattr = "attrName#bindType"
 

or, if you are using an attribute type that requires a value other than a user DN, group DN, role DN, or an LDAP filter:

userattr = "attrName#attrValue"
 

where:

The following sections provide examples of the userattr keyword with the various possible bind types.

Example with USERDN Bind Type

The following is an example of the userattr keyword associated with a bind based on the user DN:

userattr = "manager#USERDN"
 

The bind rule is evaluated to be true if the bind DN matches the value of the manager attribute in the targeted entry. You can use this to allow a user's manager to modify employees' attributes. This mechanism only works if the manager attribute in the targeted entry is expressed as a full DN.

The following example grants a manager full access to his or her employees' entries:

aci: (target="ldap:///dc=example,dc=com")(targetattr=*) 
(version 3.0;

acl "manager-write"; allow (all) userattr = "manager#USERDN";)
 
Example with GROUPDN Bind Type

The following is an example of the userattr keyword associated with a bind based on a group DN:

userattr = "owner#GROUPDN"
 

The bind rule is evaluated to be true if the bind DN is a member of the group specified in the owner attribute of the targeted entry. For example, you can use this mechanism to allow a group to manage employees' status information. You can use an attribute other than owner as long as the attribute you use contains the DN of a group entry.

The group you point to can be a dynamic group, and the DN of the group can be under any suffix in the database. However, the evaluation of this type of ACI by the server is very resource intensive.

If you are using static groups that are under the same suffix as the targeted entry, you can use the following expression:

userattr = "ldap:///dc=example,dc=com?owner#GROUPDN"
 

In this example, the group entry is under the dc=example,dc=com suffix. The server can process this type of syntax more quickly than the previous example.

(By default, owner is not an allowed entry in a user's entry. You would have to extend your schema to allow this attribute in a person object.)

Example with ROLEDN Bind Type

The following is an example of the userattr keyword associated with a bind based on a role DN:

userattr = "exampleEmployeeReportsTo#ROLEDN"
 

The bind rule is evaluated to be true if the bind DN belongs to the role specified in the exampleEmployeeReportsTo attribute of the targeted entry. For example, if you create a nested role for all managers in your company, you can use this mechanism to grant managers at all levels access to information about employees that are at a lower grade than themselves.

Note

This example assumes that you have added the exampleEmployeeReportsTo attribute to the schema and that all employee entries contain this attribute. It also assumes that the value of this attribute is the DN of a role entry.

For information on designing your schema, refer to Red Hat Directory Server Deployment Guide. For information on adding attributes to the schema, see "Creating Attributes," on page 383.


The DN of the role can be under any suffix in the database. If, in addition, you are using filtered roles, the evaluation of this type of ACI uses a lot of resources on the server.

If you are using a static role definition and the role entry is under the same suffix as the targeted entry, you can use the following expression:

userattr = "ldap:///dc=example,dc=com?employeeReportsTo#ROLEDN"
 

In this example, the role entry is under the dc=example,dc=com suffix. The server can process this type of syntax more quickly than the previous example.

Example with LDAPURL Bind Type

The following is an example of the userattr keyword associated with a bind based on an LDAP filter:

userattr = "myfilter#LDAPURL"
 

The bind rule is evaluated to be true if the bind DN matches the filter specified in the myfilter attribute of the targeted entry. The myfilter attribute can be replaced by any attribute that contains an LDAP filter.

Example with Any Attribute Value

The following is an example of the userattr keyword associated with a bind based on any attribute value:

userattr = "favoriteDrink#Beer"
 

The bind rule is evaluated to be true if the bind DN and the target DN include the favoriteDrink attribute with a value of Beer.

Using the userattr Keyword with Inheritance

When you use the userattr keyword to associate the entry used to bind with the target entry, the ACI applies only to the target specified and not to the entries below it. In some circumstances, you might want to extend the application of the ACI several levels below the targeted entry. This is possible by using the parent keyword and specifying the number of levels below the target that should inherit the ACI.

When you use the userattr keyword in association with the parent keyword, the syntax is as follows:

userattr = "parent[inheritance_level].attrName#bindType"
 

or, if you are using an attribute type that requires a value other than a user DN, group DN, role DN, or an LDAP filter:

userattr = "parent[inheritance_level].attrName#attrValue"
 

where:

For example,

userattr = "parent[0, 1].manager#USERDN"
 

This bind rule is evaluated to be true if the bindDN matches the manager attribute of the targeted entry. The permissions granted when the bind rule is evaluated to be true apply to the target entry and to all entries immediately below it.

Example with userattr Inheritance

The example in Figure 6-1 indicates that user bjensen is allowed to read and search the cn=Profiles entry as well as the first level of child entries which includes cn=mail and cn=news, thus allowing her to search through her own mail and news IDs.

Figure 6-1 Using Inheritance With the userattr Keyword

In this example, if you did not use inheritance, you would have to do one of the following to achieve the same result:

aci: (targetattr="*") (version 3.0; acl "profiles access"; allow (read,search) userattr="owner#USERDN";)

Granting Add Permission Using the userattr Keyword

If you use the userattr keyword in conjunction with all or add permissions, you might find that the behavior of the server is not what you expect. Typically, when a new entry is created in the directory, Directory Server evaluates access rights on the entry being created and not on the parent entry. However, in the case of ACIs using the userattr keyword, this behavior could create a security hole, and the server's normal behavior is modified to avoid it.

Consider the following example:

aci: (target="ldap:///dc=example,dc=com")(targetattr=*) (version 
3.0;

acl "manager-write"; allow (all) userattr = "manager#USERDN";)
 

This ACI grants managers all rights on the entries of employees that report to them. However, because access rights are evaluated on the entry being created, this type of ACI would also allow any employee to create an entry in which the manager attribute is set to their own DN. For example, disgruntled employee Joe (cn=Joe,ou=eng,dc=example,dc=com) might want to create an entry in the Human Resources branch of the tree to use (or misuse) the privileges granted to Human Resources employees.

He could do this by creating the following entry:

dn: cn= Trojan Horse,ou=Human Resources,dc=example,dc=com

objectclass: top

...

cn: Trojan Horse

manager: cn=Joe,ou=eng,dc=example,dc=com
 

To avoid this type of security threat, the ACI evaluation process does not grant add permission at level 0, to the entry itself. You can, however, use the parent keyword to grant add rights below existing entries. You must specify the number of levels below the parent for add rights. For example, the following ACI allows child entries to be added to any entry in the dc=example,dc=com that has a manager attribute that matches the bind DN:

aci: (target="ldap:///dc=example,dc=com")(targetattr=*)

(version 3.0; acl "parent-access"; allow (add)

userattr = "parent[0,1].manager#USERDN";)
 

This ACI ensures that add permission is granted only to users whose bind DN matches the manager attribute of the parent entry.

Defining Access from a Specific IP Address

Using bind rules, you can indicate that the bind operation must originate from a specific IP address. This is often used to force all directory updates to occur from a given machine or network domain.

The LDIF syntax for setting a bind rule based on an IP address is as follows:

ip = "IP_address" or ip != "IP_address"
 

The IP address must be expressed in dot notation.You can use the wildcard character (*) to include multiple machines. For example, the following string is valid:

ip = "12.123.1.*";
 

The bind rule is evaluated to be true if the client accessing the directory is located at the named IP address. This can be useful for allowing certain kinds of directory access only from a specific subnet or machine.

For example, you could use a wildcard IP address such as 12.3.45.* to specify a specific subnetwork or 123.45.6.*+255.255.255.115 to specify a subnetwork mask.

From the Server Console, you can define specific machines to which the ACI applies through the Access Control Editor. For more information, see "Creating ACIs from the Console," on page 242.

Defining Access from a Specific Domain

A bind rule can specify that the bind operation must originate from a particular domain or host machine. This is often used to force all directory updates to occur from a given machine or network domain.

The LDIF syntax for setting a bind rule based on the DNS hostname is as follows:

dns = "DNS_Hostname" or dns != "DNS_Hostname"
 
Caution

The dns keyword requires that the naming service used on your machine is DNS. If the name service is not DNS, you should use the ip keyword instead.


The dns keyword requires a fully qualified DNS domain name. Granting access to a host without specifying the domain creates a potential security threat. For example, the following expression is allowed but not recommended:

dns = "legend.eng";
 

You should use a fully qualified name such as:

dns = "legend.eng.example.com";
 

The dns keyword allows wildcards. For example:

dns = "*.example.com";
 

The bind rule is evaluated to be true if the client accessing the directory is located in the named domain. This can be useful for allowing access only from a specific domain. Wildcards will not work if your system uses a naming service other than DNS. In such a case, if you want to restrict access to a particular domain, use the ip keyword, as described in "Defining Access from a Specific IP Address," on page 236.

Defining Access at a Specific Time of Day or Day of Week

You can use bind rules to specify that binding can only occur at a certain time of day or on a certain day of the week. For example, you can set a rule that will allow access only if it is between the hours of 8 a.m. and 5 p.m. Monday through Friday. The time used to evaluate access rights is the time on the Directory Server, not the time on the client.

The LDIF syntax for setting a bind rule based on the time of day is as follows:

timeofday operator "time"
 

where operator can be one of the following symbols: equal to (=), not equal to (!=), greater than (>), greater than or equal to (>=), less than (<), or less than or equal to (<=).

The timeofday keyword requires a time of day expressed in hours and minutes in the 24 hour clock (0 to 2359).

Note

The time on the server is used for the evaluation, not the time on the client.


The LDIF syntax for setting a bind rule based on the day in the week is as follows:

dayofweek = "day1, day2 ..."
 

The possible values for the dayofweek keyword are the English three-letter abbreviations for the days of the week: sun, mon, tue, wed, thu, fri, sat.

Examples

The following are examples of the timeofday and dayofweek syntax:

timeofday = "1200";
 
The bind rule is evaluated to be true if the client is accessing the directory at noon.
timeofday != "0100";
 
The bind rule is evaluated to be true if the client is accessing the directory at any time other than 1 a.m.
timeofday > "0800";
 
The bind rule is evaluated to be true if the client is accessing the directory at any time after 8 a.m.
timeofday < "1800";
 
The bind rule is evaluated to be true if the client is accessing the directory at any time before 6 p.m.
timeofday >= "0800";
 
The bind rule is evaluated to be true if the client is accessing the directory at 8 a.m. or later.
timeofday <= "1800";
 
The bind rule is evaluated to be true if the client is accessing the directory at 6 p.m. or earlier.
dayofweek = "Sun, Mon, Tue";
 
The bind rule is evaluated to be true if the client is accessing the directory on Sunday, Monday, or Tuesday.

Defining Access Based on Authentication Method

You can set bind rules that state that a client must bind to the directory using a specific authentication method. The authentication methods available are:

In the case of SSL, the connection is established to the LDAPS second port; in the case of TLS, the connection is established through a Start TLS operation. In both cases, a certificate must be provided. For information on setting up SSL, see Chapter 11, "Managing SSL and SASL."

You cannot set up authentication-based bind rules through the Access Control Editor.

The LDIF syntax for setting a bind rule based on an authentication method is as follows:

authmethod = "authentication_method"
 

where authentication_method is none, simple, ssl, or "sasl sasl_mechanism".

Examples

The following are examples of the authmethod keyword:

authmethod = "none";
 
Authentication is not checked during bind rule evaluation.
authmethod = "simple";
 
The bind rule is evaluated to be true if the client is accessing the directory using a username and password.
authmethod = "ssl";
 
The bind rule is evaluated to be true if the client authenticates to the directory using a certificate over LDAPS. This is not evaluated to be true if the client authenticates using simple authentication (bind DN and password) over LDAPS.
authmethod = "sasl DIGEST-MD5";
 
The bind rule is evaluated to be true if the client is accessing the directory using the SASL DIGEST-MD5 mechanism. The other supported SASL mechanisms are EXTERNAL and GSS-API.

Using Boolean Bind Rules

Bind rules can be complex expressions that use the Boolean expressions AND, OR, and NOT to set very precise access rules. You cannot use the Server Console to create Boolean bind rules. You must create an LDIF statement.

The LDIF syntax for a Boolean bind rule is as follows:

bind_rule [boolean][bind_rule][boolean][bind_rule]...;)
 

For example, the following bind rule will be evaluated to be true if the bind DN is a member of either the administrator's group or the mail administrator's group and if the client is running from within the example.com domain:

(groupdn = "ldap:///cn=administrators,dc=example,dc=com" or 
groupdn = "ldap:///cn=mail administrators,dc=example,dc=com" and 
dns = "*.example.com";)
 

The trailing semicolon (;) is a required delimiter that must appear after the final bind rule.

Boolean expressions are evaluated in the following order:

The Boolean OR and Boolean AND operators have no order of precedence.

Consider the following Boolean bind rules:

(bind_rule_A) OR (bind_rule_B)
 
(bind_rule_B) OR (bind_rule_A)
 

Because Boolean expressions are evaluated from left to right, in the first case, bind rule A is evaluated before bind rule B, and, in the second case, bind rule B is evaluated before bind rule A.

However, the Boolean NOT is evaluated before the Boolean OR and Boolean AND. Thus, in the following example

(bind_rule_A) AND NOT (bind_rule_B)
 

bind rule B is evaluated before bind rule A despite the left-to-right rule.

Creating ACIs from the Console

You can use the Directory Server Console to view, create, edit, and delete access control instructions for your directory. This section provides general instructions for:

See "Access Control Usage Examples," on page 247, for a collection of access control rules commonly used in Directory Server security policies, along with step-by-step instructions for using the Directory Server Console to create them.

The Access Control Editor does not enable you to construct some of the more complex ACIs when you are in Visual editing mode. In particular, from the Access Control Editor you cannot:

Tip

In the Access Control Editor, you can click on the Edit Manually button at any time to check the LDIF representation of the changes you make through the graphical interface.


Displaying the Access Control Editor

  1. Start the Directory Server Console. Log in using the bind DN and password of a privileged user, such as the Directory Manager, who has write access to the ACIs configured for the directory.
For instructions, refer to "Using the Directory Server Console," on page 34.
  1. In the Directory Server Console, select the Directory tab.
  2. Right-click the entry in the navigation tree for which you want to set access control, and select Set Access Permissions from the pop-up menu (Figure 6-2).
Or highlight the entry, and select Set Access Permissions from the Object menu.
Figure 6-2 Selecting an Object in the Navigation Tree to Set Access Control

  1. Click New.
The Access Control Editor is displayed as shown in Figure 6-3.
Figure 6-3 Access Control Editor Window

For information on navigating through the Access Control dialog boxes, refer to the online help.

Viewing Current ACIs

If you want to see what ACIs apply to a particular subtree in your directory, follow these steps:

  1. In the Directory tab, right-click the top entry in the subtree, and choose Set Access Permissions from the pop-up menu.
The Access Control Manager window is displayed. It contains the list of ACIs belonging to the entry.
  1. Check the checkbox for Show Inherited ACIs if you want to display the full list of ACIs that apply to the entry.

Creating a New ACI

To create a new ACI:

  1. Display the Access Control Editor.
This task is explained in "Displaying the Access Control Editor," on page 243.
If the view displayed is different from Figure 6-3, on page 244,, click the Edit Visually button.
  1. Name the ACI by typing a name in the ACI Name text box.
The name can be any string you want to use to identify uniquely the ACI. If you do not enter a name, the server uses unnamed ACI.
  1. In the Users/Groups tab, select the users to whom you are granting access by highlighting All Users or clicking the Add button to search the directory for the users to add.
In the Add Users and Groups window:
    1. Select a search area from the drop-down list, enter a search string in the Search field, and click the Search button.
The search results are displayed in the list below.
    1. Highlight the entries you want in the search result list, and click the Add button to add them to the list of entries which have access permission.
    2. Click OK to dismiss the Add Users and Groups window.
The entries you selected are now listed on the Users/Groups tab in the ACI editor.
  1. In the Access Control Editor, click the Rights tab, and use the checkboxes to select the rights to grant.
  2. Click the Targets tab, then click This Entry to display the node targeted by the ACI.
You can change the value of the target DN, but the new DN must be a direct or indirect child of the selected entry.
If you do not want every entry in the subtree under this node to be targeted by the ACI, you must enter a filter in the Filter for Sub-entries field.
Additionally, you can restrict the scope of the ACI to only certain attributes by selecting the attributes you want to target in the attribute list.
  1. Click the Hosts tab, then the Add button, to display the Add Host Filter dialog box.
You can specify a hostname or an IP address. If you specify an IP address, you can use the wildcard character (*).
  1. Click the Times tab to display the table showing at what times access is allowed.
By default, access is allowed at all times. You can change the access times by clicking and dragging the cursor over the table. You cannot select discrete blocks of time.
  1. When you have finished editing the ACI, click OK.
The ACI Editor is dismissed, and the new ACI is listed in the ACI Manager window.
Note

At any time during the creation of the ACI, you can click the Edit Manually button to display the LDIF statement that corresponds to your input. You can modify this statement, but your changes will not necessarily be visible in the graphical interface.


Editing an ACI

To edit an ACI:

  1. In the Directory tab, right-click the top entry in the subtree, and choose Set Access Permissions from the pop-up menu.
The Access Control Manager window is displayed. It contains the list of ACIs belonging to the entry.
  1. In the Access Control Manager window, highlight the ACI that you want to edit, and click Edit.
The Access Control Editor is displayed. For details on the information you can edit using this dialog box, refer to the online help.
  1. Make the changes you want under the various tabs of the Access Control Editor.
  2. When you have finished editing the ACI, click OK.
The ACI Editor is dismissed, and the modified ACI is listed in the ACI Manager.

Deleting an ACI

To delete an ACI:

  1. In the Directory tab, right-click the top entry in the subtree, and choose Set Access Permissions from the pop-up menu.
The Access Control Manager window is displayed. It contains the list of ACIs belonging to the entry.
  1. In the Access Control Manager window, select the ACI that you want to delete.
  2. Click Remove.
The ACI is no longer listed in the Access Control Manager.

Access Control Usage Examples

The examples provided in this section illustrate how an imaginary ISP company, example.com, would implement its access control policy. All the examples explain how to perform a given task from the Console and using an LDIF file.

example.com's business is to offer 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, HostedCompany1 and HostedCompany2. It also provides Internet access to a number of individual subscribers.

These are the access control rules that example.com wants to put in place:

Granting Anonymous Access

Most directories are run such that you can anonymously access at least one suffix for read, search, or compare. For example, you might want to set these permissions if you are running a corporate personnel directory that you want employees to be able to search, such as a phonebook. This is the case at example.com internally and is illustrated in the ACI "Anonymous example.com" example.

As an ISP, example.com also wants to advertise the contact information of all of its subscribers by creating a public phonebook accessible to the world. This is illustrated in the ACI "Anonymous World" example.

ACI "Anonymous example.com"

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" 
and dns="*.example.com";)
 

This example assumes that the aci is added to the dc=example,dc=com entry. The userPassword attribute is excluded from the scope of the ACI.

From the Console, you can set this permission by doing the following:

  1. In the Directory tab, right click the example.com node in the left navigation tree, and choose Set Access Permissions from the pop-up menu to display the Access Control Manager.
  2. Click New to display the Access Control Editor.
  3. In the Users/Groups tab in the ACI name field, type Anonymous example.com. Check that All Users is displayed in the list of users granted access permission.
  4. In the Rights tab, tick the checkboxes for read, compare, and search rights. Make sure the other checkboxes are clear.
  5. In the Targets tab, click This Entry to display the dc=example,dc=com suffix in the target directory entry field. In the attribute table, locate the userPassword attribute, and clear the corresponding checkbox.
All other checkboxes should be ticked. This task is made easier if you click the Name header to organize the list of attributes alphabetically.
  1. In the Hosts tab, click Add, and in the DNS host filter field, type *.example.com. Click OK to dismiss the dialog box.
  2. Click OK in the Access Control Editor window.
The new ACI is added to the ones listed in the Access Control Manager window.

ACI "Anonymous World"

In LDIF, to grant read and search access of the individual subscribers subtree to the world, while denying access to information on unlisted subscribers, 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. It also assumes that every subscriber entry has an unlistedSubscriber attribute which 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," on page 264.

From the Console, you can set this permission by doing the following:

  1. In the Directory tab, right click the Subscribers entry under the example.com node in the left navigation tree, and choose Set Access Permissions from the pop-up menu to display the Access Control Manager.
  2. Click New to display the Access Control Editor.
  3. In the Users/Groups tab, in the ACI name field, type Anonymous World. Check that All Users is displayed in the list of users granted access permission.
  4. In the Rights tab, tick the checkboxes for read and search rights. Make sure the other checkboxes are clear.
  5. In the Targets tab, click This Entry to display the dc=subscribers, dc=example,dc=com suffix in the target directory entry field.
    1. In the filter for subentries field, type the following filter:
(!(unlistedSubscriber=yes))
    1. In the attribute table, tick the checkboxes for the homePhone, homePostalAddress, and mail attributes.
All other checkboxes should be clear. This task is made easier if you click the Check None button to clear the checkoxes for all attributes in the table, then click the Name header to organize them alphabetically, and select the appropriate ones.
  1. Click OK.
The new ACI is added to the ones listed in the Access Control Manager window.

Granting Write Access to Personal Entries

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 illustrated in the ACI "Write example.com" example.

It is also example.com's policy to let their subscribers update their own personal information in the example.com tree, provided that they establish an SSL connection to the directory. This is illustrated in the ACI "Write Subscribers" example.

ACI "Write example.com"

Note

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 password, home telephone number, and home address, you would write the following statement:

aci: (targetattr="userPassword || homePhone || 
homePostalAddress") (version 3.0; acl "Write example.com"; allow 
(write) userdn= "ldap:///self" and dns="*.example.com";)
 

This example assumes that the ACI is added to the ou=example-people,dc=example,dc=com entry.

From the Console, you can set this permission by doing the following:

  1. In the Directory tab, right click the example.com node in the left navigation tree, and choose Set Access Permissions from the pop-up menu to display the Access Control Manager.
  2. Click New to display the Access Control Editor.
  3. In the Users/Groups tab, in the ACI name field, type Write example.com. In the list of users granted access permission, do the following:
    1. Select and remove All Users, then click Add.
The Add Users and Groups dialog box is displayed.
    1. Set the Search area to Special Rights, and select Self from the Search results list.
    2. Click the Add button to list Self in the list of users who are granted access permission.
    3. Click OK to dismiss the Add Users and Groups dialog box.
  1. In the Rights tab, select the checkbox for write right. Make sure the other checkboxes are clear.
  2. In the Targets tab, click This Entry to display the dc=example,dc=com suffix in the target directory entry field. In the attribute table, tick the checkboxes for the homePhone, homePostalAddress, and userPassword attributes.
All other checkboxes should be clear. This task is made easier if you click the Check None button to clear the checkoxes for all attributes in the table, then click the Name header to organize them alphabetically, and select the appropriate ones.
  1. In the Hosts tab, click Add to display the Add Host Filter dialog box. In the DNS host filter field, type *.example.com. Click OK to dismiss the dialog box.
  2. Click OK in the Access Control Editor window.
The new ACI is added to the ones listed in the Access Control Manager window.

ACI "Write Subscribers"

Note

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 password and home telephone number, you would write the following statement:

aci: (targetattr="userPassword || 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.

example.com subscribers do not have write access to their home address because they might delete the attribute, and example.com needs that information for billing. Therefore, the home address is business-critical information.

From the Console, you can set this permission by doing the following:

  1. In the Directory tab, right click the Subscribers entry under the example.com node in the left navigation tree, and choose Set Access Permissions from the pop-up menu to display the Access Control Manager.
  2. Click New to display the Access Control Editor.
  3. In the Users/Groups tab, in the ACI name field, type Write Subscribers. In the list of users granted access permission, do the following:
    1. Select and remove All Users, then click Add.
The Add Users and Groups dialog box is displayed.
    1. Set the Search area to Special Rights, and select Self from the Search results list.
    2. Click the Add button to list Self in the list of users who are granted access permission.
    3. Click OK to dismiss the Add Users and Groups dialog box.
  1. In the Rights tab, tick the checkbox for write. Make sure the other checkboxes are clear.
  2. In the Targets tab, click This Entry to display the dc=subscribers, dc=example,dc=com suffix in the target directory entry field.
    1. In the filter for subentries field, type the following filter:
(!(unlistedSubscriber=yes))
    1. In the attribute table, tick the checkboxes for the homePhone, homePostalAddress, and mail attributes.
All other checkboxes should be clear. This task is made easier if you click the Check None button to clear the checkoxes for all attributes in the table, then click the Name header to organize them alphabetically, and select the appropriate ones.
  1. If you want users to authenticate using SSL, switch to manual editing by clicking the Edit Manually button, and add authmethod=ssl to the LDIF statement so that it reads as follows:
(targetattr="homePostalAddress || homePhone || mail") (version 3.0; acl "Write Subscribers"; allow (write) (userdn= "ldap:///self") and authmethod="ssl";)
  1. Click OK.
The new ACI is added to the ones listed in the Access Control Manager window.

Restricting Access to Key Roles

You can use role definitions in the directory to identify functions that are critical to your business, the administration of your network and directory, or another purpose.

For example, you might create a superAdmin role by identifying a subset of your system administrators that 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 members of staff on a particular site that have done first aid training. For information on creating role definitions, refer to "Using Roles," on page 174.

When a role gives any sort of privileged user rights over critical corporate or business functions, you should consider restricting access to that role. For example, at example.com, employees can add any role to their own entry except the superAdmin role. This is illustrated in the ACI "Roles" example.

ACI "Roles"

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 = "nsRoleDn") 
(targattrfilters="add=nsRoleDN:(nsRoleDN != 
"cn=superAdmin,dc=example,dc=com")") (version 3.0; acl "Roles";

allow (write) userdn= "ldap:///self" and dns="*.example.com";)
 

This example assumes that the ACI is added to the ou=example-people,dc=example,dc=com entry.

From the Console, you can set this permission by doing the following:

  1. In the Directory tab, right click the example.com node in the left navigation tree, and choose Set Access Permissions from the pop-up menu to display the Access Control Manager.
  2. Click New to display the Access Control Editor.
  3. In the Users/Groups tab, in the ACI name field, type Roles. In the list of users granted access permission, do the following:
    1. Select and remove All Users, then click Add.
The Add Users and Groups dialog box is displayed.
    1. Set the Search area in the Add Users and Groups dialog box to to Special Rights, and select Self from the Search results list.
    2. Click the Add button to list Self in the list of users who are granted access permission.
    3. Click OK to dismiss the Add Users and Groups dialog box.
  1. In the Rights tab, tick the checkbox for write. Make sure the other checkboxes are clear.
  2. In the Hosts tab, click Add to display the Add Host Filter dialog box. In the DNS host filter field, type *.example.com. Click OK to dismiss the dialog box.
  3. To create the value-based filter for roles, switch to manual editing by clicking the Edit Manually button. Add the following to the beginning of the LDIF statement:
(targattrfilters="add=nsRoleDN:(nsRoleDN != "cn=superAdmin, dc=example,dc=com")")
The LDIF statement should read as follows:
(targattrfilters="add=nsRoleDN:(nsRoleDN != "cn=superAdmin, dc=example,dc=com")") (targetattr = "*") (target = "ldap:///dc=example,dc=com") (version 3.0; acl "Roles"; allow (write) (userdn = "ldap:///self") and (dns="*.example.com");)
  1. Click OK.
The new ACI is added to the ones listed in the Access Control Manager window.

Granting a Group Full Access to a Suffix

Most directories have a group that is used to identify certain corporate functions. These groups can be given full access to all or part of the directory. By applying the access rights to the group, you can avoid setting the access rights for each member individually. Instead, you grant users these access rights simply by adding them to the group.

For example, when you install the Directory Server using the Typical Install process, an Administrators group with full access to the directory is created by default.

At example.com, the Human Resources group is allowed full access to the ou=example-people branch of the directory so that they can update the employee database. This is illustrated in the ACI "HR" example.

ACI "HR"

In LDIF, to grant the HR group all rights on the employee branch of the directory, you would use the following statement:

aci: (version 3.0; acl "HR"; allow (all) userdn= 
"ldap:///cn=HRgroup,ou=example-people,dc=example,dc=com";)
 

This example assumes that the ACI is added to the ou=example-people,dc=example,dc=com entry.

From the Console, you can set this permission by doing the following:

  1. In the Directory tab, right click the example.com-people entry under the example.com node in the left navigation tree, and choose Set Access Permissions from the pop-up menu to display the Access Control Manager.
  2. Click New to display the Access Control Editor.
  3. In the Users/Groups tab, in the ACI name field, type HR. In the list of users granted access permission, do the following:
    1. Select and remove All Users, then click Add.
The Add Users and Groups dialog box is displayed.
    1. Set the Search area to Users and Groups, and type "HRgroup" in the Search for field.
This example assumes that you have created an HR group or role. For more information on groups and roles, see Chapter 5, "Advanced Entry Management."
    1. Click the Add button to list the HR group in the list of users who are granted access permission.
    2. Click OK to dismiss the Add Users and Groups dialog box.
  1. In the Rights tab, click the Check All button.
All checkboxes are ticked, except for Proxy rights.
  1. Click OK.
The new ACI is added to the ones listed in the Access Control Manager window.

Granting Rights to Add and Delete Group Entries

Some organizations want to allow employees to create entries in the tree if it can increase their efficiency or if it can contribute to the corporate dynamics.

At example.com for example, there is an active social committee that is organized into various clubs: tennis, swimming, skiing, role-playing, etc. Any example.com employee can create a group entry representing a new club. This is illustrated in the ACI "Create Group" example. Any example.com employee can become a member of one of these groups. This is illustrated in ACI "Group Members" under "Allowing Users to Add or Remove Themselves from a Group," on page 264. Only the group owner can modify or delete a group entry. This is illustrated in the ACI "Delete Group" example.

ACI "Create 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: (target="ldap:///ou=social committee,dc=example,dc=com) 
(targattrfilters="add=objectClass:(objectClass=groupOfNames)") 
(version 3.0; acl "Create Group"; allow (add) 

(userdn= "ldap:///uid=*,ou=example-people,dc=example,dc=com") 
and dns="*.example.com";)
 
Note

This ACI does not grant write permission, which means that the entry creator cannot modify the entry.


This example assumes that the ACI is added to the ou=social committee, dc=example,dc=com entry.

From the Console, you can set this permission by doing the following:

  1. In the Directory tab, right click the Social Committee entry under the example.com node in the left navigation tree, and choose Set Access Permissions from the pop-up menu to display the Access Control Manager.
  2. Click New to display the Access Control Editor.
  3. In the Users/Groups tab, in the ACI name field, type Create Group. In the list of users granted access permission, do the following:
    1. Select and remove All Users, then click Add.
The Add Users and Groups dialog box is displayed.
    1. Set the Search area to Special Rights, and select All Authenticated Users from the Search results list.
    2. Click the Add button to list All Authenticated Users in the list of users who are granted access permission.
    3. Click OK to dismiss the Add Users and Groups dialog box.
  1. In the Rights tab, tick the checkbox for add. Make sure the other checkboxes are clear.
  2. In the Targets tab, click This Entry to display the ou=social committee, dc=example,dc=com suffix in the target directory entry field.
  3. In the Hosts tab, click Add to display the Add Host Filter dialog box. In the DNS host filter field, type *.example.com. Click OK to dismiss the dialog box.
  4. To create the value-based filter that will allow employees to add only group entries to this subtree, switch to manual editing by clicking the Edit Manually button. Add the following to the beginning of the LDIF statement:
(targattrfilters="add=objectClass:(objectClass=groupOfNames)")
The LDIF statement should read as follows:
(targattrfilters="add=objectClass:(objectClass=groupOfNames)") (targetattr = "*") (target="ldap:///ou=social committee,dc=example,dc=com) (version 3.0; acl "Create Group"; allow (read,search,add) (userdn= "ldap:///all") and (dns="*.example.com"); )
  1. Click OK.
The new ACI is added to the ones listed in the Access Control Manager window.

ACI "Delete Group"

In LDIF, to grant example.com employees the right to modify or delete a group entry which they own under the ou=Social Comittee branch, you would write the following statement:

aci: (target="ou=social committee,dc=example,dc=com) 
(targattrfilters="del=objectClass:(objectClass=groupOfNames)") 
(version 3.0; acl "Delete Group"; allow (delete) userattr= 
"owner#GROUPDN";)
 

This example assumes that the aci is added to the ou=social committee, dc=example,dc=com entry.

Using the Console is not an effective way of creating this ACI because you would have to use manual editing mode to create the target filter and to check group ownership.

Granting Conditional Access to a Group or Role

In many cases, when you grant a group or role privileged access to the directory, you want to 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, HostedCompany1 and HostedCompany2. It wants these companies to be able to manage their own data and implement their own access control rules while securing it against intruders. For this reason, HostedCompany1 and HostedCompany2 have full rights on their respective branches of the directory tree, provided the following conditions are fulfilled:

These conditions are illustrated in a single ACI for each company, ACI "HostedCompany1" and ACI "HostedCompany2." Because the content of these ACIs is the same, the examples below illustrate the "HostedCompany1" ACI only.

ACI "HostedCompany1"

In LDIF, to grant HostedCompany1 full access to their own branch of the directory under the conditions stated above, you would write the following statement:

aci: 
(target="ou=HostedCompany1,ou=corporate-clients,dc=example,dc=co
m")

(targetattr= "*") (version 3.0; acl "HostedCompany1";

allow (all) 
(roledn="ldap:///cn=DirectoryAdmin,ou=HostedCompany1,

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=HostedCompany1, ou=corporate-clients,dc=example,dc=com entry.

From the Console, you can set this permission by doing the following:

  1. In the Directory tab, right click the HostedCompany1 entry under the example.com node in the left navigation tree, and choose Set Access Permissions from the pop-up menu to display the Access Control Manager.
  2. Click New to display the Access Control Editor.
  3. In the Users/Groups tab, in the ACI name field, type HostedCompany1. In the list of users granted access permission, do the following:
    1. Select and remove All Users, then click Add.
The Add Users and Groups dialog box is displayed.
    1. Set the Search area to Users and Groups, and type DirectoryAdmin in the Search For field.
This example assumes that you have created an administrators role with a cn of DirectoryAdmin.
    1. Click the Add button to list the administrators role in the list of users who are granted access permission.
    2. Click OK to dismiss the Add Users and Groups dialog box.
  1. In the Rights tab, click the Check All button.
  2. In the Targets tab, click This Entry to display the ou=HostedCompany1,ou=corporate-clients,dc=example,dc=com suffix in the target directory entry field.
  3. In the Hosts tab, click Add to display the Add Host Filter dialog box. In the IP address host filter field, type 255.255.123.234. Click OK to dismiss the dialog box.
The IP address must be a valid IP address for the host machine that the HostedCompany1 administrators will use to connect to the example.com directory.
  1. In the Times tab, select the block time corresponding to Monday through Thursday and 8 a.m. to 6 p.m.
A message appears below the table that specifies what time block you have selected.
  1. To enforce SSL authentication from HostedCompany1 administrators, switch to manual editing by clicking the Edit Manually button. Add the following to the end of the LDIF statement:
and (authmethod="ssl")
The LDIF statement should be similar to:
aci: (targetattr = "*") (target="ou=HostedCompany1,ou=corporate-clients,dc=example,dc=com") (version 3.0; acl "HostedCompany1"; allow (all) (roledn= "ldap:///cn=DirectoryAdmin,ou=HostedCompany1,ou=corporate-clients, dc=example,dc=com") and (dayofweek="Mon,Tues,Wed,Thu") and (timeofday >= "0800" and timeofday <= "1800") and (ip="255.255.123.234") and (authmethod="ssl"); )
  1. Click OK.
The new ACI is added to the ones listed in the Access Control Manager window.

Denying Access

If your directory holds business-critical information, you might specifically want to deny access to it.

For example, example.com wants all subscribers to be able to read billing information such as connection time or account balance under their own entries but explicitly wants to deny write access to that information. This is illustrated in ACI "Billing Info Read" and ACI "Billing Info Deny," respectively.

ACI "Billing Info Read"

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.

From the Console, you can set this permission by doing the following:

  1. In the Directory tab, right click the subscribers entry under the example.com node in the left navigation tree, and choose Set Access Permissions from the pop-up menu to display the Access Control Manager.
  2. Click New to display the Access Control Editor.
  3. In the Users/Groups tab, in the ACI name field, type Billing Info Read. In the list of users granted access permission, do the following:
    1. Select and remove All Users, then click Add.
The Add Users and Groups dialog box is displayed.
    1. Set the Search area in the Add Users and Groups dialog box to to Special Rights, and select Self from the Search results list.
    2. Click the Add button to list Self in the list of users who are granted access permission.
    3. Click OK to dismiss the Add Users and Groups dialog box.
  1. In the Rights tab, tick the checkboxes for search and read rights. Make sure the other checkboxes are clear.
  2. In the Targets tab, click This Entry to display the ou=subscribers, dc=example,dc=com suffix in the target directory entry field. In the attribute table, tick the checkboxes for the connectionTime and accountBalance attributes.
All other checkboxes should be clear. This task is made easier if you click the Check None button to clear the checkoxes for all attributes in the table, then click the Name header to organize them alphabetically, and select the appropriate ones.
This example assumes that you have added the the connectionTime and accountBalance attributes to the schema.
  1. Click OK.
The new ACI is added to the ones listed in the Access Control Manager window.

ACI "Billing Info Deny"

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.

From the Console, you can set this permission by doing the following:

  1. In the Directory tab, right click the subscribers entry under the example.com node in the left navigation tree, and choose Set Access Permissions from the pop-up menu to display the Access Control Manager.
  2. Click New to display the Access Control Editor.
  3. In the Users/Groups tab, in the ACI name field, type Billing Info Deny. In the list of users granted access permission, do the following:
    1. Select and remove All Users, then click Add.
The Add Users and Groups dialog box is displayed.
    1. Set the Search area in the Add Users and Groups dialog box to to Special Rights, and select Self from the Search results list.
    2. Click the Add button to list Self in the list of users who are granted access permission.
    3. Click OK to dismiss the Add Users and Groups dialog box.
  1. In the Rights tab, tick the checkbox for write. Make sure the other checkboxes are clear.
  2. Click the Edit Manually button, and, in the LDIF statement that is displayed, change the word allow to deny.
  3. In the Targets tab, click This Entry to display the ou=subscribers, dc=example,dc=com suffix in the target directory entry field. In the attribute table, tick the checkboxes for the connectionTime and accountBalance attributes.
All other checkboxes should be clear. This task is made easier if you click the Check None button to clear the checkoxes for all attributes in the table, then click the Name header to organize them alphabetically, and select the appropriate ones.
This example assumes that you have added the the connectionTime and accountBalance attributes to the schema.
  1. Click OK.
The new ACI is added to the ones listed in the Access Control Manager window.

Setting a Target Using Filtering

If you want to set access controls that allow access to a number of entries that are spread across the directory, you may want to use a filter to set the target. Keep in mind that because search filters do not directly name the object for which you are managing access, it is easy to allow or deny access to the wrong objects unintentionally, especially as your directory becomes more complex. Additionally, filters can make it difficult for you to troubleshoot access control problems within your directory.

The following procedure shows you how to grant user bjensen write access to the department number, home phone number, home postal address, JPEG photo, and manager attributes for all members of the accounting organization.

Before you can set these permissions, you must create the accounting branch point (ou=accounting,dc=example,dc=com). You can create organizational unit branch points using the directory tab on the Directory Server Console.

Allowing Users to Add or Remove Themselves from a Group

Many directories set ACIs that allow users to add or remove themselves from groups. This is useful, for example, for allowing users to add and remove themselves from mailing lists.

At example.com, employees can add themselves to any group entry under the ou=social committee subtree. This is illustrated in the ACI "Group Members" example.

ACI "Group Members"

In LDIF, to grant example.com employees the right to add or delete themselves from a group, you would write the following statement:

aci: (targettattr="member")(version 3.0; acl "Group Members";

allow (selfwrite)

(userdn= "ldap:///uid=*,ou=example-people,dc=example,dc=com") ;)
 

This example assumes that the ACI is added to the ou=social committee, dc=example,dc=com entry.

From the Console, you can set this permission by doing the following:

  1. In the Directory tab, right click the example-people entry under the example.com node in the left navigation tree, and choose Set Access Permissions from the pop-up menu to display the Access Control Manager.
  2. Click New to display the Access Control Editor.
  3. In the Users/Groups tab, in the ACI name field, type Group Members. In the list of users granted access permission, do the following:
    1. Select and remove All Users, then click Add.
The Add Users and Groups dialog box is displayed.
    1. Set the Search area in the Add Users and Groups dialog box to to Special Rights, and select All Authenticated Users from the Search results list.
    2. Click the Add button to list All Authenticated Users in the list of users who are granted access permission.
    3. Click OK to dismiss the Add Users and Groups dialog box.
  1. In the Rights tab, tick the checkbox for selfwrite. Make sure the other checkboxes are clear.
  2. In the Targets tab, type dc=example,dc=com suffix in the target directory entry field. In the attribute table, tick the checkbox for the member attribute.
All other checkboxes should be clear. This task is made easier if you click the Check None button to clear the checkoxes for all attributes in the table, then click the Name header to organize them alphabetically, and select the appropriate ones.
  1. Click OK.
The new ACI is added to the ones listed in the Access Control Manager window.

Defining Permissions for DNs That Contain a Comma

DNs that contain commas require special treatement 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: dc=example.com Bolivia\, S.A.,dc=com

objectClass: top

objectClass: organization

aci: (target="ldap:///dc=example.com Bolivia\, 
S.A.,dc=com")(targetattr=*) (version 3.0; acl "aci 2"; allow 
(all)

groupdn = "ldap:///cn=Directory Administrators,dc=example.com 
Bolivia\, S.A.,dc=com";) 
 

Proxied Authorization ACI Example

For this example, suppose:

In order for the client application to gain access to the Accounting subtree (using the same access permissions as the Accounting Administrator):

With this ACI in place, the MoneyWizAcctSoftware client application can bind to the directory and send an LDAP command such as ldapsearch or ldapmodify that requires the access rights of the proxy DN.

In the above example, if the client wanted to perform an ldapsearch command, the command would include the following controls:

#ldapmodify -D "uid=MoneyWizAcctSoftware, 
ou=Applications,dc=example,dc=com" -w secretpwd

-y "uid=AcctAdministrator,ou=Administrators,dc=example,dc=com"
 

The client or application (MoneyWizAcctSoftware) binds as itself but is granted the privileges of the proxy entry (AcctAdministrator). The client does not need the password of the proxy entry.

Note

You cannot use the directory manager's DN (Root DN) as a proxy DN. In addition, if Directory Server receives more than one proxied authentication control, an error is returned to the client application, and the bind attempt is unsuccessful.


Viewing the ACIs for an Entry

You can view all the ACIs under a single suffix in the directory by running the following ldapsearch command:

ldapsearch -h host -p port -b baseDN -D rootDN -w rootPassword (aci=*) 
aci
 

See Red Hat Directory Server Configuration, Command, and File Reference for information on using the ldapsearch utility.

From the Console, you can view all of the ACIs that apply to a particular entry through the Access Control Manager.

  1. In the Directory Console, on the Directory tab, right-click the entry in the navigation tree, and select Set Access Permissions.
The Access Control Manager is displayed. It contains a list of the ACIs belonging to the selected entry.
  1. Check the Show Inherited ACIs checkbox to display all ACIs created on entries above the selected entry that also apply.

Get Effective Rights Control

Finding the rights on existing attributes within a specific entry offers a convenient way for administrators to find and control the access rights.

"Get effective rights" is an extended ldapsearch which returns the access control permissions set on each attribute within an entry. The effective rights can be retrieved by sending an LDAP control along with a search operation. The results show the effective rights on each returned entry and each attribute of each returned entry.

The access control information is divided into two groups of access: rights for an entry and rights for an attribute. "Rights for an entry" means the rights, such as modify or delete, that are limited to that specific entry. "Rights for an attribute" means the access right to every instance of that attribute throughout the directory.

Some of the situations when this kind of detailed access control may be necessary include the following:

An ldapsearch run with the -J tool will return the access controls placed on a particular entry. The entryLevelRights and attributeLevelRights returns are added as attributes to the bottom of the query results. If the ldapsearch is run without -J, then the entry information is returned as normal, without the entryLevelRights or attributeLevelRights information.

A get effective rights result looks like the following:

dn: uid=tmorris, ou=People, dc=example,dc=com

l: Santa Clara

userPassword: {SSHA}bz0uCmHZM5b357zwrCUCJs1IOHtMD6yqPyhxBA==

entryLevelRights: vadn

attributeLevelRights: l:rscwo, userPassword:wo
 

In this example, Ted Morris has the right to add, view, delete, or rename the DN on his own entry, as shown by the returns in entryLevelRights. For attributes, he has the right to read, search, compare, self-modify, or self-delete the location (l) attribute but only self-write and self-delete rights to his password, as shown in the attributeLevelRights return.

Information is not given for attributes in an entry that do not have a value; for example, if the userPassword value is removed, then a future effective rights search on the entry above would not return any effective rights for userPassword, even though self-write and self-delete rights could be allowed. Likewise, if the street attribute were added with read, compare, and search rights, then street: rsc would appear in the attributeLevelRights results.

Table 6-3 and Table 6-4 summarize the permissions that can be set on entries and on attributes that are retrieved by the get effective rights operation.

Table 6-3 Permissions That Can Be Set on Entries
Permission
Description
a
Add.
d
Delete.
n
Rename the DN.
v
View the entry.

Table 6-4 Permissions That Can Be Set on Attributes
Permission
Description
r
Read.
s
Search.
w
Write (mod-add).
o
Obliterate (mod-del). Analogous to delete.
c
Compare.
W
Self-write.
O
Self-delete.

Using Get Effective Rights from the Command-Line

To retrieve the effective rights with ldapsearch, you must pass the control information with the ldapsearch utility's -J option, as follows:

./ldapsearch -p port -h host -D bindDN -w bindPassword -b user -J control 
OID:boolean criticality:dn:AuthId
 

A user, such as Ted Morris, can use this ldapsearch option to retrieve the rights he has to his personal entry, as shown below. Along with returning the effective rights information, the ldapsearch returns the regular entry information:

./ldapsearch -p 389 -h localhost -D 
"uid=tmorris,ou=people,dc=example,dc=com" -w password -b 
"uid=tmorris,ou=people,dc=example,dc=com" -J 
"1.3.6.1.4.1.42.2.27.9.5.2:true:dn: 
uid=tmorris,ou=people,dc=example,dc=com" "(objectClass=*)"
 
version: 1

dn: uid=tmorris, ou=People, dc=example,dc=com

givenName: Ted

sn: Morris

ou: Accounting

ou: People

l: Santa Clara

manager: uid=dmiller, ou=People, dc=example,dc=com

roomNumber: 4117

mail: [email protected]

facsimileTelephoneNumber: +1 408 555 5409

objectClass: top

objectClass: person

objectClass: organizationalPerson

objectClass: inetOrgPerson

uid: tmorris

cn: Ted Morris

userPassword: {SSHA}bz0uCmHZM5b357zwrCUCJs1IOHtMD6yqPyhxBA==

entryLevelRights: v

attributeLevelRights: givenName:rsc, sn:rsc, ou:rsc, l:rsc, 
manager:rsc, roomNumber:rscwo, mail:rscwo, 
facsimileTelephoneNumber:rscwo, objectClass:rsc, uid:rsc, 
cn:rsc, userPassword:wo
 

An administrative user, such as Directory Manager, can use the get effective rights operation to determine what rights are granted between users. The following is a sample ldapsearch to retrieve effective rights that a manager, Dave Miller (shown in the dn:user part of the -J value), has over the entry of one of his subordinates, Ted Morris (shown in the -b value):

./ldapsearch -p 389 -h localhost -D "cn=directory manager" -w 
password -b "uid=tmorris,ou=people,dc=example,dc=com" -J 
"1.3.6.1.4.1.42.2.27.9.5.2:true:dn: 
uid=dmiller,ou=people,dc=example,dc=com" "(objectClass=*)"
 
version: 1

dn: uid=tmorris, ou=People, dc=example,dc=com

givenName: Ted

sn: Morris

ou: Accounting

ou: People

l: Santa Clara

manager: uid=dmiller, ou=People, dc=example,dc=com

roomNumber: 4117

mail: [email protected]

facsimileTelephoneNumber: +1 408 555 5409

objectClass: top

objectClass: person

objectClass: organizationalPerson

objectClass: inetOrgPerson

uid: tmorris

cn: Ted Morris

userPassword: {SSHA}bz0uCmHZM5b357zwrCUCJs1IOHtMD6yqPyhxBA==

entryLevelRights: vadn

attributeLevelRights: givenName:rscwo, sn:rscwo, ou:rscwo, 
l:rscwo, manager:rscwo, roomNumber:rscwo, mail:rscwo, 
facsimileTelephoneNumber:rscwo, objectClass:rscwo, uid:rscwo, 
cn:rscwo, userPassword:rscwo
 

For all attributes, Dave Miller has read, search, compare, modify, and delete permissions to Ted Morris's entry. These results are different than the ones returned in checking Ted Morris's access to his own entry, since he personally had only read, search, and compare rights to most of these attributes.

Only an administrator can retrieve effective rights to another user's entry. If Ted Morris tried to retrieve his rights to Dave Miller's entry, then he would receive the following error:

./ldapsearch -p 389 -h localhost -D 
"uid=dmiller,ou=people,dc=example,dc=com" -w password -b 
"uid=tmorris,ou=people,dc=example,dc=com" -J 
"1.3.6.1.4.1.42.2.27.9.5.2:true:dn: 
uid=tmorris,ou=people,dc=example,dc=com" "(objectClass=*)"
 
ldap_search: Insufficient access

ldap_search: additional info: get-effective-rights: requestor 
has no g permission on the entry
 

However, Ted Morris could run a get effective rights search on his personal entry to determine the rights another user, such as Sam Carter, has to it. Assuming that an ldapsearch was run with -b set to uid=tmorris,ou=people,dc=example,dc=com and the AuthId was set to uid=scarter,ou=people,dc=example,dc=com, then Ted Morris would retrieve the following effective rights information:

entryLevelRights: v

attributeLevelRights: givenName:rsc, sn:rsc, ou:rsc, l:rsc, 
manager:rsc, roomNumber:rsc, mail:rsc, 
facsimileTelephoneNumber:rsc, objectClass:rsc, uid:rsc, cn:rsc, 
userPassword:none
 

This means that Sam Carter has the right to view the DN of the entry and to read, search, and compare the ou, givenName, l, and other attributes and no rights to the userPassword attribute.

Using Get Effective Rights from the Console

To view effective rights from the Console, do the following:

  1. Open the Directory tab, and right-click on the entry which rights you want to check.
  2. Select "Advanced Properties" from the drop-down menu.
The Properties Editor will appear.
  1. Check the "Show effective rights" checkbox.
The attribute-level effective rights (r, s, c, w, o) will appear next to the attributes. The entry-level rights (v, a, d, n) will appear under the full DN for the entry in the lower left-hand corner of the Properties Editor.

If you check the "Show all allowed attributes" checkbox, then the effective rights for those attributes will appear next to the additional attributes, even though they do not have values.

Get Effective Rights Return Codes

If the criticality is set to false for a get effective rights search and an error occurs, the regular entry information is returned, but, in place of rights for entryLevelRights and attributeLevelRights, an error code is returned. This code can give information on the configuration of the entry that was queried. Table 6-5 summarizes the error codes and the potential configuration information they can relay.

Table 6-5 Returned Result Codes
Code
Description
0
Successfully completed.
1
Operation error.
12
The critical extension is unavailable. If the criticality expression is set to true and effective rights do not exist on the entry being queried, then this error is returned.
16
No such attribute. If an attribute is specifically queried for access rights but that attribute does not exist in the schema, this error is returned.
17
Undefined attribute type.
21
Invalid attribute syntax.
50
Insufficient rights.
52
Unavailable.
53
Unwilling to perform.
80
Other.

Advanced Access Control: Using Macro ACIs

In organizations that use repeating directory tree structures, it is possible to optimize the number of ACIs used in the directory by using macros. Reducing the number of ACIs in your directory tree makes it easier to manage your access control policy and improves the efficiency of ACI memory usage.

Macros are placeholders that are used to represent a DN, or a portion of a DN, in an ACI. You can use a macro to represent a DN in the target portion of the ACI or in the bind rule portion, or both. In practice, when Directory Server gets an incoming LDAP operation, the ACI macros are matched against the resource targeted by the LDAP operation. If there is a match, the macro is replaced by the value of the DN of the targeted resource. Directory Server then evaluates the ACI normally.

Macro ACI Example

The benefits of macro ACIs and how they work are best explained using an example. Figure 6-4, on page 275,, shows a directory tree in which using macro ACIs is an effective way of reducing the overall number of ACIs.

This illustration uses repeating pattern of subdomains with the same tree structure (ou=groups, ou=people). This pattern is also repeated across the tree because the example.com directory tree stores the suffixes dc=hostedCompany2, dc=example,dc=com and dc=hostedCompany3,dc=example,dc=com.

The ACIs that apply in the directory tree also have a repeating pattern. For example, the following ACI is located on the dc=hostedCompany1,dc=example,dc=com node:

aci: 
(targetattr="*")(targetfilter=(objectClass=nsManagedDomain)) 
(version 3.0; acl "Domain access"; allow (read,search) groupdn= 
"ldap:///cn=DomainAdmins,ou=Groups,dc=hostedCompany1,dc=example
,dc=com";)
 

This ACI grants read and search rights to the DomainAdmins group to any entry in the dc=hostedCompany1,dc=example,dc=com tree.

Figure 6-4 Example Directory Tree for Macro ACIs

The following ACI is located on the dc=hostedCompany1,dc=example,dc=com node:

aci: 
(targetattr="*")(targetfilter=(objectClass=nsManagedDomain)) 
(version 3.0; acl "Domain access"; allow (read,search) 
groupdn="ldap:///cn=DomainAdmins,ou=Groups,dc=hostedCompany1, 
dc=example,dc=com";)
 

The following ACI is located on the dc=subdomain1,dc=hostedCompany1, dc=example,dc=com node:

aci: 
(targetattr="*")(targetfilter=(objectClass=nsManagedDomain)) 
(version 3.0; acl "Domain access"; allow (read,search) 
groupdn="ldap:///cn=DomainAdmins,ou=Groups,dc=subdomain1, 
dc=hostedCompany1,dc=example,dc=com";)
 

The following ACI is located on the dc=hostedCompany2,dc=example,dc=com node:

aci: 
(targetattr="*")(targetfilter=(objectClass=nsManagedDomain)) 
(version 3.0; acl "Domain access"; allow (read,search) 
groupdn="ldap:///cn=DomainAdmins,ou=Groups,dc=hostedCompany2, 
dc=example,dc=com";)
 

The following ACI is located on the dc=subdomain1,dc=hostedCompany2, dc=example,dc=com node:

aci: 
(targetattr="*")(targetfilter=(objectClass=nsManagedDomain)) 
(version 3.0; acl "Domain access"; allow (read,search) 
groupdn="ldap:///cn=DomainAdmins,ou=Groups, dc=subdomain1, 
dc=hostedCompany2,dc=example,dc=com";)
 

In the four ACIs shown above, the only differentiator is the DN specified in the groupdn keyword. By using a macro for the DN, it is possible to replace these ACIs by a single ACI at the root of the tree, on the dc=example,dc=com node. This ACI reads as follows:

aci: (target="ldap:///ou=Groups,($dn),dc=example,dc=com") 
(targetattr="*")(targetfilter=(objectClass=nsManagedDomain)) 
(version 3.0; acl "Domain access"; allow (read,search) 
groupdn="ldap:///cn=DomainAdmins,ou=Groups,[$dn],dc=example,dc=
com";)
 

The target keyword, which was not previously used, needs to be introduced.

In the example above, the number of ACIs is reduced from four to one. However, the real benefit is a factor of how many repeating patterns you have down and across your directory tree.

Macro ACI Syntax

Macro ACIs include the following types of expressions to replace a DN or part of a DN:

To simplify the discussion in this section, the ACI keywords used to provide bind credentials, such as userdn, roledn, groupdn, and userattr, are collectively called the subject, as opposed to the target, of the ACI. Macro ACIs can be used in the target part or the subject part of an ACI.

Table 6-6 shows in what parts of the ACI you can use DN macros:

Table 6-6 Macros in ACI Keywords  
Macro
ACI Keyword
($dn)
target, targetfilter, userdn, roledn, groupdn, userattr
[$dn]
targetfilter, userdn, roledn, groupdn, userattr
($attr.attrName)
userdn, roledn, groupdn, userattr

The following restrictions apply:

In short, you when using any macro, you always need a target definition that contains the ($dn) macro.

You can combine the ($dn) macro and the ($attr.attrName) macro.

Macro Matching for ($dn)

The ($dn) macro is replaced by the matching part of the resource targeted in an LDAP request. For example, you have an LDAP request targeted at the cn=all, ou=groups,dc=subdomain1,dc=hostedCompany1,dc=example,dc=com entry and an ACI that defines the target as follows:

(target="ldap:///ou=Groups,($dn),dc=example,dc=com")
 

The ($dn) macro matches with dc=subdomain1, dc=hostedCompany1.

When the subject of the ACI also uses ($dn), the substring that matches the target is used to expand the subject. For example:

aci: (target="ldap:///ou=*,($dn),dc=example,dc=com") 
(targetattr = "*") (version 3.0; acl "Domain access"; allow 
(read,search) 
groupdn="ldap:///cn=DomainAdmins,ou=Groups,($dn),dc=example,dc=
com";)
 

In this case, if the string matching ($dn) in the target is dc=subdomain1, dc=hostedCompany1, then the same string is used in the subject. The ACI above is expanded as follows:

aci: 
(target="ldap:///ou=Groups,dc=subdomain1,dc=hostedCompany1, 
dc=example,dc=com") (targetattr = "*") (version 3.0; acl "Domain 
access"; allow (read,search) 
groupdn="ldap:///cn=DomainAdmins,ou=Groups, 
dc=subdomain1,dc=hostedCompany1,dc=example,dc=com";)
 

Once the macro has been expanded, Directory Server evaluates the ACI following the normal process to determine whether access is granted.

Macro Matching for [$dn]

The matching mechanism for [$dn] is slightly different than for ($dn). The DN of the targeted resource is examined several times, each time dropping the left-most RDN component, until a match is found.

For example, you have an LDAP request targeted at the cn=all,ou=groups, dc=subdomain1,dc=hostedCompany1,dc=example,dc=com subtree and the following ACI:

aci: (target="ldap:///ou=Groups,($dn),dc=example,dc=com") 
(targetattr = "*") (version 3.0; acl "Domain access"; allow 
(read,search) 
groupdn="ldap:///cn=DomainAdmins,ou=Groups,[$dn],dc=example,dc=
com";)
 

The steps for expanding this ACI are as follows:

  1. ($dn) in target matches dc=subdomain1,dc=hostedCompany1.
  2. Replace [$dn] in subject with dc=subdomain1,dc=hostedCompany1.
The result is groupdn="ldap:///cn=DomainAdmins,ou=Groups, dc=subdomain1,dc=hostedCompany1,dc=example,dc=com". If the bind DN is a member of that group, the matching process stops, and the ACI is evaluated. If it does not match, the process continues.
  1. Replace [$dn] in subject with dc=hostedCompany1.
The result is groupdn="ldap:///cn=DomainAdmins,ou=Groups, dc=hostedCompany1,dc=example,dc=com". In this case, if the bind DN is not a member of that group, the ACI is not evaluated. If it is a member, the ACI is evaluated.

The advantage of the [$dn] macro is that it provides a flexible way of granting access to domain-level administrators to all the subdomains in the directory tree. Therefore, it is useful for expressing a hierarchical relationship between domains.

For example, consider the following ACI:

aci: (target="ldap:///ou=*, ($dn),dc=example,dc=com") 
(targetattr="*")(targetfilter=(objectClass=nsManagedDomain)) 
(version 3.0; acl "Domain access"; allow (read,search) 
groupdn="ldap:///cn=DomainAdmins,ou=Groups,[$dn],dc=example,dc=c
om";)
 

It grants access to the members of cn=DomainAdmins,ou=Groups, dc=hostedCompany1,dc=example,dc=com to all of the subdomains under dc=hostedCompany1, so an administrator belonging to that group could access; for example, the subtree ou=people, dc=subdomain1.1, dc=subdomain1.

However, at the same time, members of cn=DomainAdmins,ou=Groups, dc=subdomain1.1 would be denied access to the ou=people,dc=hostedCompany1 and ou=people,dc=hostedCompany1 nodes.

Macro Matching for ($attr.attrName)

The ($attr.attrName) macro is always used in the subject part of a DN. For example, you could define the following roledn:

roledn = "ldap:///cn=DomainAdmins,($attr.ou)"
 

Now, assume the server receives an LDAP operation targeted at the following entry:

dn: cn=Jane Doe, ou=People, dc=HostedCompany1, dc=example,dc=com

cn: Jane Doe

sn: Doe

ou: Engineering, dc=HostedCompany1, dc=example,dc=com

...
 

In order to evaluate the roledn part of the ACI, the server looks at the ou attribute stored in the targeted entry and uses the value of this attribute to expand the macro. Therefore, in the example, the roledn is expanded as follows:

roledn = 
"ldap:///cn=DomainAdmins,ou=Engineering,dc=HostedCompany1, 
dc=example,dc=com"
 

The Directory Server then evaluates the ACI according to the normal ACI evaluation algorithm.

When an attribute is multi-valued, each value is used to expand the macro, and the first one that provides a successful match is used.

Consider this example:

dn: cn=Jane Doe,ou=People,dc=HostedCompany1,dc=example,dc=com

cn: Jane Doe

sn: Doe

ou: Engineering, dc=HostedCompany1, dc=example,dc=com

ou: People, dc=HostedCompany1,dc=example,dc=com

...
 

In this case, when the Directory Server evaluates the ACI, it performs a logical OR on the following expanded expressions:

roledn = 
"ldap:///cn=DomainAdmins,ou=Engineering,dc=HostedCompany1, 
dc=example,dc=com"
 
roledn = "ldap:///cn=DomainAdmins,ou=People,dc=HostedCompany1, 
dc=example,dc=com"
 

Access Control and Replication

ACIs are stored as attributes of entries; therefore, if an entry containing ACIs is part of a replicated database, the ACIs are replicated like any other attribute.

ACIs are always evaluated on the Directory Server that services the incoming LDAP requests. This means that when a consumer server receives an update request, it will return a referral to the supplier server before evaluating whether the request can be serviced on the supplier.

Logging Access Control Information

To obtain information on access control in the error logs, you must set the appropriate log level.

To set the error log level from the Console:

  1. In the Console, click the Directory tab, right click the config node, and choose Properties from the pop-up menu.
This displays the Property Editor for the cn=config entry.
  1. Scroll down the list of attribute value pairs to locate the nsslapd-errorlog-level attribute.
  2. Add 128 to the value already displayed in the nsslapd-errorlog-level value field.
For example, if the value already displayed is 8192 (replication debugging), you should change the value to 8320. For complete information on error log levels, refer to Red Hat Directory Server Configuration, Command, and File Reference.
  1. Click OK to dismiss the Property Editor.

Compatibility with Earlier Releases

Some ACI keywords that were used in earlier releases of Directory Server have been deprecated in release 6.1 and later. However, for reasons of backward compatibility, they are still supported. These keywords are:

Therefore, if you have set up a replication agreement between a legacy supplier server and a consumer version later than 6.1, you should not encounter any problems in the replication of ACIs.




Previous
Contents
Index
Next

© 2001 Sun Microsystems, Inc. Used by permission. © 2005 Red Hat, Inc. All rights reserved.
Read the Full Copyright and Third-Party Acknowledgments.

last updated May 20, 2005