使用 DirSync 控件轮询更改
Active Directory 目录同步 (DirSync) 控件是一个 LDAP 服务器扩展,使应用程序能够搜索自上一状态以来已更改的对象目录分区。
使用 IDirectorySearch 时,通过 ADSI 指定ADS_SEARCHPREF_DIRSYNC搜索首选项,从而使用 DirSync 控件。 有关详细信息和代码示例,请参阅 使用ADS_SEARCHPREF_DIRSYNC的示例代码。 还可以使用 LDAP API 执行 DirSync 搜索。 下面介绍了 ADSI 实现,其中大多数也适用于直接使用 LDAP,但本主题末尾所述除外。
执行 DirSync 搜索时,会传入提供程序特定的数据元素 (cookie) ,用于标识上一次 DirSync 搜索时的目录状态。 对于第一次搜索,将传入 null Cookie,搜索将返回与筛选器匹配的所有对象。 搜索还会返回有效的 Cookie。 将 Cookie 存储在与 Active Directory 服务器同步的同一存储中。 在后续搜索中,从存储获取 Cookie,并使用搜索请求传递它。 搜索结果现在仅包含自 Cookie 标识的上一状态以来已更改的对象和属性。 搜索还会返回用于存储下一次搜索的新 Cookie。
下表列出了客户端搜索请求可以指定的搜索参数。
参数 | 说明 |
---|---|
搜索基础 | DirSync 搜索的基数必须是目录分区的根目录,可以是域分区、配置分区或架构分区。 |
作用域 | DirSync 搜索的范围必须 ADS_SCOPE_SUBTREE,即分区的整个子树。 请注意,对于搜索域分区,子树包含配置和架构分区的头,但不包括内容。 若要轮询较小范围内的更改,请使用 USNChanged 技术而不是 DirSync。 |
筛选器 | 可以指定任何有效的搜索筛选器。 对于具有 null Cookie 的初始搜索,结果包括与筛选器匹配的所有对象。 对于具有有效 Cookie 的后续搜索,搜索结果仅包含与筛选器匹配的对象的数据,并且自 Cookie 指示的状态以来已更改。 有关搜索筛选器的详细信息,请参阅 创建查询筛选器。 |
特性 | 可以指定要在发生更改时返回的属性列表。 对于每个对象,初始结果包括对象上设置的所有请求属性。 后续搜索结果仅包含已更改的指定属性。 搜索结果中不包含未更改的属性。 在 ADSI 实现中,搜索结果始终包括每个对象的 objectGUID 和 instanceType 。 此外,指定的属性列表充当其他筛选器:初始搜索结果仅包含至少一个指定属性集的对象;后续搜索仅包含一个或多个属性已更改的对象, (添加或删除) 的值。 |
此外,请注意:
对于增量搜索,最佳做法是绑定到在上一次搜索中使用的同一域控制器 (DC) ,即生成 Cookie 的 DC。 如果同一 DC 不可用,请等待,或绑定到新的 DC 并执行完全同步。 使用 Cookie 将 DC 的 DNS 名称存储在辅助存储中。
可以将一个 DC 生成的 Cookie 传递到托管同一目录分区副本的不同 DC。 客户端不可能使用另一个 DC 上的 Cookie 来错过更改。 但是,新 DC 的搜索结果可能包括旧 DC 的报告更改;在某些情况下,新的 DC 可能会返回所有对象和属性,就像完全同步一样。 客户端应使其数据库与报告的任何 DirSync 调用的搜索结果保持一致,即处理所有增量结果,就像它们是最新状态一样。 不管之前还是回退到以前的状态,因为重复的增量同步会聚合在一致性上,这无关紧要。
另一个 DC 可能拒绝从原始 DC 返回的 Cookie。 搜索在服务器上生成 LDAP 错误,例如“0000203D:LdapErr:DSID-xxxxxxxx,注释:错误处理控制,数据 0”,客户端应用程序可能会生成错误,例如“System.DirectoryServices.Protocols.DirectoryOperationException:发生协议错误”。例如,如果 Cookie 较旧,并且运行不同版本的 Windows 的 LDAP 服务器处理 Cookie 的内部内容预期不同,则可能会发生这种情况。 Cookie 是一种不透明结构,不能保证在所有 Windows OS 版本结构上保持一致。 如果遇到此错误,客户端应用程序应处理此情况,并使用完全同步重试。
重命名或移动对象时,其子对象(如果有)不包括在搜索结果中,即使子对象的可分辨名称已更改。 同样,在对象安全描述符中修改可继承的 ACE 时,即使子对象的安全描述符已更改,该对象的子对象也不会包含在搜索结果中。
使用 objectGUID 属性标识跟踪的对象。 无论对象在林中移动的位置,每个对象的 objectGUID 保持不变。
请注意,DirSync 搜索的搜索结果指示搜索时目录分区副本上对象的状态。 这意味着,如果其他 DC 未复制到目标 DC,则不会包含对其他 DC 所做的更改。 这也意味着对象的属性可能已更改多次,因为以前的 DirSync 搜索,但搜索将只显示最终状态,而不是更改序列。
在 ADSI 实现中,应用程序必须将 Cookie 作为不透明处理,而不对其内部组织或价值做出任何假设。
请注意,客户端将 COOKIE、Cookie 长度和 DNS 名称存储在包含同步对象数据的同一存储中。 这可确保从备份还原存储时,Cookie 和其他参数与对象数据保持同步。
若要检索为 DirSync 控件构造的 parentGUID 属性,还需要请求 名称 属性。
若要使用 DirSync 控件,调用方必须在所监视分区的根目录上分配“目录获取更改”。 默认情况下,此权限分配给域控制器上的管理员和 LocalSystem 帐户。 调用方还必须具有 DS-Replication-Get-Changes 扩展控制访问权限。 有关为必须在没有此权限的帐户下运行的应用程序实现更改跟踪机制的详细信息,请参阅 使用 USNChanged 轮询更改。 有关特权的详细信息,请参阅 Privileges。
使用 DirSync 搜索检索已删除的对象
ADS_SEARCHPREF_DIRSYNC搜索结果自动包括与指定搜索筛选器匹配的已删除对象) (墓碑。 但是,搜索筛选器在实时时与对象匹配,在删除对象后可能不匹配该对象。 这是因为墓碑只保留原始对象上存在的属性的子集。 例如,通常对用户对象使用以下筛选器。
(&(objectClass=user)(objectCategory=person))
删除对象时会删除 objectCategory 属性,因此上述筛选器与任何墓碑对象不匹配。 相反,objectClass 属性保留在逻辑块对象上,因此“ (objectClass =user) ”的筛选器将匹配已删除的用户对象。
使用 DirSync 搜索指定的属性列表也充当筛选器;搜索结果仅包含自上一次 DirSync 搜索以来一个或多个指定属性已更改的对象。 如果属性列表不包含在墓碑上保留的任何属性,则搜索结果将不包括墓碑。 若要处理此问题,请通过指定 null 属性列表请求所有属性;也可以请求 isDeleted 属性,在所有墓碑上设置为 TRUE 。 Tombstone 属性在 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 实现中。