Sun Directory Server Enterprise Edition 7.0 Administration Guide

Chapter 6 Directory Server Access Control

The control of access to your directory is an integral part of creating a secure directory. This chapter describes access control instructions (ACIs) that determine which permissions are granted to users who access the directory.

While you are in the planning phase of your directory deployment, define an access control strategy that serves your overall security policy. See the Sun Directory Server Enterprise Edition 7.0 Deployment Planning Guide for tips on planning an access control strategy.

For additional information about ACIs, including ACI syntax and bind rules, see Sun Directory Server Enterprise Edition 7.0 Reference.

This chapter covers the following topics:

Creating, Viewing, and Modifying ACIs

You can create ACIs either by using Directory Service Control Center (DSCC) or by using the command line. Whichever method you choose, it is often easier to view and copy an existing ACI value, rather than to create a new ACI from scratch.

You can view and modify the aci attribute values in DSCC. For information about how to modify ACIs through DSCC, see the DSCC online help.

ProcedureTo Create, Modify, and Delete ACIs

To create ACIs by using the command line, you first create the ACIs in a file using LDIF statements. Then you add the ACIs to your directory tree by using the ldapmodify command.

You can use DSCC to perform this task. For information, see Directory Service Control Center Interface and the DSCC online help.

  1. Create the ACI in an LDIF file.


    dn: dc=example,dc=com
    changetype: modify
    add: aci
    aci: (target)(version 3.0; acl "name";permission bindrules;)

    This example shows how to add an ACI. To modify or delete the ACI, replace add with replace or delete.

    For more examples of ACIs that are commonly used, see Access Control Usage Examples.

  2. Make the change using the LDIF file.


    $ ldapmodify -h host -p port -D cn=admin,cn=Administrators,cn=config -w - -f ldif-file
    

ProcedureTo View ACI Attribute Values

ACIs are stored as one or more values of the aci attribute of an entry. The aci attribute is a multi-valued operational attribute that can be read and modified by directory users. Therefore, the ACI attribute itself should be protected by ACIs. Administration users are usually given full access to the aci attribute.

You can use DSCC to perform this task. For information, see Directory Service Control Center Interface and the DSCC online help.

  1. View the ACI attribute value of an entry by running the following ldapsearch command:


    $ ldapsearch -h host -p port -D cn=admin,cn=Administrators,cn=config -w - \
     -b entryDN -s base "(objectclass=*)" aci

    The result is LDIF text that you can copy to your new LDIF ACI definition for editing. Because the value of an ACI is a long string, the output from the ldapsearch operation is likely to be displayed over several lines. In addition, the first space is a continuation marker. If you want the LDIF output to not contain a continuation marker, use the -T option. Take the output format into account when copying and pasting the LDIF output.


    Note –

    To view the permissions that an aci value grants and denies, see Viewing Effective Rights.


ProcedureTo View ACIs at the Root Level

When you create a suffix, some default ACIs are created at the top or root level. These ACIs allow the default administration user cn=admin,cn=Administrators,cn=config to have the same access rights to directory data as the Directory Manager.

You can use DSCC to perform this task. For information, see Directory Service Control Center Interface and the DSCC online help.

  1. View the default root level ACIs.


    $ ldapsearch -h host -p port -D cn=admin,cn=Administrators,cn=config -w - \
     -b "" -s base "(objectclass=*)" aci

ACI Syntax

The aci attribute has the following syntax:

aci: [list of (target)](version 3.0; acl "name";[list of "permission bindRules;"])

The following values are used in the ACI syntax:

target

Specifies the entry, attributes, or set of entries and attributes for which you want to control access. The target can be a distinguished name, one or more attributes, or a single LDAP filter. The target is optional. When a target is not specified, the ACI applies to the entry on which it is defined and its subtree. For information about targets, see ACI Targets.

version 3.0

A required string that identifies the ACI version.

name

A required string that identifies the ACI. Although there are no restrictions on the name, it is good practice to use unique, descriptive names for ACIs. Using unique names, will allow you to use Get Effective Rights to determine which ACI is in force.

permission

States what rights you are allowing or denying. For information about permissions, see ACI Permissions.

bindRules

Specifies the credentials and bind parameters that a user has to provide to be granted access. Bind rules can also be based on user membership, group membership, or connection properties of the client. For information about bind rules, see ACI Bind Rules.

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

Multiple targets and multiple permission-bind rule pairs can be used. This allows you to refine both the entry and attributes being targeted and efficiently set multiple access controls for a given target. The following example shows an ACI with multiple targets and multiple permission-bind rule pairs:

aci: (targetdefinition)...(targetdefinition)(version 3.0;acl "name"; 
permission bindRule; ...; permission bindRule;)

In the following example, the ACI states that bjensen has rights to modify all attributes in her own directory entry:

aci: (target="ldap:///uid=bjensen,dc=example,dc=com")
  (targetattr="*")(targetscope="subtree")(version 3.0; acl "example";
   allow (write) userdn="ldap:///self";)

The following sections describe the syntax of targets, permissions and bind rules.

ACI Targets

An ACI target statement specifies the entry, attributes, or set of entries and attributes for which you want to control access.

Target Syntax

An ACI target statement has this syntax:

(keyword = "expression")

The following values are used in the target.

keyword

Indicates the type of target.

expression

Identifies the target. The quotation marks ("") around expression are syntactically required, although the current implementation accepts expressions like targetattr=*.

=
!=

Indicates that the target is or is not the object specified in the expression.

The != operator cannot be used with the targettrfilters keyword or the targetscope keyword.

Target Keywords

For a description of target keywords, see the following sections:

The following table lists the target keywords and their associated expressions.

Table 6–1 Target Keywords and Their Expressions

Keyword 

Type of target 

Expression 

target

A directory entry or its subtree 

ldap:///distinguished_name

targetattr

The attributes of an entry 

attribute

targetfilter

A set of entries or attributes that match an LDAP filter 

LDAP_filter

targattrfilters

An attribute value or combination of values that match an LDAP filter 

LDAP_operation:LDAP_filter

targetscope

The scope of the target 

base, onelevel, subtree

target Keyword

The target keyword specifies that an ACI is defined for a directory entry. The target keyword uses the following syntax:

(target = "distinguished_name")

or

(target != "distinguished_name")

The distinguished name must be in the subtree rooted at the entry where the ACI is defined. For example, the following target may be used in an ACI on ou=People,dc=example,dc=com:


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

The DN of the entry must be a distinguished name in string representation (RFC 4514). Therefore, characters that are syntactically significant for a DN, such as commas, must be escaped with a single backslash (\).

