使用 DirSync Control 轮询更改
Active Directory 目录同步 (DirSync) 控件是一个 LDAP 服务器扩展,可让应用程序搜索目录分区中自以前状态以来已更改的对象。
在使用 IDirectorySearch 时指定 ADS_SEARCHPREF_DIRSYNC 搜索首选项,从而通过 ADSI 使用 DirSync 控件。 有关更多信息和代码示例,请参阅使用 ADS_SEARCHPREF_DIRSYNC 的示例代码。 还可以使用 LDAP API 来执行 DirSync 搜索。 下面介绍了 ADSI 的实现,其中大部分内容也适用于直接使用 LDAP,但本主题末尾讨论的内容除外。
在执行 DirSync 搜索时,会传入一个特定于提供商的数据元素 (Cookie),用于识别上次 DirSync 搜索时的目录状态。 对于第一次搜索,将传入一个空 Cookie,然后搜索会返回所有与筛选器匹配的对象。 搜索还会返回一个有效的 Cookie。 将 Cookie 存储在与 Active Directory 服务器同步的同一存储中。 在后续搜索中,从存储器中获取 Cookie 并将其与搜索请求一起传递。 现在,搜索结果只包括自 Cookie 标识的上一个状态以来发生变化的对象和属性。 搜索还会返回一个新的 Cookie,以便下次搜索时存储。
下表列出了客户端搜索请求可指定的搜索参数。
参数 | 说明 |
---|---|
搜索基础 | DirSync 搜索的基础必须是目录分区的根目录,而目录分区可以是域分区、配置分区或模式分区。 |
范围 | DirSync 搜索的范围必须是 ADS_SCOPE_SUBTREE,即分区的整个子树。 请注意,对于域分区的搜索,子树包括配置和模式分区的头,但不包括内容。 要轮询较小范围内的更改,请使用 USNChanged 技术而不是 DirSync。 |
筛选器 | 可以指定任何有效的搜索筛选器。 对于使用空 Cookie 进行的初始搜索,搜索结果包括与筛选器器匹配的所有对象。 对于使用有效 Cookie 进行的后续搜索,搜索结果只会包括符合筛选条件的对象数据,以及自 Cookie 所示状态以来发生了变化的对象数据。 有关搜索筛选器的详细信息,请参阅创建查询筛选器。 |
属性 | 可以指定更改发生时要返回的属性列表。 对于每个对象,初始结果包括该对象上设置的所有请求属性。 后续搜索结果只包括已更改的指定属性。 未更改的属性不会包括在搜索结果中。 在 ADSI 实现中,搜索结果总是包括每个对象的 objectGUID 和 instanceType。 此外,指定的属性列表还可作为附加筛选器:初始搜索结果只包括至少设置了一个指定属性的对象;后续搜索结果只包括一个或多个属性已发生变化(值已添加或删除)的对象。 |
此外,请注意:
对于渐进式搜索,最佳做法是绑定到上一次搜索中使用的同一域控制器 (DC),即生成 Cookie 的 DC。 如果同一 DC 不可用,要么等到它可用,要么绑定到新的 DC 并执行完全同步。 将 DC 的 DNS 名称与 Cookie 一起存储在辅助存储器中。
可以将一个 DC 生成的 Cookie 传递给托管同一目录分区副本的另一个 DC。 客户端不会因为在另一个 DC 上使用一个 DC 的 Cookie 而错过更改。 不过,新 DC 的搜索结果有可能包括旧 DC 报告的更改;在某些情况下,新 DC 可能会返回所有对象和属性,就像完全同步一样。 客户端只需使其数据库与任何给定 DirSync 调用所报告的搜索结果保持一致,也就是说,把所有渐进式结果当作最新状态来处理。 至于您之前是否看到过变化,甚至是否要回到之前的状态,这并不重要,因为重复的渐进式同步会趋于一致。
其他 DC 也有可能拒绝接受原始 DC 返回的 Cookie。 搜索会在服务器上产生 LDAP 错误,如“0000203D: LdapErr: DSID-xxxxxxxx, comment: Error processing control, data 0”,客户端应用程序可能会产生类似“System.DirectoryServices.Protocols.DirectoryOperationException: A protocol error occurred”。例如,当 Cookie 较旧,而运行不同 Windows 版本的 LDAP 服务器在处理 Cookie 时预计 Cookie 的内部内容会有所不同时,就可能发生这种情况。 cookie 是一种不透明结构,不能保证所有 Windows OS 版本在结构上保持一致。 如果遇到此错误,客户端应用程序应处理这种情况,并重试完全同步。
当一个对象被重命名或移动时,其子对象(如有)将不包括在搜索结果中,即使子对象的可分辨名称已经改变。 同样,当对象安全描述符中的可继承 ACE 被修改时,即使子对象的安全描述符已更改,搜索结果中也不会包括该对象的子对象。
使用 objectGUID 属性来标识跟踪的对象。 无论对象在林中移动到哪个位置,每个对象的 objectGUID 均保持不变。
请注意,DirSync 搜索结果显示的是搜索时目录分区副本上对象的状态。 这意味着,在其他 DC 上进行的更改如果没有复制到目标 DC,它们就不会被包括在内。 这也意味着,自上次 DirSync 搜索以来,对象的属性可能已多次更改,但搜索只会显示最终状态,而不会显示更改序列。
在 ADSI 实现中,应用程序必须将 Cookie 作为不透明处理,并且不能对其内部组织或价值做出任何假设。
请注意,客户端会将 DC 的 Cookie、Cookie 长度和 DNS 名称存储在包含同步对象数据的同一存储区中。 这样可以确保在从备份恢复存储时,Cookie 和其他参数与对象数据保持同步。
要检索为 DirSync 控件构建的 parentGUID 属性,还需要请求 name 属性。
要使用 DirSync 控件,调用方必须在被监控分区的根目录上分配有“获取目录更改”的权限。 默认情况下,将为域控制器上的 Administrator 和 LocalSystem 帐户分配此权限。 调用方还必须拥有 DS-Replication-Get-Changes 扩展控制访问权限。 有关为必须在无此权限的帐户下运行的应用程序实施更改跟踪机制的更多信息,请参阅使用 USNChanged 轮询更改。 有关权限的更多信息,请参阅 XUserPrivilege。
使用 DirSync 搜索检索已删除的对象
ADS_SEARCHPREF_DIRSYNC 搜索结果会自动包含符合指定搜索筛选器的已删除对象(逻辑删除)。 但是,一个搜索筛选器如果在对象处于活动状态时与之匹配,那么在对象被删除后可能就与之不匹配了。 这是因为逻辑删除只会保留原始对象上存在的属性的子集。 例如,通常会对用户对象使用以下筛选器。
(&(objectClass=user)(objectCategory=person))
在删除对象时,objectCategory 属性会被移除,因此上述筛选器不会匹配任何逻辑删除对象。 相反,objectClass 属性保留在逻辑删除对象上,因此“(objectClass=user)”筛选器将匹配已删除的用户对象。
在 DirSync 搜索中指定的属性列表也可用作筛选器;搜索结果只包括自上次 DirSync 搜索以来有一个或多个指定属性发生变化的对象。 如果属性列表不包括逻辑删除上保留的任何属性,则搜索结果将不包括逻辑删除。 要处理这种情况,可以通过指定一个 null 属性列表来请求所有属性;也可以请求在所有逻辑删除上设置为 TRUE 的 isDeleted 属性。 逻辑删除属性在 attributeSchema 定义的 searchFlags 属性中设置了 0x8 位。
有关详细信息,请参阅检索已删除的对象。
DirSync 控件的 LDAP 实现
还可以通过使用 LDAP API 和 LDAP_SERVER_DIRSYNC_OID 控件来执行 DirSync 搜索。 如果使用 LDAP API,还应指定 LDAP_SERVER_EXTENDED_DN_OID 和 LDAP_SERVER_SHOW_DELETED_OID 控件。 LDAP_SERVER_EXTENDED_DN_OID 控件会使 LDAP 搜索返回一个扩展形式的可分辨名称,其中包括用户、组和计算机等安全主体对象的 objectGUID 和 objectSID。 LDAP_SERVER_SHOW_DELETED_OID 控件会让搜索结果包含已删除对象的数据。 请注意,这些控件会自动包含在 ADSI 实现中。