14.7. 使用指定控制进行搜索

目录服务器在其 DSE 的 supportedControls 属性中定义了控制。其中一些定义了复制等服务器操作;其他允许扩展操作,如获得有效权限或解引用控制哪些客户端可以通过 LDAP 操作传递给服务器。
这些控件可以通过 -E 选项指定,方法是提供控制 OID、其 ldapsearch 的关键程度以及控制操作所需的信息。
-E '[!]control_OID:control_information'
有些控制(如服务器端和简单页面的结果)有一个别名,可用于将控制权传递给搜索操作。使用控制别名时,结果将被格式化,因为客户端可识别控制。

14.7.1. 检索受影响的用户右边

使用控制 OID 传递 get valid-rights 搜索控制。例如:
# ldapsearch -D "cn=Directory Manager" -W -p 389 -h server.example.com -b "dc=example,dc=com" -s sub -x -E '!1.3.6.1.4.1.42.2.27.9.5.2=:dn:uid=jsmith,ou=people,dc=example,dc=com' "(objectclass=*)"
重要
当使用 OID 传递控制时,搜索的结果不会被格式化。
访问控制一章中更详细地介绍了有效的权利搜索 第 18.12 节 “检查条目上的访问权限(受影响的右边)”

14.7.2. 使用服务器端排序

服务器端排序是作为其他控制操作执行的,使用 -E 标志和 sss 控制别名。操作的结构设置属性,用于对结果进行排序,以及可选的排序顺序和排序规则。
-E sss=[-]attribute_name:[ordering_rule_OID]
短划线(-)是一个可选标志,用于反向运行排序顺序,以自然方式运行。第 14.3.4 节 “使用匹配规则” 中的匹配规则表包含目录服务器支持的排序规则。
例如:
# ldapsearch -D "cn=Directory Manager" -W -p 389 -h server.example.com -b "dc=example,dc=com" -s sub -x -E sss=-uidNumber:2.5.13.15 "(objectclass=*)"

14.7.3. 执行引用搜索

解引用 搜索是一种快速跟踪条目中的跨引用,并返回有关引用条目的信息。例如,组条目包含对其成员用户条目的引用。常规搜索首先搜索组,然后列出其成员,然后为每个成员单独搜索。解引用搜索组条目返回关于成员的信息,如其位置、电子邮件地址或管理器 - 以及 组的信息,它们都在单个搜索请求中。
解引用简化了许多客户端操作,并减少所执行的搜索操作数量。跨链接显示条目之间的关系。有些操作可能需要从一个条目中获取跨链接的列表,然后执行一系列后续搜索以从列表中的每个条目中获取信息。解引用允许将这些搜索序列合并到单个搜索中。
重要
取消引用的操作需要使用 OpenLDAP 命令行工具版本 2.4.18 或更高版本,或其他支持取消引用搜索的其他客户端。
dereference 参数的格式是:
-E 'deref=deref_attribute:list_of_attributes'
deref_attribute 是包含引用的搜索目标中的属性。这可以是具有值 DN 的任何属性,如 membermanager
注意
不仅必须是 deref_attribute 的值,但属性的实际定义语法必须是 DN 语法(1.3.6.1.4.1.1466.115.121.1.12)。
list_of_attributes 是引用条目中的一个或多个属性,它将与主搜索结果一起返回。可以使用逗号分隔多个属性,如 l、mail、cn

图 14.1. 简单引用搜索命令

简单引用搜索命令
在搜索参数中请求的已请求的取消引用信息会被返回,它带有其余的搜索结果。例如,这会解引用搜索,告知服务器使用搜索目标条目(工程师组)中的 member 属性作为 deref_attribute。然后,它会返回每个成员的 locality 属性。
# ldapsearch -x -D "cn=Directory Manager" -W -b "cn=Example,ou=Groups,dc=example,dc=com" -E 'deref=member:mail,cn' "(objectclass=*)"

# Engineers, Groups, example.com
dn: cn=Engineers,ou=Groups,dc=example,dc=com
control: 1.3.6.1.4.1.4203.666.5.16 false MIQAAADNMIQAAAA1BAZtZW1iZXIEK2NuPURld
 mVsb3BlcnMsIG91PUdyb3VwcywgZGM9ZXhhbXBsZSxkYz1jb20whAAAADIEBm1lbWJlcgQoY249VG
 VzdGVycywgb3U9R3JvdXBzLCBkYz1leGFtcGxlLGRjPWNvbTCEAAAAVAQGbWVtYmVyBCp1aWQ9ZW5
 nLCBvdT1lbmdpbmVlcmluZywgZGM9ZXhhbXBsZSxkYz1jb22ghAAAABowhAAAABQEAWwxhAAAAAsE
 CUNhbWJyaWRnZQ==
# member: <mail=jsmith@example.com><cn=John Smith>;uid=jsmith,ou=people,dc=example,dc=com
 objectClass: top
objectClass: inetuser
objectClass: groupofnames
cn: Engineers
member: uid=jsmith,ou=people,dc=example,dc=com

14.7.4. 使用简单页面结果

搜索结果可能非常大,处理结果的一部分正在组织结果。执行此操作的一种方法是 使用简单的页面结果,其控制会将结果分成特定长度的页面。
简单的页面结果控制一次要显示的条目数。一次可以通过一个页面滚动结果,从而使结果更易于摘要。RFC 2696 中描述了控制的完整行为。
简单的页面结果是作为目录服务器的 LDAP 控制扩展实施的。其 OID 是 1.2.840.113556.1.4.319