Wildcards, shown as asterisk characters can be used in the expression for the target keyword. The asterisk matches an attribute value, a substring of a value, or a DN component. For example, all of the following expressions match uid=bjensen,ou=people,dc=example,dc=com.

The following further examples show permitted uses of wildcards.

Other usage of wildcards to such as target="ldap:///uid=bjensen,o*,dc=com" might be accepted, but are deprecated.

targetattr Keyword

The targetattr keyword specifies that an ACI is defined for one or more attributes in the targeted entries. The targetattr keyword uses the following syntax:


(targetattr = "attribute")

or


(targetattr != "attribute")

If no targetattr keyword is present, no attributes are targeted. To target all attributes, the targetattr keyword must be targetattr="*".

Targeted attributes do not need to exist on the target entry or its subtree, but the ACI applies whenever they do.

Targeted attributes do not need to be defined in the schema. The absence of schema checking makes it possible to implement an access control policy before importing data and its schema.

The targetattr keyword can be used for multiple attributes, by using this syntax:


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

Note –

If you configure attribute aliases, you must specify both the attribute name and the alias in the targetattr keyword for the ACI to take them into account.


Targeted attributes include all subtypes of the named attribute. For example, (targetattr = "locality") also targets locality;lang-fr.

Wildcards can be used in the expression for the targetattr keyword, but the use of wildcards would serve no purpose and may reduce performance.

targetfilter Keyword

The targetfilter keyword is used in ACIs to target entries that match an LDAP filter. The ACI applies to all entries that match the LDAP filter and that are in the scope of the ACI. The targetfilter keyword uses the following syntax:


(targetfilter = "(standard LDAP search filter)")

Example 6–1 Using the targetfilter Keyword to Target Specific Entries

The following example is for employees with a status of salaried or contractor, and an attribute for the number of hours worked as a percentage of a full-time position. The filter targets entries for contractors or part-time employees:


(targetfilter = "(|(status=contractor)(fulltime<=79))")

The Netscape extended filter syntax is not supported in ACIs. For example, the following target filter is not valid:


(targetfilter = "(locality:fr:=<= Québec)")

The filter syntax that describes matching rules for internationalized values is supported. For example, the following target filter is valid:


(targetfilter = "(locality:2.16.840.1.113730.3.3.2.18.1.4:=Québec)")

The targetfilter keyword selects whole entries as targets of the ACI. The targetfilter keyword and the targetattr keyword can be used together to create ACIs that apply to a subset of attributes in the targeted entries.

targattrfilters Keyword

The targattrfilters keyword is used in ACIs to target specific attribute values by using LDAP filters. By using the targattrfilters keyword, 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. The targattrfilters keyword uses this syntax:


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

where

add

represents the operation of creating an attribute.

del

represents the operation of deleting an attribute.

attrn

represents the target attributes.

Fn

represents filters that apply only to the associated attribute.

The following conditions must be met when filters apply to entries, and those entries are created, deleted or modified:


Example 6–2 Using the targattrfilters Keyword to Allow Users to Add Roles to Their Own Entries

The following ACI allows users to add any role to their own entry, except the superAdmin role. It also allows users to add a telephone number with a 123 prefix.

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

targetscope Keyword

The targetscope keyword is used in ACIs to specify the scope of the ACI. The targetscope keyword uses this syntax:

(targetscope="base")

The targetscope keyword can have one of these values:

base

The ACI applies to the target resource only

onelevel

The ACI applies to the target resource and its first-generation children

subtree

The ACI applies to the target resource and its subtree

If the targetscope keyword is not specified, the default value is subtree.

ACI Permissions

Permissions specify the type of access that is allowed or denied by the ACI. For information about bind rules, see the following sections:

Permission Syntax

An ACI permission statement has this syntax:

allow|deny (right1, right2 ...)

Rights define the operations you can perform on directory data. In an ACI statement, rights is a list of comma-separated keywords enclosed within parentheses.

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

Permission Rights

The following rights can be allowed or denied in an ACI permission statement:

Read

Permission to read directory data. This permission applies only to the search operation.

Write

Permission to modify an entry by adding, modifying, or deleting attributes. This permission applies to the modify and modify DN operations.

Add

Permission to create entries. This permission applies only to the add operation

Delete

Permission to delete entries. This permission applies only to the delete operation.

Search

Permission to search for directory data. Users must have Search and Read rights in order to view the data returned as part of a search result. This permission applies only to the search operation.

Compare

Permission for users to compare data they supply with data stored in the directory. With compare rights, the directory returns a success or failure message in response to an inquiry, but the user cannot see the value of the entry or attribute. This permission applies only to the compare operation.

Selfwrite

Permission for users to add or delete their own DN in an attribute of the target entry. The syntax of this attribute must be distinguished name. This right is used only for group management. The Selfwrite permission works with proxy authorization; it grants the right to add or delete the proxy DN from the group entry (not the DN of the bound user).

Proxy

Permission for the specified DN to access the target with the rights of another entry. You can grant proxy access using the DN of any user in the directory except the Directory Manager DN. You cannot grant proxy rights to the Directory Manager.

Import

Permission for an entry to be imported to the specified DN. This permission applies the modify DN operation.

Export

Permission for an entry to be exported from the specified DN. This permission applies the modify DN operation.

All

Permission for the specified DN to have the following rights for the targeted entry: read, write, search, delete, compare, and selfwrite. The All access right does control permission for the following rights to the target entry: proxy, import, and export.

Permissions for Typical LDAP Operations

This section describes the rights required to perform a set of LDAP operations.

Adding an entry:
  • Grant add permission on the entry being added.

  • Grant write permission on the value of each attribute in the entry. This right is granted by default but could be restricted using the targettrfilters keyword.

Deleting an entry:
  • Grant delete permission on the entry to be deleted.

  • Grant write permission on the value of each attribute in the entry. This right is granted by default but could be restricted using the targettrfilters keyword.

Modifying an attribute in an entry:
  • Grant write permission on the attribute type.

  • Grant write permission on the value of each attribute type. This right is granted by default but could be restricted using the targettrfilters keyword.

Modifying the RDN of an entry:
  • Grant write permission on the entry.

  • Grant write permission on the attribute type used in the new RDN.

  • Grant write permission on the attribute type used in the old RDN, if you want to grant the right to delete the old RDN.

  • Grant write permission on the value of attribute type used in the new RDN. This right is granted by default but could be restricted using the targettrfilters keyword.

Moving an entry to another subtree:
  • Grant export permissions on the entry that you want to move.

  • Grant import permission on the new superior entry of the entry that you want to move.

Comparing the value of an attribute:

Grant compare permission on the attribute type.

