Chapter 2. Using macro access control instructions Macro access control instructions (ACIs) provides you with the possibility to automate the tailored access to an LDAP entry distinguished name (DN) or to its part and reduce the number of ACIs. 2.1. Macro access control instruction example The picture below shows a directory tree with suffixes dc=hostedCompany1,dc=example,dc=com and dc=hostedCompany2,dc=example,dc=com with the repetitive pattern of subdomains. Each subdomain has the same structure of ou=groups , ou=people entries. The directory tree uses macro access control instructions (ACIs) to reduce the total number of ACIs. 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 and grants read and search rights to the DomainAdmins group to any entry in that tree: 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";) Figure 2.1. Directory tree for macro ACI example The ACIs below show the different part of DN in the groupdn keyword: The dc=hostedCompany1,dc=example,dc=com node contains the following ACI: The dc=subdomain1,dc=hostedCompany1,dc=example,dc=com node contains the following ACI: The dc=hostedCompany2,dc=example,dc=com node contains the following ACI: The dc=subdomain1,dc=hostedCompany2,dc=example,dc=com node contains the following ACI: Use the macro to replace multiple ACIs for repetitive patterns. For example, to reduce the ACIs above to one, use the following macro: 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";) 2.2. Macro access control instruction syntax Macro access control instructions (ACIs) include the following types of expressions to replace a DN or a part of a DN: (USDdn) , [USDdn] , (USDattr. attrName ) , where attrName represents an attribute which is the part of the target entry. The ACI keywords provide bind credentials which are the subject of the ACI. The subject determines where the ACI applies. Table 2.1. Macros for ACI keywords Macro ACI keywords Description (USDdn) target, targetfilter, userdn, roledn, groupdn, userattr Matching and direct substitution in the subject. It will match to target or to targetfilter and substitute the matched value into userdn , groupdn , or userattr . [USDdn] targetfilter, userdn, roledn, groupdn, userattr Substitution of multiple RDNs that work in subtrees of the subject. (USDattr. attrName ) userdn, roledn, groupdn, userattr Substitution of the attributeName attribute value from the target entry into the subject. Note, if you use any macro, you must define the target that contains the (USDdn) macro. You can combine (USDdn) and (USDattr. attrName ) macros. 2.3. The (USDdn) macro example The (USDdn) macro compares the substitution value to the entry from the LDAP request. For example, the LDAP request targets the entry: cn=all,ou=groups,dc=subdomain1,dc=hostedCompany1,dc=example,dc=com The ACI defines the following target: (target="ldap:///ou=groups,(USDdn),dc=example,dc=com") The (USDdn) macro matches with dc=subdomain1,dc=hostedCompany1 in this example. The substring that matches the target expands the subject when the subject of the ACI uses the (USDdn) macro: 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";) The ACI expands as follow: 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";) After the macro is expanded, Red Hat Directory Server evaluates the ACI following the normal process to determine if access is granted. 2.4. The [USDdn] macro example The [USDdn] macro examines the DN of the targeted source multiple times. This macro drops the leftmost RDN component each iteration until it finds a match. For example, you have an LDAP request with the target at the cn=all,ou=groups,dc=subdomain1,dc=hostedCompany1,dc=example,dc=com subtree and the following ACI: 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";) The macro expands as follows: The (USDdn) in the target matches dc=subdomain1,dc=hostedCompany1 . The replacement for the [USDdn] in the subject is 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 the result does not match, the process continues and drops the leftmost part. The [USDdn] in the subject is dc=hostedCompany1 . The result is groupdn="ldap:///cn=domainAdmins,ou=Groups,dc=hostedCompany1,dc=example,dc=com" . 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 [USDdn] macro grants access to domain-level administrators to all the subdomains in the directory tree. It is useful for expressing a hierarchical relationship between domains. For example, consider the following ACI: 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";) This ACI grants access to the members of the cn=domainAdmins,ou=groups,dc=hostedCompany1,dc=example,dc=com to all of the subdomains under dc=hostedCompany1 . An administrator that is a member of that group can access a subtree like ou=people,dc=subdomain1.1,dc=subdomain1 . But members of cn=domainAdmins,ou=groups,dc=subdomain1.1 do not have an access to the ou=people,dc=hostedCompany1 and ou=people,dc=subdomain1,dc=hostedCompany1 nodes. 2.5. The (USDattr.attrName) macro example You always use the (USDattr. attrName ) macro as a part of a DN. For example, define the following roledn : roledn = "ldap:///cn=DomainAdmins,(USDattr.ou),dc=HostedCompany1,dc=example,dc=com" Assuming, that the server receives an LDAP operation that targets at the following entry: dn: cn=Jane Doe,ou=People,dc=HostedCompany1,dc=example,dc=com cn: Jane Doe sn: Doe ou: Engineering... To evaluate the roledn part of the ACI, the server looks at the ou attribute in the targeted entry and uses the value of this attribute to expand the macro. The roledn expands as follows: roledn = "ldap:///cn=DomainAdmins,ou=Engineering,dc=HostedCompany1,dc=example,dc=com" Red Hat Directory Server evaluates the ACI according to the normal ACI evaluation algorithm. If the attribute has multiple values, RHDS uses each value to expand the macro and uses the value that has a first successful match of the expanded macro. For example: dn: cn=Jane Doe,ou=People,dc=HostedCompany1,dc=example,dc=com cn: Jane Doe sn: Doe ou: Engineering ou: People... When the Red Hat 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"

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";)
cn=all,ou=groups,dc=subdomain1,dc=hostedCompany1,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),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
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 ou: People
roledn = "ldap:///cn=DomainAdmins,ou=Engineering,dc=HostedCompany1,dc=example,dc=com" roledn = "ldap:///cn=DomainAdmins,ou=People,dc=HostedCompany1,dc=example,dc=com"