我的服务器上有一个简单的 ACL,运行良好。我决定设置 SSSD 以通过 LDAP 验证用户登录,因此我需要授予对 SSSD 绑定帐户的更多访问权限。在此过程中,我以某种方式阻止了第一个 ACL 之外的所有访问;尽管break
ACL {0} 末尾有语句,但不是根级别用户的每次搜索都会返回错误 32(找不到对象。)
数据库的结构大致如下:
organization: dc=r1,dc=internal
organizationalUnit: ou=users,dc=r1,dc=internal
inetOrgPerson: uid=mike,ou=users,dc=r1,dc=internal
organizationalUnit: ou=groups,dc=r1,dc=internal
groupOfUniqueNames: cn=root,ou=groups,dc=r1,dc=internal
posixGroup: cn=mike,ou=groups,dc=r1,dc=internal
organizationalUnit: ou=system,dc=r1,dc=internal
inetOrgPerson: uid=sssd,ou=system,dc=r1,dc=internal
这是我的 ACL:
version: 1
dn: olcDatabase={2}mdb,cn=config
changetype: modify
replace: olcAccess
# admin users can write anything in this subtree
# also the root SASL user (eg ldapmodify -QY EXTERNAL -H ldapi:/// ...)
# nobody else has access, but continue searching for matches below
olcAccess: {0}to dn.subtree="dc=r1,dc=internal"
by anonymous break
by group/groupOfUniqueNames/uniqueMember="cn=root,ou=groups,dc=r1,dc=internal" write
by dn.base="gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth" write
by * break
# sssd user can read all user/group attributes
# other users keep looking
olcAccess: {1}to dn.onelevel="ou=users,dc=r1,dc=internal"
by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
by * break
olcAccess: {2}to dn.onelevel="ou=groups,dc=r1,dc=internal"
by dn.exact="uid=sssd,ou=system,dc=r1,dc=internal" read
by * break
# you can update your own password
# anonymous users can authenticate against it
# nobody else sees it
olcAccess: {3}to dn.subtree="dc=r1,dc=internal"
attrs=userPassword
by self write
by anonymous auth
by * none
# anonymous users can read select user/group attributes
olcAccess: {4}to dn.onelevel="ou=users,dc=r1,dc=internal"
attrs=entry,cn,uid,sn,givenName,mail,telephoneNumber,mobile,memberOf
by anonymous read
by * break
olcAccess: {5}to dn.onelevel="ou=groups,dc=r1,dc=internal"
attrs=entry,cn,description,uniqueMember,memberUid
by anonymous read
by * break
# all users can update their own records
# and see all other users' attributes
# everyone (including anonymous) can search
olcAccess: {6}to dn.onelevel="ou=users,dc=r1,dc=internal"
by self write
by users read
by * search
这是带有额外 ACL 日志记录的日志提取:
Aug 26 13:04:10 lemongrab slapd[3991]: => access_allowed: search access to "ou=users,dc=r1,dc=internal" "entry" requested
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [1] dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => acl_get: [1] matched
Aug 26 13:04:10 lemongrab slapd[3991]: => acl_get: [1] attr entry
Aug 26 13:04:10 lemongrab slapd[3991]: => acl_mask: access to entry "ou=users,dc=r1,dc=internal", attr "entry" requested
Aug 26 13:04:10 lemongrab slapd[3991]: => acl_mask: to all values by "uid=sssd,ou=system,dc=r1,dc=internal", (=0)
Aug 26 13:04:10 lemongrab slapd[3991]: <= check a_dn_pat: anonymous
Aug 26 13:04:10 lemongrab slapd[3991]: <= check a_dn_pat: cn=admin,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: <= check a_group_pat: cn=root,ou=groups,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => mdb_entry_get: found entry: "cn=root,ou=groups,dc=r1,dc=internal"
Aug 26 13:04:10 lemongrab slapd[3991]: <= check a_dn_pat: gidNumber=0+uidNumber=0,cn=peercred,cn=external,cn=auth
Aug 26 13:04:10 lemongrab slapd[3991]: <= check a_dn_pat: *
Aug 26 13:04:10 lemongrab slapd[3991]: <= acl_mask: [5] applying +0 (break)
Aug 26 13:04:10 lemongrab slapd[3991]: <= acl_mask: [5] mask: =0
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [2] ou=users,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [3] ou=groups,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [4] dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => acl_get: [4] matched
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [5] ou=users,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [6] ou=groups,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: => dn: [7] ou=users,dc=r1,dc=internal
Aug 26 13:04:10 lemongrab slapd[3991]: <= acl_get: done.
Aug 26 13:04:10 lemongrab slapd[3991]: => slap_access_allowed: no more rules
Aug 26 13:04:10 lemongrab slapd[3991]: => access_allowed: no more rules
日志条目证实了我的怀疑,即在第一条规则之后没有做任何事情。例如,为什么它会从规则 1 跳到规则 4?根据我的理解,接下来应该考虑规则 2。
我已经尝试了 ACL 中的onelevel
和范围,效果相同。children
如果我将 ACL 更改为olcAccess: {1}to dn.subtree="dc=r1,dc=internal"
它似乎可以工作,但除了用户和组之外还有其他 OU 我不想授予访问权限。我是否误解了范围的工作原理?
更新我想通了!主要问题是文档很微妙。这是 dnstyle 限定符的描述
slapd.access(5)
:关键点是仅
dn.one
授予对紧随其后的条目的访问权限。如果你写(就像你一样):<dnpattern>
这将失败,因为
dn.onelevel="ou=users,dc=r1,dc=internal"
不授予sssd
用户访问 dnou=users,dc=r1,dc=internal
本身的权限。如果您在发出请求时查看 ACL 日志,您会看到如下内容:您没有授予此访问权限的规则,因此它失败了。我们需要添加授予对 ou 本身的访问权限的 ACL。这意味着替换这样的东西:
有了这个:
(如果您不想读取 ou 本身的属性,可以在第一个 ACL 中替换
read
为。)search
sssd
这是我在测试环境中设置的完整 ACL 集:
这行得通!使用这样的目录结构:
然后运行:
产生:
...这正是我们想要的:
sssd
只能看到一个级别,并且看不到ou=nested
. 如果我们以 组成员的身份执行相同的搜索root
,我们现在可以看到:user3
ou=nested