Searching for entries:
  • Grant search permission on each attribute type used in the search filter.

  • Grant read permission on at least one attribute type used in the entry to ensure that the entry is returned.

  • Grant read permission an each attribute type to be returned with the entry.


Example 6–3 Granting ACI Permissions to Perform a Search

The following ACI determines whether bjensen can be granted access for searching her own entry:

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 allow bjensen the right to search on the objectclass attribute. To perform the search operation described, you must modify the ACI as follows:

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

ACI Bind Rules

Bind rules identify the set of users to which an ACI applies. The permission and bind rule portions of the ACI are set as a pair. The specified permission to access the target is granted or denied depending on whether the accompanying bind rule is evaluated to be true or false.

For information about bind rules, see the following sections:

Introduction to Bind Rules

Bind rules identify a set of users by using the following methods:

A simple bind rule might require a person accessing the directory to belong to a specific group. A complex bind rule can require a person to belong to a specific group and to log in from a machine with a specific IP address, between 8 am and 5 pm. Additionally, bind rules can be complex constructions that combine these criteria by using Boolean operators.

The server evaluates the logical expressions used in ACIs according to a three-valued logic, similar to the one used to evaluate LDAP filters, as described in section 4.5.1.7 of RFC 4511 Lightweight Directory Access Protocol (v3). Therefore, if any component in the expression evaluates to Undefined (for example if the evaluation of the expression aborted due to a resource limitation), then the server handles this case correctly. The server does not erroneously grant access because an Undefined value occurred in a complex Boolean expression.

Bind Rule Syntax

An ACI bind rule has this syntax:

keyword = "expression";

or

keyword != "expression";

The following values are used in the bind rule:

keyword

Indicates the type of bind rule.

expression

Identifies the bind rule.

Bind Rule Keywords

For information about bind rule keywords, see the following sections:

The following table summarizes the keywords for bind rules.

Table 6–2 Bind Rule Keywords and Their Expressions

Keyword 

Used to define access based on 

Expression 

userdn

Specified user 

ldap:///distinguished_name
ldap:///all
ldap:///anyone
ldap:///self
ldap:///parent
ldap:///suffix??sub?(filter)

groupdn

Specified group or groups 

