我們在LDAP中創建目錄樹后,最感興趣的就是如何控制用戶在目錄樹中的權限(讀寫)。誰在什么條件下有記錄權限,我們有權限看到哪些信息。ACL(Access Control List)訪問控制列表就是解決用戶權限問題的。
1、我們要把ACL寫在哪里?
ACL寫在OpenLDAP的服務端全局配置文件slapd.conf中,如下這段即為其指令:
access to dn.base="" by * read
access to dn.base="cn=Subschema" by * read
access to *
by self write
by users read
by anonymous auth
也可以寫在一個單獨的文件中,如access.conf,然后在全局配置文件slapd.conf中
調用,在配置文件中引入這個文件即可,如下:
include /etc/openldap/access.conf
include后面的路徑為該文件的放置地址。
2、ACL語法基礎
怎么看懂ACL指令?
首先看下ACL訪問指令的格式:
access to [resources]
by [who] [type of access granted] [control]
by [who] [type of access granted] [control]
# More 'by' clauses, if necessary....
指令中包含1個to語句,多個by語句。
這個指令的大體意思是:
通過access to約束我們訪問的范圍(resources),
通過by設定哪個用戶(who)獲取對這個約束范圍有什么權限(type of access granted),
並控制(control)這個by語句完成后是否繼續執行下一個by語句或者下一個ACL指令。
如果對ACL指令很熟悉的話,可以不必繼續往下看,因為以下為詳細的指令基礎介紹。
現在對ACL指令分解成兩大部分進行詳細說明,一個是access to指令,一個是by指令。
先看看access to吧。
以上內容意思是:
dn.base:約束這個特定DN的訪問。他和dn.exact和dn.baselevel是相同的意思。
dn.one:約束這個特定的DN第一級子樹的訪問。dn.onelevel是同義詞。
dn.children:這個和dn.subtree類似,都是對其以下的子樹訪問權的約束。不同點在於,
這個的約束是不包含自己本身DN。而subtree包含了本身的DN。
對於dn的約束條件還可以利用模糊約束,如下:
access to dn.regex="uid=[^,]+,ou=Users,dc=example,dc=com"
by * none
dn.regex是用來做匹配(match)用的。
這個指令將約束所有uid=(任何值),ou=Users,dc=example,dc=com的DN,其中的任何值是用[^,]+這個符號組合來表示的,他可以代表任何至少有1個字符,且字符當中沒有逗號(,)的值。
更明確點說,意思就是在ou=Users,dc=example,dc=com這個DN下的所有以uid為屬性的一級子樹都屬於這個約束的范圍。
3、通過約束attrs訪問
對於DN的約束大多用在對某個層級的約束,而用attrs的話,就可以跨層級(或者說跨越父類樹),通過屬性來約束訪問的范圍。
access to attrs=homePhone by * none
這個例子意思是,任何人都沒有權限訪問屬性為homePhone的信息。
在attrs后面的值可以多個,如
access to attrs=homePhone,homePostalAddress
如果想約束某個對象類(Object class)的所有屬性,我們或許可以有這樣的形式:
access to attrs = title, registeredAddress, destinationIndicator,……
但這個方法太耗時,也難以閱讀,顯得笨重,以下給出一個好的方法:
access to attrs=@organizationalPerson by * none
用@的方法必須謹慎,這段指令不僅僅約束了organizationalPerson里的屬性,也約束
了person對象類的屬性。為什么?因為organizationalPerson對象類是person的子類,
因此,所有person中的屬性就當然也是organizationalPerson的屬性了。
如果想做除了organizationalPerson的其他對象類的約束,可以用!來表示:
access to attrs=!organizationalPerson
也可以加入屬性的值,具體約束某個值:
access to attrs=givenName val="Matt"
這個指令也可以用模糊約束的方法,如下:
access to attrs=givenName val.regex="M.*"
最后給個一般情況下用到的利用屬性約束的例子:
access to attrs=member val.children="ou=Users,dc=example,dc=com"
by * none
4、通過Filters訪問
Filters提供一種支持條目記錄匹配的方法,如下:
access to filter="(objectClass=simpleSecurityObject)" by * none
這表示我們可以約束所有記錄中包含對象類為simpleSecurityObject的信息。
與編程語言類似, ACL指令也有類似與或的條件判斷,如下:
access to filter="(|(|(givenName=Matt)(givenName=Barbara))(sn=Kant))"
by * none
這段代碼過濾出givenName為Matt或者Barbara,或者surname為Kant的信息。
Access to [resources]
resources可以有多種形式,如DN,attrs, Filters.
以下即詳細說明。
5、通過約束DN進行訪問
如下所示
access to dn="uid=matt,ou=Users,dc=example,dc=com"
by * none
這個指令是指訪問uid=matt,ou=Users,dc=example,dc=com這個DN,即把訪問的
范圍約束在這個DN中。
by * none是指對於任何人的訪問都是拒絕的。
總體的意思就是,任何人都沒有權限訪問uid=matt,ou=Users,dc=example,dc=com這個DN,當然,服務器管理員是可以訪問的,不然它無法維護這個OpenLDAP中的用戶信息。
再來看一個
access to dn.subtree="ou=Users,dc=example,dc=com"
by * none
在這個例子中,我們用了dn.subtree。在我們的目錄信息樹中,在ou=Users子樹下可能有多個用戶。舉例來說,DN為uid=matt,ou=Users,dc=example,dc=com就是ou=Users, dc=example,dc=com的子樹,當要試圖訪問他時,這個ACL指令就起了作用。
總體的意思是,任何人都沒有權限訪問ou=Users,dc=example,dc=com以及其子樹的信息。
6、此處插播1個知識點
dn.base:Restrict access to this particular DN. This is the default, and dn.exactand dn.baselevel are synonyms of dn.base.
dn.one: Restrict access to any entries immediately below this DN. dn.onelevelis a synonym.
dn.children:Restrict access to the children (subordinate) entries of this DN. This is similar to subtree, except that the given DN itself is not restricted by the rule.