(1)、控制对什么的访问(What to control access to)<what>
<what>决定了将要应用访问控制的条目和属性。条目通常通过两种方式选定:通过DN或者通过过滤器。下面的示例通过DN选择条目:
to *
to dn[.<basic-style>]=<regex>
to dn.<scope-style>=<DN>
第一种格式用于选择所有的条目。第二种格式用于选择标准化的DN与所给正则表达式相匹配的条目(第二种格式不会在本文档中深入讨论)。第三种格式用语选择在所请求的DN范围之内的条目。<DN>是一个标识名的字符串表示,如RFC2253中所述。
DN范围可以是以下四种之一:base, one, subtree, 或者 children。这里的base只与所给的DN相匹配,one只与父条目是所给DN的条目相匹配,subtree只与根为所给DN的子树下是所有条目相 匹配,而children匹配所有位于DN之下的条目(除了以DN为标识名的条目以外)。
比如,如果目录包含以如下方式命名的条目:
0: o=suffix
1: cn=Manager,o=suffix
2: ou=people,o=suffix
3: uid=kdz,ou=people,o=suffix
4: cn=addresses,uid=kdz,ou=people,o=suffix
5: uid=hyc,ou=people,o=suffix
那么:
dn.base="ou=people,o=suffix" 匹配 2;
dn.one="ou=people,o=suffix" 匹配 3, 和 5;
dn.subtree="ou=people,o=suffix" 匹配 2, 3, 4, 和 5;
dn.children="ou=people,o=suffix" 匹配 3, 4, 和 5。
条目也可以通过过滤器收集起来:
to filter=<ldap filter>
这里的<ldap filter>是LDAP搜索过滤器的一个字符串表示,如RFC2254所述。比如:
to filter=(objectClass=person)
注意到条目可以同时通过DN和过滤器来搜集,只需要同时把两者都包含在<what>子句中即可:
to dn.one="ou=people,o=suffix" filter=(objectClass=person)
条目的属性通过在<what>搜集器中包含用逗号分隔的属性名列表指定:
attrs=<attribute list>
一个属性的具体取值通过单个的属性名和值选取器来指定:
attrs=<attribute> val[.<style>]=<regex>
有两个特殊的的伪属性entry 和 children。要读取(也就是得到)一个条目,必须要有对目标条目的entry属性的读权限。要添加或者删除一个条目,必须要有对目标条目的 entry属性的写权限,并且还必须要有对条目的父条目的children属性的写权限。要重命名一个条目,必须要同时拥有对目标条目的entry属性的 写权限,对原父条目的children属性的写权限,以及对新的父条目的children属性的写权限。本节末尾的完全示例将会把所有这一切将清楚的。
最后要说明一点,选取器“*”是一个特殊的条目选取器,用来选取所有的条目。在没有其他的<what>选取器给出的情况下它将被使用。等价于"dn=.*"。
(2)、赋予Who访问权限(Who to grant access to)<who>
部分指明了被赋予访问权限的身份。注意,权限被赋予“身份”(实体:entities)而不是“条目”(entries)。下表说明了身份说明选项:
---Specifier--- ---Entities---
* All, including anonymous and authenticated users
anonymous Anonymous (non-authenticated) users
users Authenticated users
self User associated with target entry
dn[.<basic-style>]=<regex> Users matching a regular expression
dn.<scope-style>=<DN> Users within scope of a DN
DN说明选项使用一个正则表达式来匹配当前身份的“规范”DN。
其他的控制因素也被支持。比如,a <who> can be restricted by an entry listed in a DN-valued attribute in the entry to which the access applies:
dnattr=<dn-valued attribute name>
dnattr用来授权给一个条目,而该条目的DN是在所列的条目的属性当中(比如,可以给一个条目组的拥有者所在的条目授权)。
系统还支持其他的控制方式。比如可以通过一个匹配限制客户端的域名:
domain=
一些因素可能不是在所有的环境下都是正确的。比如,域名因素依赖于域名查询。因为这些很容易spoofed,所以域名因素不可避免。
(3)、赋予的access权限(The access to grant)<access>
可以赋予的的类型可以是如下几种:
---Level--- ---Privileges--- ---Description---
none =0 no access
auth =x needed to bind
compare =cx needed to compare
search =scx needed to apply search filters
read =rscx needed to read search results
write =wrscx needed to modify/rename
每一个级别隐含了更低的级别。因此,给予某人写一个条目的权限同时给了他读,搜索,比较和认证的权限。但是,也可以使用权限说明来赋予特定的权限。
(4)、访问控制评估(Access Control Evaluation)
在评估某个请求者是否具有对一个条目和/或属性的访问权限时,slapd将条目和/或属性与配置文件中的<what>选取器进行比较。对每一 个条目,数据库级的访问控制首先生效,跟着生效的是全局访问控制指令。按照这样的先后顺序,访问控制指令以它们在配置文件中出现的先后次序被检查。 slapd在碰到第一个匹配条目和/或属性的<what>选取器时终止。对应的访问控制指令就是slapd将要用来评估访问控制权限的。
接下来,slapd把提出访问的实体与访问控制指令中的<who>选取器依次比较。当它遇到第一个匹配请求实体的<who>选取器是它将停止。这也就决定了实体能够拥有的对条目和/或属性的访问权限。
最后,slapd将访问控制指令中的<access>与客户的请求权限相比较。如果它允许大于或等于的访问权限,访问就被批准。否则,访问将被拒绝。
访 问控制指令的评估顺序使它们在配置文件中的位置变得很重要。如果一个访问控制指令就它所选的条目而言比另一个更具体,那么它应当出现在配置文件的前面。类 似地,如果一个<who>选取器比另一个更具体,它也应该在配置文件的前面出现。下面给出的访问控制示例将会使这一切变得更清晰。
存取控制示例:
上面描述的存取控制应用是非常强大的。下面的部分显示了它们的一些实用示例。首先,几个简单的例子:
eg1: access to * by * read
这个存取控制指令将读权限赋予每一个人。
eg2:
access to * ( "to *"指的是<what>即控制对什么的访问 )
by self write ( "self"指的是<who>即赋予谁访问权限 ; "write"指的是<access>即赋予什么权限 )
by anonymous auth
by * read
该指令允许用户修改自己的条目,允许认证,并且允许所有其他人读取。注意,只有第一个by 语句匹配应用。因此,匿名用户被赋予认证权限,而非读取权限。因此,最后一个语句和“by users read”效果相同(因为上一条已经将匿名用户验证为users,之后不会再有匿名用户了)。
eg3:
经常需要对不同的保护级别执行不同的受限操作。以下显示了security strength factors (SSF)可以怎样被使用:
access to *
by ssf=128 self write
by ssf=64 anonymous auth
by ssf=64 users read
这条指令允许用户修改他们自己的条目,如果安全保护强度为128或者更高的话;允许匿名用户拥有auth权限,一般用户拥有读权限,如果确定了级别为64 或者更高的安全保护强度的话。如果客户没有确定足够的安全保护强度的话,暗含的by * none字据将会起作用。
eg4:
下面的例子显示了通过style specifiers 在两个访问指令中通过DN选择条目的用法,其中,访问指令的顺序是很重要的。
access to dn.children="dc=example,dc=com"
by * search
access to dn.children="dc=com"
by * read
所有用户都拥有对dc=com 子树下的条目的读权限,例外的是,对那些dc=example,dc=com 子树下的条目,用户仅仅有搜索的权限。dc=com 是不可访问的,因为没有访问指令匹配该条DN。如果这里的指令顺序颠倒了的话,那么尾部的指令将永远不会被用到,因为所有 dc=example,dc=com 下的条目也都是dc=com 下的条目。
(可以理解为:下一个"access to"是除去上一个里的内容的,上面的范围要更精确)
同时要注意到如果没有与指令相匹配的访问权限或者没有by <who>子句的话,访问将被拒绝。也就是说,每一个access to 指令都是以一个暗含的by * none 子句结尾的,并且每一个访问列表都以一个暗含的access to * by * none指令结尾。
eg5:
下面的示例再一次说明了对access指令和by <who>子句而言出现顺序的重要性。它也显示了属性选取器和各种<who>选取器的用法。
access to dn.subtree="dc=example,dc=com" attr=homePhone
by self write
by dn.children="dc=example,dc=com" search
by peername=IP:10\..+ read
access to dn.subtree="dc=example,dc=com"
by self write
by dn.children="dc=example,dc=com" search
by anonymous auth
本例对"dc=example,dc=com"子树中的条目起作用。除了homePhone之外,一个条目可以写它所有的属性,example.com 下的条目可以被它自己搜索,其他任何人都没有权限访问(暗含by * none),例外是经过认证/授权的用户可以(总是匿名进行)。homePhone属性对条目自身而言是可写的,对example.com下的条目是可搜 索的,对来自10网络的客户总是可读的,否则就是不可读的(暗含by * none)。所有其他的访问都将被拒绝,因为暗含有access to * by * none子句。
eg6:
有时,允许一个特定的DN来从一个属性中增加或者删除自己是很有用的。比如,如果您想创建一个组,并且允许人们向该组的member属性中增加或者删除自己的DN,应该使用如下的存取控制指令来完成这一点:
access to attr=member,entry
by dnattr=member selfwrite
这个dnattr说明的选择器说明,该存取控制应用于member属性中列出的条目。selfwrite存取控制选择器说明那些成员只能从属性中增加或者 删除自己,而不能增加或者删除其他值。附加的“entry”是必须的,因为要访问该条目的属性,能够访问该条目是必须的。
<what>决定了将要应用访问控制的条目和属性。条目通常通过两种方式选定:通过DN或者通过过滤器。下面的示例通过DN选择条目:
to *
to dn[.<basic-style>]=<regex>
to dn.<scope-style>=<DN>
第一种格式用于选择所有的条目。第二种格式用于选择标准化的DN与所给正则表达式相匹配的条目(第二种格式不会在本文档中深入讨论)。第三种格式用语选择在所请求的DN范围之内的条目。<DN>是一个标识名的字符串表示,如RFC2253中所述。
DN范围可以是以下四种之一:base, one, subtree, 或者 children。这里的base只与所给的DN相匹配,one只与父条目是所给DN的条目相匹配,subtree只与根为所给DN的子树下是所有条目相 匹配,而children匹配所有位于DN之下的条目(除了以DN为标识名的条目以外)。
比如,如果目录包含以如下方式命名的条目:
0: o=suffix
1: cn=Manager,o=suffix
2: ou=people,o=suffix
3: uid=kdz,ou=people,o=suffix
4: cn=addresses,uid=kdz,ou=people,o=suffix
5: uid=hyc,ou=people,o=suffix
那么:
dn.base="ou=people,o=suffix" 匹配 2;
dn.one="ou=people,o=suffix" 匹配 3, 和 5;
dn.subtree="ou=people,o=suffix" 匹配 2, 3, 4, 和 5;
dn.children="ou=people,o=suffix" 匹配 3, 4, 和 5。
条目也可以通过过滤器收集起来:
to filter=<ldap filter>
这里的<ldap filter>是LDAP搜索过滤器的一个字符串表示,如RFC2254所述。比如:
to filter=(objectClass=person)
注意到条目可以同时通过DN和过滤器来搜集,只需要同时把两者都包含在<what>子句中即可:
to dn.one="ou=people,o=suffix" filter=(objectClass=person)
条目的属性通过在<what>搜集器中包含用逗号分隔的属性名列表指定:
attrs=<attribute list>
一个属性的具体取值通过单个的属性名和值选取器来指定:
attrs=<attribute> val[.<style>]=<regex>
有两个特殊的的伪属性entry 和 children。要读取(也就是得到)一个条目,必须要有对目标条目的entry属性的读权限。要添加或者删除一个条目,必须要有对目标条目的 entry属性的写权限,并且还必须要有对条目的父条目的children属性的写权限。要重命名一个条目,必须要同时拥有对目标条目的entry属性的 写权限,对原父条目的children属性的写权限,以及对新的父条目的children属性的写权限。本节末尾的完全示例将会把所有这一切将清楚的。
最后要说明一点,选取器“*”是一个特殊的条目选取器,用来选取所有的条目。在没有其他的<what>选取器给出的情况下它将被使用。等价于"dn=.*"。
(2)、赋予Who访问权限(Who to grant access to)<who>
部分指明了被赋予访问权限的身份。注意,权限被赋予“身份”(实体:entities)而不是“条目”(entries)。下表说明了身份说明选项:
---Specifier--- ---Entities---
* All, including anonymous and authenticated users
anonymous Anonymous (non-authenticated) users
users Authenticated users
self User associated with target entry
dn[.<basic-style>]=<regex> Users matching a regular expression
dn.<scope-style>=<DN> Users within scope of a DN
DN说明选项使用一个正则表达式来匹配当前身份的“规范”DN。
其他的控制因素也被支持。比如,a <who> can be restricted by an entry listed in a DN-valued attribute in the entry to which the access applies:
dnattr=<dn-valued attribute name>
dnattr用来授权给一个条目,而该条目的DN是在所列的条目的属性当中(比如,可以给一个条目组的拥有者所在的条目授权)。
系统还支持其他的控制方式。比如可以通过一个匹配限制客户端的域名:
domain=
一些因素可能不是在所有的环境下都是正确的。比如,域名因素依赖于域名查询。因为这些很容易spoofed,所以域名因素不可避免。
(3)、赋予的access权限(The access to grant)<access>
可以赋予的的类型可以是如下几种:
---Level--- ---Privileges--- ---Description---
none =0 no access
auth =x needed to bind
compare =cx needed to compare
search =scx needed to apply search filters
read =rscx needed to read search results
write =wrscx needed to modify/rename
每一个级别隐含了更低的级别。因此,给予某人写一个条目的权限同时给了他读,搜索,比较和认证的权限。但是,也可以使用权限说明来赋予特定的权限。
(4)、访问控制评估(Access Control Evaluation)
在评估某个请求者是否具有对一个条目和/或属性的访问权限时,slapd将条目和/或属性与配置文件中的<what>选取器进行比较。对每一 个条目,数据库级的访问控制首先生效,跟着生效的是全局访问控制指令。按照这样的先后顺序,访问控制指令以它们在配置文件中出现的先后次序被检查。 slapd在碰到第一个匹配条目和/或属性的<what>选取器时终止。对应的访问控制指令就是slapd将要用来评估访问控制权限的。
接下来,slapd把提出访问的实体与访问控制指令中的<who>选取器依次比较。当它遇到第一个匹配请求实体的<who>选取器是它将停止。这也就决定了实体能够拥有的对条目和/或属性的访问权限。
最后,slapd将访问控制指令中的<access>与客户的请求权限相比较。如果它允许大于或等于的访问权限,访问就被批准。否则,访问将被拒绝。
访 问控制指令的评估顺序使它们在配置文件中的位置变得很重要。如果一个访问控制指令就它所选的条目而言比另一个更具体,那么它应当出现在配置文件的前面。类 似地,如果一个<who>选取器比另一个更具体,它也应该在配置文件的前面出现。下面给出的访问控制示例将会使这一切变得更清晰。
存取控制示例:
上面描述的存取控制应用是非常强大的。下面的部分显示了它们的一些实用示例。首先,几个简单的例子:
eg1: access to * by * read
这个存取控制指令将读权限赋予每一个人。
eg2:
access to * ( "to *"指的是<what>即控制对什么的访问 )
by self write ( "self"指的是<who>即赋予谁访问权限 ; "write"指的是<access>即赋予什么权限 )
by anonymous auth
by * read
该指令允许用户修改自己的条目,允许认证,并且允许所有其他人读取。注意,只有第一个by 语句匹配应用。因此,匿名用户被赋予认证权限,而非读取权限。因此,最后一个语句和“by users read”效果相同(因为上一条已经将匿名用户验证为users,之后不会再有匿名用户了)。
eg3:
经常需要对不同的保护级别执行不同的受限操作。以下显示了security strength factors (SSF)可以怎样被使用:
access to *
by ssf=128 self write
by ssf=64 anonymous auth
by ssf=64 users read
这条指令允许用户修改他们自己的条目,如果安全保护强度为128或者更高的话;允许匿名用户拥有auth权限,一般用户拥有读权限,如果确定了级别为64 或者更高的安全保护强度的话。如果客户没有确定足够的安全保护强度的话,暗含的by * none字据将会起作用。
eg4:
下面的例子显示了通过style specifiers 在两个访问指令中通过DN选择条目的用法,其中,访问指令的顺序是很重要的。
access to dn.children="dc=example,dc=com"
by * search
access to dn.children="dc=com"
by * read
所有用户都拥有对dc=com 子树下的条目的读权限,例外的是,对那些dc=example,dc=com 子树下的条目,用户仅仅有搜索的权限。dc=com 是不可访问的,因为没有访问指令匹配该条DN。如果这里的指令顺序颠倒了的话,那么尾部的指令将永远不会被用到,因为所有 dc=example,dc=com 下的条目也都是dc=com 下的条目。
(可以理解为:下一个"access to"是除去上一个里的内容的,上面的范围要更精确)
同时要注意到如果没有与指令相匹配的访问权限或者没有by <who>子句的话,访问将被拒绝。也就是说,每一个access to 指令都是以一个暗含的by * none 子句结尾的,并且每一个访问列表都以一个暗含的access to * by * none指令结尾。
eg5:
下面的示例再一次说明了对access指令和by <who>子句而言出现顺序的重要性。它也显示了属性选取器和各种<who>选取器的用法。
access to dn.subtree="dc=example,dc=com" attr=homePhone
by self write
by dn.children="dc=example,dc=com" search
by peername=IP:10\..+ read
access to dn.subtree="dc=example,dc=com"
by self write
by dn.children="dc=example,dc=com" search
by anonymous auth
本例对"dc=example,dc=com"子树中的条目起作用。除了homePhone之外,一个条目可以写它所有的属性,example.com 下的条目可以被它自己搜索,其他任何人都没有权限访问(暗含by * none),例外是经过认证/授权的用户可以(总是匿名进行)。homePhone属性对条目自身而言是可写的,对example.com下的条目是可搜 索的,对来自10网络的客户总是可读的,否则就是不可读的(暗含by * none)。所有其他的访问都将被拒绝,因为暗含有access to * by * none子句。
eg6:
有时,允许一个特定的DN来从一个属性中增加或者删除自己是很有用的。比如,如果您想创建一个组,并且允许人们向该组的member属性中增加或者删除自己的DN,应该使用如下的存取控制指令来完成这一点:
access to attr=member,entry
by dnattr=member selfwrite
这个dnattr说明的选择器说明,该存取控制应用于member属性中列出的条目。selfwrite存取控制选择器说明那些成员只能从属性中增加或者 删除自己,而不能增加或者删除其他值。附加的“entry”是必须的,因为要访问该条目的属性,能够访问该条目是必须的。