[ldap:///DN]

roledn

Specified role or roles 

[ldap:///DN]

userattr

Matched attribute value 

attribute#bindType

or 

attribute#value

ip

Specified IP address or IP addresses 

IP_address

dns

Specified domain or domains 

DNS_host_name

timeofday

Specified time of day 

0 - 2359

dayofweek

Specified day or days of the week 

sun, mon, tue, wed, thu, fri, and sat

authmethod

Specified authentication method 

none, simple, ssl, sasl authentication_method

userdn Keyword

The userdn keyword is used to allow or deny access to a specified user. The following sections contain more information about the userdn keyword.

Syntax of the userdn Keyword

The userdn keyword uses this syntax:

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

The userdn keyword can alternatively be expressed as an LDAP URL filter. For information about expressing the userdn keyword as an LDAP URL, see LDAP URLs in the userdn Keyword.

dn can have of the following values:

distinguished-name

A fully qualified DN. Characters that are syntactically significant for a DN, such as commas, must be escaped with a single backslash (\). The wildcard * can be used to specify a set of users. For example, if the following user DN is specified, users with a bind DN beginning with the letter b are allowed or denied access:

uid=b*,dc=example,dc=com
anyone

Allows or denies access for anonymous and authenticated users, regardless of the circumstances of the bind.

This access can be limited to specific types of access (for example, access for read or access for search) or to specific subtrees or individual entries within the directory. The following ACI on the dc=example,dc=com node allows anonymous access to read and search the entire dc=example,dc=com tree.

aci: (version 3.0; acl "anonymous-read-search"; 
 allow (read, search) userdn = "ldap:///anyone";)
all

Allows or denies access for authenticated users. This all value prevents anonymous access. The following ACI on the dc=example,dc=com node allows authenticated users to read the entire dc=example,dc=com tree:

aci: (version 3.0; acl "all-read"; 
 allow (read) userdn="ldap:///all";)
self

Allows or denies users access to their own entries if the bind DN matches the DN of the targeted entry. The following ACI on the dc=example,dc=com node allows authenticated users in the dc=example,dc=com tree to write to their userPassword attribute.

aci: (targetattr = "userPassword") 
 (version 3.0; acl "modify own password"; allow (write) 
 userdn = "ldap:///self";)
parent

Allows or denies users access to the entry if the bind DN is the parent of the targeted entry.

The following ACI on the dc=example,dc=com node allows authenticated users in the dc=example,dc=com tree to modify any child entries of their bind DN:

aci: (version 3.0; acl "parent access"; 
 allow (write) userdn="ldap:///parent";)

LDAP URLs in the userdn Keyword

The userdn keyword can also be expressed as an LDAP URL with a filter, by using this syntax:

userdn = ldap:///suffix??sub?(filter)

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

The following ACI on the dc=example,dc=com node allows all users in the accounting and engineering branches of the example.com tree to access to the targeted resource dynamically based on the following URL

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

LDAP URLs can be used with the logical OR operator and the not-equal operator as shown in the following examples.


Example 6–4 Using the userdn Keyword With a Logical OR Operator in LDAP URLs

This bind rule is evaluated to be true for users that bind with either of the specified DN patterns.

userdn = "ldap:///uid=b*,c=example.com || ldap:///cn=b*,dc=example,dc=com";


Example 6–5 Using the userdn Keyword With a Not-Equal Operator in LDAP URLs

This bind rule is evaluated to be true if the client is not binding as a UID-based DN 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:///uid=*,ou=Accounting,dc=example,dc=com";

groupdn Keyword

The groupdn keyword specifies that access to a targeted entry is granted or denied if the user binds by using a DN that belongs to a specific group. The groupdn keyword uses this syntax:

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

The bind rule is evaluated to be true if the bind DN belongs to a group that is specified by any of the values for groupDN.

In the following example, the bind rule is true if the bind DN belongs to the Administrators group :

aci: (version 3.0; acl "Administrators-write"; allow (write)
 groupdn="ldap:///cn=Administrators,dc=example,dc=com";)

Characters that are syntactically significant for a DN, such as commas, must be escaped with a single backslash (\).

roledn Keyword

The roledn keyword specifies that access to a targeted entry is 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 this 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.

Characters that are syntactically significant for a DN, such as commas, must be escaped with a single backslash (\).

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

userattr Keyword

The userattr keyword specifies which attribute values in the entry that was used to bind must match those in the targeted entry. The userattr keyword can be used for the following attributes:

An attribute generated by a Class of Service (CoS) definition cannot be used with the userattr keyword. ACIs that contain bind rules that depend on attribute values generated by CoS will not work.

The userattr keyword uses this syntax:

userattr = "attrName#bindType"

Alternatively, if you are using an attribute type that requires a value other than a user DN, group DN, role DN, or an LDAP filter, the userattr keyword uses this syntax:

userattr = "attrName#attrValue"

The userattr keyword can have one of the following values:

attrName

The name of the attribute used for value matching

bindType

One of the following types of bind: USERDN,GROUPDN,ROLEDN,LDAPURL

attrValue

Any string that represents an attribute value

Examples of userattr Keyword With Various Bind Types


Example 6–6 Using the userattr Keyword With the 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 6–7 Using the userattr Keyword With the 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 directory. 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.



Example 6–8 Using the userattr Keyword With the 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.

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



Example 6–9 Using the userattr Keyword With the 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 6–10 Using the userattr Keyword With Any Attribute Value

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

userattr = "favoriteDrink#Milk"

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


Use of the userattr Keyword With the parent Keyword for Inheritance

The userattr keyword can be used with the parent keyword to specify the number of levels below the target that should inherit the ACI. The userattr keyword and parent keyword use this syntax:

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

The userattr keyword and parent keyword can have the following values:

inheritance_level

A comma separated list that indicates how many levels below the target should inherit the ACI. These levels below the targeted entry can be specified: [0,1,2,3,4]. Zero (0) indicates the targeted entry.

attribute

The attribute targeted by the userattr or groupattr keyword.

bindType

The type of bind can be USERDN or GROUPDN. Inheritance cannot be used with LDAPURL and ROLEDN binds.

The following example shows how the userattr keyword is used with the parent keyword for inheritance:

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.

Use of the userattr Keyword to Grant Add Permissions

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, for ACIs that use 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, that is, 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.

ip Keyword

The ip keyword is used to specify that a bind operation must originate from a specific IP address. The ip keyword uses this syntax:

ip = "IPaddressList" or ip != "IPaddressList"

The IPaddressList value is a list of one or more comma-separated elements from the following elements:

The bind rule is evaluated to be true if the client accessing the directory is located at the named IP address.

The ip keyword can be used to force all directory updates to occur from a given machine or network domain. However, the IP address from which a user authenticates can be spoofed, and can therefore not be trusted. Do not base ACIs on this information alone.

The wildcard * can be used to specify a set of IP addresses.

The wildcard * cannot be used in IPv6 addresses.

dns Keyword


Note –

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 is used to specify that a bind operation must originate from a specific domain or host machine. The dns keyword uses this syntax:

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

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.

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. Note that wildcards do not work if your system uses a naming service other than DNS.

timeofday Keyword

The timeofday keyword is used to specify that access can occur at a certain time of day. The time and date on the server are used for the evaluation of the timeofday and dayofweek bind rules, and not the time on the client. The timeofday keyword uses this syntax:

timeofday operator "time"

The timeofday keyword can have the following values:

operator
  • Equal to (=)

  • Not equal to (!=)

  • Greater than or equal to (>=)

  • Less than (<)

  • Less than or equal to (<=)

time

Four digits representing hours and minutes in the 24-hour clock (0 to 2359)

  • timeofday = "1200"; is true if the client is accessing the directory during the minute that the system clock shows noon.

  • timeofday != "0100"; is true for access at any other time than 1 a.m.

  • timeofday > "0800"; is true for access from 8:01 a.m. through 11:59 p.m.

  • timeofday >= "0800"; is true for access from 8:00 a.m. through 11:59 p.m.

  • timeofday < "1800"; is true for access from 12:00 midnight through 5:59 p.m.

dayofweek Keyword

The dayofweek keyword is used to specify that access can occur on a certain day or on certain days of the week. The time and date on the server are used for the evaluation of the timeofday and dayofweek bind rules, and not the time on the client. The dayofweek keyword uses this syntax:

dayofweek = "day1, day2 ..."

The bind rule is true if the directory is being accessed on one of the days listed.

The dayofweek keyword can have one or more of the following values: sun, mon, tue, wed, thu, fri, sat.

authmethod Keyword

The authmethod keyword is used to specify that a client must bind to the directory by using a specific authentication method. The authmethod keyword uses this syntax:

authmethod = "authentication_method"

The authmethod keyword can have the following values:

None

Authentication is not checked during bind rule evaluation. This is the default.

Simple

The bind rule is evaluated to be true if the client is accessing the directory using a username and password.

SSL

The client must bind to the directory over a Secure Sockets Layer (SSL) or Transport Layer Security (TLS) connection.

The bind rule is evaluated to be true if the client authenticates to the directory by using a certificate over LDAPS. It will not be true if the client authenticates by using simple authentication (bind DN and password) over LDAPS.

SASL sasl_mechanism

The bind rule is evaluated to be true if the client authenticates to the directory by using one of the following SASL mechanisms: DIGEST-MD5, GSSAPI, or EXTERNAL.

Boolean Bind Rules

Bind rules can be complex expressions that use the Boolean expressions AND, OR, and NOT to set precise access rules. Boolean bind rules use this syntax:

(bindRuleA and (bindRuleB or (bindRuleC and bindRuleD));)

Parentheses defines the order in which rules are evaluated, and a trailing semicolon must appear after the final rule.


Example 6–11 Boolean Bind Rule

The bind rule is true if both of the following conditions are met:

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

ProcedureTo Allow Normal Users to Manage User Accounts Using dsutil Command

  1. Add the following ACIs to allow users to manage other user accounts using the dsutil command.


    $ldapmodify -h host -p port -D cn=admin,cn=Administrators,cn=config -w - -c 
    dn: cn=config
    changetype: modify
    add: aci
    aci: (targetattr="*")(version 3.0; acl "Allow the Suffix Manager to browse the tree"; \
    allow (read,search,compare)userdn = "ldap:///$USERSFXADMIN";)
    aci: (targetattr="nsslapd-rootpw")\
    (version 3.0; acl "Prevent the Suffix Manager from accessing passwords"; \
    deny (all)userdn = "ldap:///$USERSFXADMIN";)
    aci: (targetattr="userPassword")\
    (version 3.0; acl "Prevent the Suffix Manager from accessing passwords"; \
    deny (all)userdn = "ldap:///$USERSFXADMIN";)
    aci: (targetattr="dsKeyedPassword")\
    (version 3.0; acl "Prevent the Suffix Manager from accessing passwords"; \
    deny (all)userdn = "ldap:///$USERSFXADMIN";)

    For more information about dsutil command, see dsutil(1M).

Access Control Usage Examples

The examples in this section illustrate how an imaginary ISP company, Example.com, would implement its access control policy.

In addition, you can find ACI examples in the example LDIF file provided with your installation, install_path/resources/ldif/Example.ldif.

All of the examples explain how to perform a given task by using an LDIF file. The following figure shows the example.com Directory Information Tree in graphical form.

Topography of an example directory tree. The top level
entry and the entries directly below the top level entry are shown.

Example.com offers a web hosting service and internet access. Part of Example.com’s web-hosting service is to host the directories of client companies. Example.com actually hosts and partially manages the directories of two medium-sized companies, Company333 and Company999. Example.com also provides internet access to a number of individual subscribers.

Example.com wants to put the following access rules in place:

Granting Anonymous Access

Most directories are configured to enable you to anonymously access at least one suffix for read, search, or compare. You might want to set these permissions if you are running a corporate personnel directory, such as a phone book that you want employees to be able to search. This is the case at Example.com internally, as shown in ACI “Anonymous Example.com”.

As an ISP, Example.com also wants to advertise the contact information of all of its subscribers by creating a public phone book that is accessible to the world. This is depicted in ACI “Anonymous World”.

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") ;)

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


Note –

Protect attributes that are confidential and attributes that should not be visible using the same syntax used in the example to protect the password attribute, (targetattr !="attribute-name").


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 subscribers who want to be unlisted, you could write the following statement:


aci: (targetfilter= "(!(unlistedSubscriber=yes))")
 (targetattr="homePostalAddress || homePhone || mail")
 (version 3.0; acl "Anonymous World"; allow (read, search)
 userdn="ldap:///anyone";)

This example assumes that the ACI is added to the ou=subscribers,dc=example, dc=com entry. The example also assumes that every subscriber entry has an unlistedSubscriber attribute that is set to yes or no. The target definition filters out the unlisted subscribers based on the value of this attribute. For details on the filter definition, refer to Setting a Target Using Filtering.

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 depicted in ACI “Write Example.com”.

Example.com also has a policy to let their subscribers update their own personal information in the Example.com tree provided that the subscribers establish an SSL connection to the directory. This is depicted in ACI “Write Subscribers”.

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


aci: (targetattr="homePhone ||
 homePostalAddress")(version 3.0; acl "Write Example.com";
 allow (write) userdn="ldap:///self" ;)

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

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


aci: (targetattr="homePhone")
 (version 3.0; acl "Write Subscribers"; allow (write)
 userdn= "ldap://self" and authmethod="ssl";)

This example assumes that the aci is added to the ou=subscribers,dc=example, dc=com entry, and that users must bind using SSL.

Note that Example.com subscribers do not have write access to their home address because they might delete that attribute. The home address is business-critical information that Example.com needs for billing purposes.

Granting Access to a Certain Level

You can set the scope of an ACI to affect different levels within your directory tree, to fine-tune the level of access you want to allow. The target ACI scope can be set to one of the following:

base

The entry itself

onelevel

The entry itself and all entries one level below

subtree

The entry itself and all entries beneath that entry, to an unlimited depth

ACI “Read Example.com only”

In LDIF, to grant Example.com subscribers the right to read the entry dc=example,dc=com for company contact information, but not allow access to any entries below it, you would write the following statement:


aci: (targetscope="base") (targetattr="*")(version 3.0;
 acl "Read Example.com only";  allow (read,search,compare)
 userdn="ldap:///cn=*,ou=subscribers,dc=example,dc=com";)

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

Restricting Access to Key Roles

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

For example, you might create a superAdmin role by identifying a subset of your system administrators who are available at a particular time of day and day of the week at corporate sites worldwide. Or you might want to create a First Aid role that includes all staff members who have first aid training at a particular site. For information about creating role definitions see Managing Roles.

When a role gives any sort of privileged user rights over critical corporate or business functions, consider restricting access to that role. For example, at Example.com, employees can add any role to their own entry, except the superAdmin role, as shown in the following example.

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="*") (targattrfilters="add=nsRoleDN:
 (nsRoleDN !="cn=superAdmin, dc=example, dc=com")")
 (version 3.0; acl "Roles"; allow (write)
 userdn= "ldap:///self" ;)

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

Granting a Role Full Access to an Entire Suffix

Sometimes it is useful to grant certain users the same rights as the Directory Manager for a suffix. At Example.com, Kirsten Vaughan is an administrator for Directory Server. She has a role of superAdmin. This role has the following advantages:


Note –

Adding Kirsten Vaughan to the cn=Administrators,cn=config group would also grant her the same rights as Directory Manager.


To give a user the same rights as the Directory Manager for the whole server, follow the procedure in To Create an Administration User with Root Access.

ACI “Full Access”

In LDIF, to grant the administrator Kirsten Vaughan the same rights as a Directory Manager, use the following statement:


aci: (targetattr="*") (version 3.0; acl "Full Access";
 allow (all) groupdn= "ldap:///cn=SuperAdmin,dc=example,dc=com"
 and authmethod="ssl" ;)

This example assumes that the ACI is added to the root entry "" (no text).

Granting a Group Full Access to a Suffix

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

For example, when you create a Directory Server instance, an Administrators group cn=Administrators,cn=config with full access to the directory is created by default.

At Example.com, the Human Resources group is allowed full access to the ou=People branch of the directory so that they can update the employee directory, as shown in ACI “HR”.

ACI “HR”

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


aci: (targetattr="*") (version 3.0; acl "HR"; allow (all)
  groupdn= "ldap:///cn=HRgroup,ou=Groups,dc=example,dc=com";)

This example assumes that the ACI is added to the following entry:


ou=People,dc=example,dc=com

Granting Rights to Add and Delete Group Entries

Some organizations allow employees to create entries in the tree to increase employees' efficiency and to encourage employees to contribute to the corporate dynamics. At Example.com, for example, the social committee is organized into various clubs, such as tennis, swimming, skiing, and role-playing.

Any Example.com employee can create a group entry that represents a new club, as shown in ACI “Create Group”.

Any Example.com employee can become a member of one of these groups, as shown in Allowing Users to Add or Remove Themselves From a Group.

Only the group owner can modify or delete a group entry, as shown in ACI “Delete Group”.

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: (targetattr="*") (targattrfilters="add=objectClass: 
(|(objectClass=groupOfNames)(objectClass=top))") 
(version 3.0; acl "Create Group"; allow (read,search,add) 
userdn= "ldap:///uid=*,ou=People,dc=example,dc=com") 
and dns="*.Example.com";)

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


Note –

ACI “Delete Group”

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


aci: (targetattr = "*") (targattrfilters="del=objectClass:
(objectClass=groupOfNames)")
 (version 3.0; acl "Delete Group"; allow (write,delete)
 userattr="owner#GROUPDN";)

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

Note that to use DSCC to create this ACI is not very effective because you have to use manual editing mode to create the target filter and to check group ownership.

Allowing Users to Add or Remove Themselves From a Group

Many directories set ACIs that allow users to add or remove themselves from groups such as mailing lists.

At Example.com, employees can add themselves to any group entry under the ou=Social Committee subtree, as shown in ACI “Group Members”.

ACI “Group Members”

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


aci: (targettattr="member")(version 3.0; acl "Group Members";
 allow (selfwrite)
 (userdn= "ldap:///uid=*,ou=People,dc=example,dc=com") ;)

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

Granting Conditional Access to a Group or Role

In many cases, when you grant a group or role privileged access to the directory, you must ensure that those privileges are protected from intruders trying to impersonate your privileged users. Therefore, in many cases, access control rules that grant critical access to a group or role are often associated with a number of conditions.

Example.com, for example, has created a Directory Administrator role for each of its hosted companies, Company333 and Company999. Example.com wants these companies to be able to manage their own data and implement their own access control rules while securing the data against intruders.

For this reason, Company333 and Company999 have full rights on their respective branches of the directory tree, provided that the following conditions are fulfilled:

These conditions are depicted in one ACI for each company, ACI “Company333” and ACI “Company999”. Because the content of both ACIs is the same, the following examples use the “Company333” ACI only.

ACI “Company333”

In LDIF, to grant Company333 full access to its own branch of the directory under the conditions stated previously, you would write the following statement:


aci: (targetattr = "*") (version 3.0; acl "Company333"; allow (all)
 (roledn="ldap:///cn=DirectoryAdmin,ou=Company333,
 ou=corporate clients,dc=example,dc=com") and (authmethod="ssl")
 and (dayofweek="Mon,Tues,Wed,Thu") and (timeofday >= "0800" and
 timeofday <= "1800") and (ip="255.255.123.234"); )

This example assumes that the ACI is added to the ou=Company333,ou=corporate clients,dc=example,dc=com entry.

Denying Access

If you have already allowed access to a large part of your suffix, you might want to deny access to a smaller part of the suffix beneath the existing ACI.


Note –

Denying access should be avoided where possible, because it can lead to surprising or complicated access control behavior. Restrict access by using a combination of scoping, attribute lists, target filters and so on.

Also, deleting a deny access ACI does not remove rights, but instead expands the rights set by other ACIs.


When the Directory Server evaluates access rights, it reads deny rights first, then allow rights.

In the examples that follow, Example.com wants all subscribers to be able to read billing information, such as connection time or account balance, under their own entries. Example.com also explicitly wants to deny write access to that information. The read access is depicted in ACI “Billing Info Read”. The deny access is depicted in ACI “Billing Info Deny”.

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.

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.

Proxy Authorization

The proxy authorization method is a special form of authentication. A user that binds to the directory by using his or her own identity is granted the rights of another user through proxy authorization.

To configure Directory Server to allow proxy requests you must do the following:


Note –

You can grant proxy rights to any users of the directory except the Directory Manager. In addition, you cannot use the Directory Manager’s DN as a proxy DN. You need to exercise great care when granting proxy rights because you grant the right to specify any DN (except the Directory Manager DN) as the proxy DN. If Directory Server receives more than one proxied authentication control in the same operation, an error is returned to the client application and the operation attempt is unsuccessful.


Example Proxy Authorization

Example.com wants the client application that binds as MoneyWizAcctSoftware to have the same access rights to the LDAP data as an Accounting Administrator.

The following parameters apply:

For the client application to gain access to the Accounting subtree, by using the same access permissions as the Accounting Administrator, the following must be true:

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

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


$ ldapsearch -D "uid=MoneyWizAcctSoftware,ou=Applications,dc=example,dc=com" -w - \
 -Y "dn: uid=AcctAdministrator,ou=Administrators,dc=example,dc=com" ...

If the client wanted to perform an ldapmodify command, the command would include the following controls:


$ ldapmodify -h hostname -p port \
-D "uid=MoneyWizAcctSoftware,ou=Applications,dc=example,dc=com" -w - \
-Y"dn: uid=AcctAdministrator,ou=Administrators,dc=example,dc=com"
dn: uid=AcctAdministrator,ou=Administrators,dc=example,dc=com
changetype: modify
delete: userpassword
-
add: userpassword
userpassword: admin1

Note that the client binds as itself, but is granted the privileges of the proxy entry. The client does not need the password of the proxy entry.

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 might want to use a filter to set the target.

In LDIF, to use a filter to allow all users in HR access to employee entries, you would write the following statement:


aci: (targetattr="*") (targetfilter=(objectClass=employee))
 (version 3.0; acl "HR access to employees";
 allow (all) groupdn= "ldap:///cn=HRgroup,ou=People,dc=example,dc=com";)

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


Note –

Because search filters do not directly name the object for which you are managing access, try not to allow or deny access to the wrong objects. Unintentionally allowing or denying access to the wrong objects becomes more of a risk as your directory becomes more complex. Additionally, filters can make it difficult for you to troubleshoot access control problems within your directory.


Defining Permissions for DNs That Contain a Comma

DNs that contain commas require special treatment within your LDIF ACI statements. In the target and bind rule portions of the ACI statement, commas must be escaped by a single backslash (\). The following example illustrates this syntax:


dn: o=Example.com Bolivia\, S.A. 
objectClass: top 
objectClass: organization 
aci: (target="ldap:///o=Example.com Bolivia\,S.A.") (targetattr="*") 
(version 3.0; acl "aci 2"; allow (all) groupdn = 
"ldap:///cn=Directory Administrators, o=Example.com Bolivia\, S.A.";)

Viewing Effective Rights

When maintaining the access policy on the entries of a directory, you need to know the effects on security of the ACIs that you define. Directory Server enables you to evaluate existing ACIs by viewing the effective rights that the ACIs grant for a given user on a given entry.

Directory Server responds to the “Get Effective Rights”, control which can be included in a search operation. The response to this control is to return the effective rights information about the entries and attributes in the search results. This extra information includes read and write permissions for each entry and for each attribute in each entry. The permissions can be requested for the bind DN that is used for the search or for an arbitrary DN. This choice allows administrators to test the permissions of directory users.

Effective rights functionality relies on an LDAP control. You must ensure that the proxy identity used to bind to the remote server is also allowed to access the effective rights attributes.

Restricting Access to the Get Effective Rights Control

The operation of viewing effective rights is a directory operation that needs to be protected and appropriately restricted.

To restrict access to effective rights information, modify the default ACI for getEffectiveRights attribute. Then create a new ACI for the getEffectiveRightsInfo attribute .

For example, the following ACI allows only members of the Directory Administrators Group to get effective rights:


aci: (targetattr != "aci")(version 3.0; acl
 "getEffectiveRights"; allow(all) groupdn =
 "ldap:///cn=Directory Administrators,ou=Groups,dc=example,dc=com";)

To obtain effective rights information, you need to have access control rights to use the Effective Rights control and read access to the aclRights attribute. This double layer of access control provides basic security that can be more finely tuned if necessary. By analogy with proxy, if you have read access to the aclRights attribute in an entry, you can request information about anyone’s rights to that entry and its attributes. This implies that the user who manages the resource can determine who has rights to that resource, even if that user does not actually manage those with the rights.

If a user requesting rights information does not have the rights to use the Effective Rights control, the operation fails and an error message is returned. However, if the user requesting rights information does have the rights to use the control but lacks the rights to read the aclRights attribute, the aclRights attribute will not appear in the returned entry. This behavior reflects Directory Server’s general search behavior.

Using the Get Effective Rights Control

Specify the “Get Effective Rights” control by using the ldapsearch command with the -J "1.3.6.1.4.1.42.2.27.9.5.2" option. By default, the control returns the effective rights of the bind DN entry on the entries and attributes in the search results.

Use the following options to change the default behavior:


Note –

The aclRights and aclRightsInfo attributes behave like virtual operational attributes. These attributes are not stored in the directory and are not returned unless explicitly requested. They are generated by Directory Server in response to the “Get Effective Rights” control.

Thus, these attributes cannot be used in filters or search operations of any kind.


The effective rights feature inherits other parameters that affect access control. These parameters include time of day, authentication method, machine address, and name.

The following example shows how the user Carla Fuente can view her rights in the directory. In the results, 1 means that permission is granted, and 0 means that permission is denied.


$ ldapsearch -J "1.3.6.1.4.1.42.2.27.9.5.2" -h host1.Example.com -p 389 \
 -D "uid=cfuente,ou=People,dc=example,dc=com" -w - -b "dc=example,dc=com" \
 "(objectclass=*)" aclRights

Enter bind password:
dn: dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: ou=Groups, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: ou=People, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: cn=Accounting Managers,ou=groups,dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: cn=HR Managers,ou=groups,dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: uid=bjensen,ou=People, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: uid=cfuente, ou=People, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:1,proxy:0

This result shows Carla Fuente the entries in the directory where she has at least read permission and shows that she can modify her own entry. The Effective Rights control does not bypass normal access permissions, so a user does not see the entries for which they do not have read permission. In the following example, the Directory Manager can see the entries to which Carla Fuente does not have read permission:


$ ldapsearch -h host1.Example.com -p 389 -D cn=admin,cn=Administrators,cn=config -w - \
 -c "dn: uid=cfuente,ou=People,dc=example,dc=com" -b "dc=example,dc=com" \
 "(objectclass=*)" aclRights

Enter bind password:
dn: dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: ou=Groups, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: cn=Directory Administrators, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:0,write:0,proxy:0
dn: ou=Special Users,dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:0,write:0,proxy:0
dn: ou=People, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: cn=Accounting Managers,ou=groups,dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: cn=HR Managers,ou=groups,dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: uid=bjensen,ou=People, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0
dn: uid=cfuente, ou=People, dc=example,dc=com
aclRights;entryLevel: add:0,delete:0,read:1,write:1,proxy:0

In the preceding output, the Directory Manager can see that Carla Fuente cannot even view the Special Users or the Directory Administrators branches of the directory tree. In the following example, the Directory Manager can see that Carla Fuente cannot modify the mail and manager attributes in her own entry:


$ ldapsearch -h host1.Example.com -p 389 -D cn=admin,cn=Administrators,cn=config -w - \
 -c "dn: uid=cfuente,ou=People,dc=example,dc=com" -b "dc=example,dc=com" \
 "(uid=cfuente)" aclRights "*"

Enter bind password:
version: 1
dn: uid=cfuente, ou=People, dc=example,dc=com
aclRights;attributeLevel;mail: search:1,read:1,compare:1,
 write:0,selfwrite_add:0,selfwrite_delete:0,proxy:0
mail: cfuente@Example.com
aclRights;attributeLevel;uid: search:1,read:1,compare:1,
 write:1,selfwrite_add:1,selfwrite_delete:1,proxy:0
uid: cfuente
aclRights;attributeLevel;givenName: search:1,read:1,compare:1,
 write:1,selfwrite_add:1,selfwrite_delete:1,proxy:0
givenName: Carla
aclRights;attributeLevel;sn: search:1,read:1,compare:1,
 write:1,selfwrite_add:1,selfwrite_delete:1,proxy:0
sn: Fuente
aclRights;attributeLevel;cn: search:1,read:1,compare:1,
 write:1,selfwrite_add:1,selfwrite_delete:1,proxy:0
cn: Carla Fuente
aclRights;attributeLevel;userPassword: search:0,read:0,
 compare:0,write:1,selfwrite_add:1,selfwrite_delete:1,proxy:0
userPassword: {SSHA}wnbWHIq2HPiY/5ECwe6MWBGx2KMiZ8JmjF80Ow==
aclRights;attributeLevel;manager: search:1,read:1,compare:1,
 write:0,selfwrite_add:0,selfwrite_delete:0,proxy:0
manager: uid=bjensen,ou=People,dc=example,dc=com
aclRights;attributeLevel;telephoneNumber: search:1,read:1,compare:1,
 write:1,selfwrite_add:1,selfwrite_delete:1,proxy:0
telephoneNumber: (234) 555-7898
aclRights;attributeLevel;objectClass: search:1,read:1,compare:1,
 write:1,selfwrite_add:1,selfwrite_delete:1,proxy:0
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: inetorgperson
aclRights;entryLevel: add:0,delete:0,read:1,write:0,proxy:0

Advanced Access Control: Using Macro ACIs

Organizations that use repeating directory tree structures can optimize the number of ACIs used in the directory by using macros. When you reduce the number of ACIs in your directory tree, it is easier to manage your access control policy. In addition, the efficiency of your ACI memory usage is improved.

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, in the bind rule portion, or in both. In practice, when Directory Server gets an incoming LDAP operation, the ACI macros are matched against the resource targeted by the LDAP operation. The matching occurs in order to determine a matching substring, if any matching substring exists. If a match exists, the bind rule-side macro is expanded using the matched substring, and access to the resource is determined by evaluating that expanded bind rule.

This section contains an example of a macro ACI and information about macro ACI syntax.

Macro ACI Example

The benefits of macro ACIs and how they work are best explained by using an example. Figure 6–1 shows a directory tree in which using macro ACIs is an effective way of reducing the overall number of ACIs.

In this illustration, note the 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 two suffixes dc=hostedCompany2,dc=example,dc=com, and dc=hostedCompany3,dc=example,dc=com, which are not shown in the figure.

The ACIs 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 the domainAdmins group read and search rights to any entry in the dc=hostedCompany1,dc=example,dc=com tree.

Figure 6–1 Example Directory Tree for Macro ACIs

Topography of an example directory tree, showing dc=hostedcompany1,dc=example,dc=com,
and various subdomains.

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 preceding four ACIs, the only difference is the DN that is specified in the groupdn keyword. By using a macro for the DN, it is possible to replace these ACIs with a single ACI at the root of the tree, on the dc=example,dc=com node. This macro 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";)

Note that the target keyword which was not previously used needs to be introduced.

In the preceding example, 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

To simplify the discussion in this section, the ACI keywords such as userdn, roledn, groupdn, and userattr that are used to provide bind credentials are collectively called the subject of the ACI. The subject determines to whom the ACI applies.

The following table shows which macros can be used to replace specific ACI keywords.

Table 6–3 Macro ACI Keywords

Macro 

Description 

ACI Keywords 

($dn)

For matching in the target, and direct substitution in the subject. 

target, targetfilter, userdn, roledn, groupdn, userattr

[$dn]

For substituting multiple RDNs that work in subtrees of the subject. 

targetfilter, userdn, roledn, groupdn, userattr

($attr.attrName)

For substituting the value of the attributeName attribute from the target entry into the subject.

userdn, roledn, groupdn, userattr

The following restrictions apply to macro ACI keywords:

Matching for ($dn) in the Target

The ($dn) macro in the target of an ACI determines the substitution value by comparing it to the entry targeted by the LDAP request. For example, you have an LDAP request targeted at this entry:


cn=all,ou=groups,dc=subdomain1, dc=hostedCompany1,dc=example,dc=com

In addition, you have 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”. This substring is then used for substitutions in the subject of the ACI.

Substituting ($dn) in the Subject

In the subject of the ACI, the ($dn) macro is replaced by the entire substring that matches in the target. For example:


groupdn="ldap:///cn=DomainAdmins,ou=Groups,($dn),dc=example,dc=com"

The subject becomes this:


groupdn="ldap:///cn=DomainAdmins,ou=Groups,
 dc=subdomain1,dc=hostedCompany1,dc=example,dc=com"

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


Note –

Unlike a standard ACI, an ACI that uses macro substitution does not necessarily grant access to the child of the targeted entry. This is because when the child DN is the target, the substitution might not create a valid DN in the subject string.


Substituting [$dn] in the Subject

The substitution 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, suppose that 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: (targetattr="*")
 (target="ldap:///ou=Groups,($dn),dc=example,dc=com")
 (version 3.0; acl "Domain access"; allow (read,search)
 groupdn="ldap:///cn=DomainAdmins,ou=Groups,[$dn],
 dc=example,dc=com";)

    The server proceeds as follows to expand this ACI:

  1. The server verifies that the ($dn) in target matches dc=subdomain1,dc=hostedCompany1.

  2. The server replaces [$dn] in the subject with dc=subdomain1,dc=hostedCompany1.

    The resulting subject is groupdn="ldap:///cn=DomainAdmins,ou=Groups, dc=subdomain1,dc=hostedCompany1,dc=example,dc=com". If access is granted because the bind DN is a member of that group, the macro expansion stops, and the ACI is evaluated. If the bind DN is not a member, the process continues.

  3. The server replaces [$dn] in the subject with dc=hostedCompany1.

    The resulting subject is groupdn="ldap:///cn=DomainAdmins,ou=Groups, dc=hostedCompany1,dc=example,dc=com". Again, the bind DN is tested as a member of this group and if it is, the ACI is evaluated fully. If the bind DN is not a member, macro expansion stops with the last RDN of the matched value, and ACI evaluation is finished for this ACI.

The advantage of the [$dn] macro is that it provides a flexible way to grant domain-level administrators access to all the subdomains in the directory tree. Therefore, the [$dn] macro 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=com";)

The ACI grants access to the members of cn=DomainAdmins,ou=Groups, dc=hostedCompany1,dc=example,dc=com to all of the subdomains under dc=hostedCompany1. Thus, an administrator who belongs 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=subdomain1, 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),dc=HostedCompany1,dc=example,dc=com"

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


dn: cn=Babs Jensen,ou=People,dc=HostedCompany1,dc=example,dc=com
cn: Babs Jensen
sn: Jensen
ou: Sales
...

To evaluate the roledn part of the ACI, the server reads the value of the ou attribute stored in the targeted entry. The server then substitutes this value in the subject to expand the macro. In the example, the roledn is expanded as follows:


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

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

When the attribute that is named in the macro is multivalued, each value is used in turn to expand the macro. The first value that provides a successful match is used.

Logging Access Control Information

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

ProcedureTo Set Logging for ACIs

You cannot use DSCC to perform this task. Use the command line, as described in this procedure.

  1. Set the log level to take into account ACI processing.


    $ dsconf set-log-prop -h host -p port error level:err-acl

Client-Host Access Control Through TCP Wrapping

You can control the host or IP address from which connections are accepted or rejected at the TCP level using TCP wrappers. You can limit client-host access through TCP wrapping. This enables you to have non host-based protection for initial TCP connections to a Directory Server.

Although you can set TCP wrapping for Directory Server, TCP wrapping can result in significant performance degradation, especially during a Denial of Service attack. The best performance is achieved by using a host-based firewall that is maintained outside Directory Server, or IP port filtering.

ProcedureTo Enable TCP Wrapping

You cannot use DSCC to perform this task. Use the command line, as described in this procedure.

  1. Create a hosts.allow file or a hosts.denyfile, somewhere within the instance path.

    For example, create the file in instance-path/config. Ensure that the formatting of the files that you create comply with hosts_access(4).

  2. Set the path to the access file.


    $ dsconf set-server-prop -h host -p port host-access-dir-path:path-to-file
    

    For example:


    $ dsconf set-server-prop -h host -p port \
    host-access-dir-path:/local/ds1/config
    "host-access-dir-path" property has been set to "/local/ds1/config".
    The "/local/ds1/config" directory on host1 must contain valid hosts.allow
    and/or hosts.deny files.
    Directory Server must be restarted for changes to take effect. 

ProcedureTo Disable TCP Wrapping

You cannot use DSCC to perform this task. Use the command line, as described in this procedure.

  1. Set the host access path to "".


    $ dsconf set-server-prop -h host -p port host-access-dir-path:""