18.14. Advanced Access Control: Using Macro ACIs Macro ACIs improve the flexibility. For example, you can add a subtree and automatically get the same tailored access controls as for other subtrees without the need to add any ACI. As a side effect, the number of ACIs is smaller, however, Macro ACI processing is more expensive than a regular ACI. 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. 18.14.1. Macro ACI Example Figure 18.1, "Example Directory Tree for Macro ACIs" shows a directory tree which uses macro ACIs to effectively reduce 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 Corp. 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: This ACI grants read and search rights to the DomainAdmins group to any entry in the dc=hostedCompany1,dc=example,dc=com tree. Figure 18.1. Example Directory Tree for Macro ACIs The following ACI is located on the dc=hostedCompany1,dc=example,dc=com node: The following ACI is located on the dc=subdomain1,dc=hostedCompany1,dc=example,dc=com node: The following ACI is located on the dc=hostedCompany2,dc=example,dc=com node: The following ACI is located on the dc=subdomain1,dc=hostedCompany2,dc=example,dc=com node: 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: The target keyword, which was not previously used, is utilized in the new ACI. In this example, the number of ACIs is reduced from four to one. The real benefit is a factor of how many repeating patterns you have down and across your directory tree. 18.14.2. Macro ACI Syntax Macro ACIs include the following types of expressions to replace a DN or part of a DN: (USDdn) [USDdn] (USDattr. attrName ), where attrName represents an attribute contained in the target entry 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 18.5, "Macros in ACI Keywords" shows in what parts of the ACI you can use DN macros: Table 18.5. Macros in ACI Keywords Macro ACI Keyword (USDdn) target, targetfilter, userdn, roledn, groupdn, userattr [USDdn] targetfilter, userdn, roledn, groupdn, userattr (USDattr. attrName ) userdn, roledn, groupdn, userattr The following restrictions apply: If you use (USDdn) in targetfilter , userdn , roledn , groupdn , userattr , you must define a target that contains (USDdn) . If you use [USDdn] in targetfilter , userdn , roledn , groupdn , userattr , you must define a target that contains (USDdn) . Note When using any macro, you always need a target definition that contains the (USDdn) macro. You can combine the (USDdn) macro and the (USDattr. attrName ) macro. 18.14.2.1. Macro Matching for (USDdn) The (USDdn) 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: The (USDdn) macro matches with dc=subdomain1,dc=hostedCompany1 . When the subject of the ACI also uses (USDdn) , the substring that matches the target is used to expand the subject. For example: In this case, if the string matching (USDdn) in the target is dc=subdomain1,dc=hostedCompany1 , then the same string is used in the subject. The ACI is then expanded as follows: Once the macro has been expanded, Directory Server evaluates the ACI following the normal process to determine whether access is granted. 18.14.2.2. Macro Matching for [USDdn] The matching mechanism for [USDdn] is slightly different than for (USDdn) . 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: The steps for expanding this ACI are as follows: (USDdn) in the target matches dc=subdomain1,dc=hostedCompany1 . [USDdn] in the subject is replaces 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. [USDdn] in the subject is replaced 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 [USDdn] 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: 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 a subtree like 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=subdomain1,dc=hostedCompany1 nodes. 18.14.2.3. Macro Matching for (USDattr.attrName) The (USDattr. attrName ) macro is always used in the subject part of a DN. For example, define the following roledn : Now, assume the server receives an LDAP operation targeted at the following entry: 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: 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. For example: In this case, when the Directory Server evaluates the ACI, it performs a logical OR on the following expanded expressions:

Commands:
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";)
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";)
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";)
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";)
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";)
aci: (target="ldap:///ou=Groups,(USDdn),dc=example,dc=com") (targetattr="*")(targetfilter=(objectClass=nsManagedDomain)) (version 3.0; acl "Domain access"; allow (read,search) groupdn="ldap:///cn=DomainAdmins,ou=Groups,[USDdn],dc=example,dc=com";)
(target="ldap:///ou=Groups,(USDdn),dc=example,dc=com")
aci: (target="ldap:///ou=*,(USDdn),dc=example,dc=com") (targetattr = "*") (version 3.0; acl "Domain access"; allow (read,search) groupdn="ldap:///cn=DomainAdmins,ou=Groups,(USDdn),dc=example,dc=com";)
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";)
aci: (target="ldap:///ou=Groups,(USDdn),dc=example,dc=com") (targetattr = "*") (version 3.0; acl "Domain access"; allow (read,search) groupdn="ldap:///cn=DomainAdmins,ou=Groups,[USDdn],dc=example,dc=com";)
aci: (target="ldap:///ou=*, (USDdn),dc=example,dc=com") (targetattr="*")(targetfilter=(objectClass=nsManagedDomain)) (version 3.0; acl "Domain access"; allow (read,search) groupdn="ldap:///cn=DomainAdmins,ou=Groups,[USDdn],dc=example,dc=com";)
roledn = "ldap:///cn=DomainAdmins,(USDattr.ou)"
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
roledn = "ldap:///cn=DomainAdmins,ou=Engineering,dc=HostedCompany1,dc=example,dc=com"
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
roledn = "ldap:///cn=DomainAdmins,ou=Engineering,dc=HostedCompany1,dc=example,dc=com" roledn = "ldap:///cn=DomainAdmins,ou=People,dc=HostedCompany1,dc=example,dc=com"