18.14. 高级访问控制:使用 Macro ACI
宏 ACI 提高了灵活性。例如,您可以添加子树,并自动获得与其它子树相同的定制的访问控制,而无需添加任何 ACI。作为副作用,ACI 的数量会较小,但 Macro ACI 处理比普通的 ACI 更昂贵。
宏是用于在 ACI 中代表 DN 或 DN 的部分占位符。您可以使用宏在 ACI 的目标部分或绑定规则部分(或两者)中代表 DN。在实践中,当目录服务器获得传入的 LDAP 操作时,ACI 宏与 LDAP 操作目标的资源匹配。如果存在匹配项,则宏将被目标资源的 DN 的值替代。然后,目录服务器会正常评估 ACI。
18.14.1. 宏 ACI 示例 复制链接链接已复制到粘贴板!
复制链接链接已复制到粘贴板!
图 18.1 “Macro ACI 的目录树示例” 显示目录树,它使用宏 ACI 有效地减少 ACI 的整体数量。本图使用具有相同树结构的子域的重复模式(ou=groups、ou=people)。此模式也跨树重复,因为 Example Corp. 目录树存储后缀 dc=hostedCompany2,dc=example,dc=com 和 dc=hostedCompany3,dc=example,dc=com。
在目录树中应用的 ACI 也具有重复的模式。例如,以下 ACI 位于 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=hostedCompany1,dc=example,dc=com";)
此 ACI 向 DomainAdmins 组授予 dc=hostedCompany1,dc=example,dc=com 树中的任何条目的读和搜索权限。
图 18.1. Macro ACI 的目录树示例
以下 ACI 位于 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=hostedCompany1,dc=example,dc=com";)
以下 ACI 位于 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=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=subdomain1,dc=hostedCompany1,dc=example,dc=com";)
以下 ACI 位于 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=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=hostedCompany2,dc=example,dc=com";)
以下 ACI 位于 dc=subdomain1,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: (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 中,唯一的区别是 groupdn 关键字中指定的 DN。通过对 DN 使用宏,可以在 dc=example,dc=com 节点上用单个 ACI 替换这些 ACI。这个 ACI 读取如下:
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";)
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";)
之前没有使用的 target 关键字在新的 ACI 中使用。
在本例中,ACI 的数量从四个减少到一。实际优势是您关闭和跨目录树中的重复模式因素。
18.14.2. 宏 ACI 语法 复制链接链接已复制到粘贴板!
复制链接链接已复制到粘贴板!
宏 ACI 包括以下类型的表达式来替换 DN 或 DN 的一部分:
- ($DN)
- [$dn]
- ($attr.attrName),其中 attrName 代表目标条目中包含的属性
在本节中,用来提供绑定凭证的 ACI 关键字(如 userdn、roledn、groupdn 和 userattr )都被称为 主题,而不是 ACI 的目标。宏 ACI 可以在目标部分或 ACI 的主题部分使用。
表 18.5 “ACI Keywords 中的宏” 显示 ACI 的哪些部分可以使用 DN 宏:
Macro | ACI 关键字 |
---|---|
($DN) | target, targetfilter, userdn, roledn, groupdn, userattr |
[$dn] | targetfilter, userdn, roledn, groupdn, userattr |
($attr.attrName) | userDN, roledn, groupdn, userattr |
有以下限制:
- 如果您在 targetfilter, userdn, roledn, groupdn, userattr 中使用 ($dn),则必须定义一个包括 ($dn) 的目标。
- 如果您在 targetfilter, userdn, roledn, groupdn, userattr 中使用 [$dn],则必须定义一个包括 ($dn) 的目标。
注意
使用任何宏时,您 总是 需要一个包含 ($dn) 宏的目标定义。
您可以组合 ($dn) 宏和 ($attr.attrName) 宏。
18.14.2.1. 宏匹配($dn) 复制链接链接已复制到粘贴板!
复制链接链接已复制到粘贴板!
($dn) 宏被 LDAP 请求目标的资源的匹配部分替代。例如,您有一个针对 cn=all,ou=groups,dc=subdomain1,dc=hostedCompany1,dc=example,dc=com 条目的 LDAP 请求,以及定义目标的 ACI:
(target="ldap:///ou=Groups,($dn),dc=example,dc=com")
(target="ldap:///ou=Groups,($dn),dc=example,dc=com")
($dn) 宏与 dc=subdomain1,dc=hostedCompany1 匹配。
当 ACI 主题也使用 ($dn) 时,与目标匹配的子字符串用于扩展主题。例如:
aci: (target="ldap:///ou=*,($dn),dc=example,dc=com") (targetattr = "*") (version 3.0; acl "Domain access"; allow (read,search) groupdn="ldap:///cn=DomainAdmins,ou=Groups,($dn),dc=example,dc=com";)
aci: (target="ldap:///ou=*,($dn),dc=example,dc=com")
(targetattr = "*") (version 3.0; acl "Domain access"; allow (read,search)
groupdn="ldap:///cn=DomainAdmins,ou=Groups,($dn),dc=example,dc=com";)
在这种情况下,如果目标中的字符串匹配 ($dn) 为 dc=subdomain1,dc=hostedCompany1,则主题中会使用相同的字符串。然后,ACI 会按如下方式扩展:
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,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";)
扩展宏后,Directory 服务器会根据正常进程评估 ACI,以确定是否授予访问权限。
18.14.2.2. 宏匹配 [$dn] 复制链接链接已复制到粘贴板!
复制链接链接已复制到粘贴板!
[$dn] 的匹配机制与 for ($dn) 稍有不同。目标资源的 DN 会多次检查,每次丢弃了最左边的 RDN 组件,直到找到匹配项为止。
例如,您有以 cn=all,ou=groups,dc=subdomain1,dc=hostedCompany1,dc=example,dc=com 子树为目标的 LDAP 请求,以及以下 ACI:
aci: (target="ldap:///ou=Groups,($dn),dc=example,dc=com") (targetattr = "*") (version 3.0; acl "Domain access"; allow (read,search) groupdn="ldap:///cn=DomainAdmins,ou=Groups,[$dn],dc=example,dc=com";)
aci: (target="ldap:///ou=Groups,($dn),dc=example,dc=com")
(targetattr = "*") (version 3.0; acl "Domain access"; allow (read,search)
groupdn="ldap:///cn=DomainAdmins,ou=Groups,[$dn],dc=example,dc=com";)
扩展此 ACI 的步骤如下:
- ($DN) 匹配 dc=subdomain1,dc=hostedCompany1。
- 主题中的 [$DN] 替换为 dc=subdomain1,dc=hostedCompany1。结果为 groupdn="ldap:///cn=DomainAdmins,ou=Groups,dc=subdomain1,dc=hostedCompany1,dc=example,dc=com"。如果绑定 DN 是该组的成员,则匹配的进程将停止,并且评估 ACI。如果不匹配,该过程将继续。
- 主题中的 [$DN] 替换为 dc=hostedCompany1。结果为 groupdn="ldap:///cn=DomainAdmins,ou=Groups,dc=hostedCompany1,dc=example,dc=com"。在这种情况下,如果绑定 DN 不是该组的成员,则不会评估 ACI。如果是一个成员,则评估 ACI。
[$dn] 宏的优点是,它提供了为目录树中的所有子域授予域级别管理员访问权限的灵活方式。因此,表示域之间的分层关系非常有用。
例如,请考虑以下 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";)
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";)
它为 dc=hostedCompany1 下的所有子域授予了访问 cn=DomainAdmins,ou=Groups,dc=hostedCompany1,dc=example,dc=com 成员的权限,因此属于那个组的管理员可以访问如 ou=people,dc=subdomain1.1,dc=subdomain1 的子树。
但是,同时,cn=DomainAdmins,ou=Groups,dc=subdomain1.1 的成员将被拒绝访问 ou=body,dc=hostedCompany1 和 ou=body,dc=subdomain1,dc=hostedCompany1 节点。
18.14.2.3. 宏匹配($attr.attrName) 复制链接链接已复制到粘贴板!
复制链接链接已复制到粘贴板!
DN 的主题部分始终使用 ($attr.attrName) 宏。例如,定义以下 roledn :
roledn = "ldap:///cn=DomainAdmins,($attr.ou)"
roledn = "ldap:///cn=DomainAdmins,($attr.ou)"
现在,假设服务器收到在以下条目的目标 LDAP 操作:
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 ...
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
...
为了评估 ACI 的 roledn 部分,服务器将查看目标条目中存储的
ou
属性,并使用此属性的值来扩展宏。因此,在示例中,roledn 被扩展如下:
roledn = "ldap:///cn=DomainAdmins,ou=Engineering,dc=HostedCompany1,dc=example,dc=com"
roledn = "ldap:///cn=DomainAdmins,ou=Engineering,dc=HostedCompany1,dc=example,dc=com"
然后目录服务器会根据普通的 ACI 评估算法评估 ACI。
当属性被多值时,每个值都会被用来扩展宏,第一个提供成功匹配项的值。例如:
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...
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...
在这种情况下,当 Directory 服务器评估 ACI 时,它会在以下扩展表达式上执行逻辑 OR :
roledn = "ldap:///cn=DomainAdmins,ou=Engineering,dc=HostedCompany1,dc=example,dc=com" roledn = "ldap:///cn=DomainAdmins,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"