在 OpenLDAP 中設置 ACL,以便使用者可以從過濾的子樹中找到自己的條目
我在基本 DN 下的 openldap 伺服器中有一個使用者目錄
ou=users,dc=mydomain
。使用者條目是uid=user1,ou=users,dc=mydomain
我目前的 ACL 是:
{5}to * by self write by dn="cn=admin,dc=mydomain" write by * none {4}to dn.subtree="ou=users,dc=mydomain" by self read {3}to dn.exact="dc=mydomain" attrs=entry by users search by * none {2}to dn.base="" by * read {1}to dn.subtree="dc=something,dc=mydomain" by dn="uid=someone,ou=users,dc=mydomain" write by * read {0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=mydomain" write by * none
這些允許使用者查詢並找到他自己的條目。但是,如果經過身份驗證的使用者user1使用過濾器集搜尋基本 DN,
(uid=user1)
則找不到任何條目。換句話說:ldapsearch -H ldap://myserver -b "ou=users,dc=mydomain" -D "uid=user1,ou=users,dc=mydomain" -x -W
什麼都不返回,而ldapsearch -H ldap://myserver -b "uid=user1,ou=users,dc=mydomain" -D "uid=user1,ou=users,dc=mydomain" -x -W
返回user1
.我需要如何調整 ACL,以便使用者可以通過對基本 DN 的過濾搜尋找到他自己的條目(並且只有他自己的)?
定義 OpenLDAP ACL 很棘手。
大多數情況下,ACL 問題是由 ACL 本身的處理順序及其 who-clauses (by …) 引起的,並且 ACL 隱含地以
by * none
停止控制流結束。您正在使用帶有cn=config的動態配置,這在架構中使用 X-ORDERED擴展來保留某些屬性值的順序,例如olcAccess。
因此,處理 ACL 的順序是:
{0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=mydomain" write by * none {1}to dn.subtree="dc=something,dc=mydomain" by dn="uid=someone,ou=users,dc=mydomain" write by * read {2}to dn.base="" by * read {3}to dn.exact="dc=mydomain" attrs=entry by users search by * none {4}to dn.subtree="ou=users,dc=mydomain" by self read {5}to * by self write by dn="cn=admin,dc=mydomain" write by * none
因此,讓我們詳細查看您的 ACL:
{0}to attrs=userPassword,shadowLastChange by self write by anonymous auth by dn="cn=admin,dc=mydomain" write by * none
這是一條可能取自某些預設配置的規則。可以從它開始,但我建議進行一些重構:
- 省略屬性shadowLastChange,因為 LDAP 影子是一個錯誤的概念。如果您確實使用影子映射,此 ACL 將允許使用者規避影子密碼到期。
- 更改 who 子句的順序。一般來說,遵循規則首先提到“更高”的特權。
- 如果 cn=admin,dc=mydomain 已經是該數據庫的rootdn,則不需要該 who 子句。
- 更好地授予組密碼管理員權限。
- 根本不要通過包含
write
訪問授予讀取權限,=w
而是使用只寫權限。更好的使用:
{0}to attrs=userPassword by group="cn=admins,ou=groups,dc=mydomain" =w by self =w by anonymous auth by * none
{1}to dn.subtree="dc=something,dc=mydomain" by dn="uid=someone,ou=users,dc=mydomain" write by * read
如果
dc=mydomain
您的數據庫後綴是這個 ACL 在您的問題的上下文中對我沒有多大意義。也許是一些測試的遺留物?
{2}to dn.base="" by * read
如果放置在您的數據庫配置條目中,這將無效。這必須添加到前端配置條目cn=config (以前在任何數據庫部分之前的靜態配置 slapd.conf中)。
{3}to dn.exact="dc=mydomain" attrs=entry by users search by * none
我會在 ACL 列表的末尾放置一個這樣的 ACL,這樣它就不會在此時停止對條目的訪問。如果您想使用ou=users,dc=mydomain之類的任意搜尋庫,則必須將此搜尋權限授予整個子樹。
因此,將其放在 ACL 的末尾並刪除 {3} 或…
{6}to dn.subtree="dc=mydomain" attrs=entry by users search by * none
…移動這條規則:
{4}to dn.subtree="ou=users,dc=mydomain" by self read
應該是最後一個 ACL 並替換 {3}。請參閱 {5} 的評論。
{5}to * by self write by dn="cn=admin,dc=mydomain" write by * none
這裡的問題:
- 由於在 {4} 中,
by self write
將永遠無法到達。by self read
by * none
由於{4}中的隱含,根本無法訪問此 ACL 。- 再次:無需授予對rootdn的訪問權限
- 再次:更好地授予對組的管理員訪問權限
- 使用更好的 who 子句順序
- 重新考慮您是否真的想向使用者本人授予對所有屬性的寫入權限
更好的:
{5}to * by group="cn=admins,ou=groups,dc=mydomain" write by self write by * none
最重要的調試選項之一是啟動slapd並記錄其 ACL 處理:
/usr/sbin/slapd … -d config,stats,stats2,acl
因此,這些提示應該讓您開始使用 ACL 自己解決問題。總是三思而後行。在我看來,您的規則中有一些相互矛盾的假設。
但顯然沒有辦法深入研究文件:
如果您想詳細了解 ACL,您應該查閱各種線上文件: