Linux

在 OpenLDAP 中設置 ACL,以便使用者可以從過濾的子樹中找到自己的條目

  • July 20, 2018

我在基本 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

這是一條可能取自某些預設配置的規則。可以從它開始,但我建議進行一些重構:

  1. 省略屬性shadowLastChange,因為 LDAP 影子是一個錯誤的概念。如果您確實使用影子映射,此 ACL 將允許使用者規避影子密碼到期。
  2. 更改 who 子句的順序。一般來說,遵循規則首先提到“更高”的特權。
  3. 如果 cn=admin,dc=mydomain 已經是該數據庫的rootdn,則不需要該 who 子句。
  4. 更好地授予組密碼管理員權限。
  5. 根本不要通過包含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

這裡的問題:

  1. 由於在 {4} 中,by self write將永遠無法到達。by self read
  2. by * none由於{4}中的隱含,根本無法訪問此 ACL 。
  3. 再次:無需授予對rootdn的訪問權限
  4. 再次:更好地授予對組的管理員訪問權限
  5. 使用更好的 who 子句順序
  6. 重新考慮您是否真的想向使用者本人授予對所有屬性的寫入權限

更好的:

{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,您應該查閱各種線上文件:

引用自:https://serverfault.com/questions/922826