简单页面结果的工作方式

当您启动一个简单的页面结果搜索时:

  1. 客户端将搜索发送到服务器,以及页面结果控制以及第一个页面中要返回多少记录。
  2. 在目录服务器开始返回数据前,服务器会生成估算总可返回多少条记录。
    记录的估计不是确切的数字。返回的记录总数可以小于估计的值。此类情况的原因包括
    • 搜索过滤器中使用的属性在索引中不存在。因此,必须索引所有查询的属性。
    • 在向客户端发送条目前,验证访问控制列表(ACL)。权限不足可能会阻止条目返回。
    生成估算后,服务器会发送第一个结果集合、cookies 和估计记录数。
  3. 返回的记录显示在客户端中。用户现在可以输入下一次请求中应返回多少记录。现在,请求的数量会和 Cookie 发送到服务器。
  4. 服务器从数据库检索请求的记录数量,并将它们与 Cookie 一起发送到客户端。
  5. 前两个步骤会重复,直到发送所有记录或取消搜索。

简单页面结果和 OpenLDAP 工具

带有 ldapsearch 的简单页面结果搜索选项的格式是:

-E pg=size
size 值是页面大小,或每个页面包含的条目数。例如:
ldapsearch -x -D "cn=Directory Manager" -W -b "ou=Engineers,ou=People,dc=example,dc=com" -E pg=3 "(objectclass=*)" cn

dn: uid=jsmith,ou=Engineers,ou=People,dc=example,dc=com
   cn: John Smith

dn: uid=bjensen,ou=Engineers,ou=People,dc=example,dc=com
   cn: Barbara Jensen

dn: uid=hmartin,ou=Engineers,ou=People,dc=example,dc=com
   cn: Henry Martin

Results are sorted.
next page size (3): 5
末尾的标签显示搜索中已配置的页面大小(括号中的数字)。冒号后,输入下一页的页面大小,因此输入 5,如所示,将打开包含五个条目的下一页。
重要
简单的页面结果操作必须使用 OpenLDAP 命令行工具版本 2.4.18 或其他支持简单页面结果(如 Perl Net::LDAP)的客户端完成。

简单页面结果和服务器端排序

简单的页面结果可与服务器端使用。服务器端排序是一个控制,它在服务器上执行排序过程,而不是在客户端上执行;这通常是针对使用特定匹配规则的搜索完成。(此行为在 RFC 2891 中定义。) OpenLDAP 客户端工具不支持使用简单页面结果控制的服务器端排序,但其他 LDAP 工具(如 Perl Net::LDAP )支持两者。

单一连接上的多个简单页面结果请求

有些客户端可能会打开与 Directory 服务器的单一连接,但发送多个操作请求,包括使用简单页面结果扩展的多个搜索请求。

目录服务器可以管理和解释多个简单的搜索。每个搜索都作为数组中的条目添加。首次发送页面搜索结果时,会创建一个 Cookie 并与搜索结果关联。每个结果页面都会使用该 Cookie 返回,并且 Cookie 用于请求下一个结果页面。在最后页中,cookies 为空,表示结果的末尾。这会为每个集合保留一组搜索结果。
当在单个连接上有多个简单的页面结果时,仍然会观察超时限制,但 所有打开的 搜索请求 在任何页面搜索断开连接前会达到 它们的配置时间限制。

简单页面结果,与 VLV 索引进行比较

VLV 索引与简单的页面类似,结果也会返回可用的浏览结果列表。主要区别在于如何生成该列表。每个搜索都会计算简单的页面结果,而 VLV 索引是永久列表。总体而言,VLV 索引对于搜索速度更快,但需要一些服务器端配置和开销才能使服务器维护。

注意
简单的页面结果和 VLV 索引 不能 在同一搜索中使用。简单的页面结果会尝试操作 VLV 索引,该索引已经是浏览索引。如果使用 VLV 索引传递了搜索控制,则服务器会返回 UNWILLING_TO_PERFORM 错误。

14.7.5. 预读取条目响应控制

红帽目录服务器支持根据 RFC 4527 的预读取条目响应控制。如果客户端请求一个或多个响应控制,则返回 LDAP 搜索条目,其中包含更新前和之后属性的值。
使用预读取控制时,会在修改前返回包含指定属性值的 LDAP 搜索查询。使用后读取控制时,查询会在修改后包含属性的值。这两个控制可以同时使用。例如,要更新 description 属性,并在修改前和之后显示值:
# ldapmodify -D "cn=Directory Manager" -W -x \
    -e \!preread=description -e \!postread=description 
dn: uid=user,ou=People,dc=example,dc=com
changetype: modify
replace: description
description: new description

modifying entry "uid=user,ou=People,dc=example,dc=com"
control: 1.3.6.1.1.13.1 false ZCkEJXVpZD1qdXNlcixvdT1QZW9wbGUsZGM9ZXhhbXBsZSxk
 Yz1jb20wAA==
# ==> preread
dn: uid=user,ou=People,dc=example,dc=com
description: old description
# <== preread
control: 1.3.6.1.1.13.2 false ZEsEJXVpZD1qdXNlcixvdT1QZW9wbGUsZGM9ZXhhbXBsZSxk
Yz1jb20wIjAgBAtkZXNjcmlwdGlvbjERBA9uZXcgZGVzY3JpcHRpb24=
# ==> postread
dn: uid=user,ou=People,dc=example,dc=com
description: new description
# <== postread