ADSI 中的事件跟踪

Windows Server 2008 和 Windows Vista 在 Active Directory 服务接口 (ADSI) 中引入了事件跟踪。 ADSI LDAP 提供程序的某些区域有一个基础实现,该实现很复杂,或者涉及一系列步骤,使得难以诊断问题。 为了帮助应用程序开发人员进行故障排除,已将事件跟踪添加到以下区域:

架构解析和下载

ADSI 中的 IADs 接口要求在客户端上缓存 LDAP 架构,以便可以正确封送处理属性(如 ADSI 架构模型中所述)。 为此,ADSI 将每个进程的架构(以及每个 LDAP 服务器/域的架构)加载到内存中,要么是从本地磁盘上保存的架构 (.sch) 文件,要么是通过从 LDAP 服务器下载。 同一客户端计算机上的不同进程使用磁盘上缓存的架构(如果可用且适用)。

如果无法从磁盘或服务器获取架构,ADSI 将使用硬编码的默认架构。 发生这种情况时,无法封送处理不属于此默认架构的属性,并且 ADSI 会在检索这些属性时返回错误。 许多因素可能会导致发生这种情况,包括解析架构时出现问题,以及没有足够的特权来下载架构。 通常很难确定使用特定默认架构的原因。 在此区域中使用事件跟踪有助于更快地诊断问题并解决问题。

更改和设置密码

ChangePasswordSetPassword 采用多个机制,根据可用配置执行请求的操作(如使用 LDAP 提供程序设置和更改用户密码中所述)。 当 ChangePasswordSetPassword 失败时,很难确切地确定原因,而事件跟踪将有助于排查这些方法的问题。

ADSI 绑定缓存

ADSI 在内部尝试尽可能重用 LDAP 连接(请参阅连接缓存)。 进行故障排除时,跟踪是否打开了新连接来与服务器通信,或者是否使用了现有连接将很有用。 跟踪连接缓存(有时称为绑定缓存)的生命周期及其创建或关闭以及是否发生连接引荐也很有用。 对于无服务器绑定,ADSI 将调用 DC 定位符来为用户上下文域选择服务器。 接着,ADSI 为后续连接维护域-服务器映射的缓存。 事件跟踪有助于跟踪 DC 的选择,因此有助于排查与连接相关的问题。

启用跟踪和启动跟踪会话

若要打开 ADSI 跟踪,请创建以下注册表项:

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\adsi\Tracing\ProcessName

ProcessName 是要跟踪的进程的全名,包括其扩展名(例如,“Svchost.exe”)。 此外,还可以在此项中放置名为 PID 的 DWORD 类型的可选值。 强烈建议设置此值,从而仅跟踪特定进程。 否则,将跟踪由 ProcessName 指定的应用程序的所有实例。

然后,执行以下命令:

tracelog.exe -start sessionname **-guid #**provider_guid -f filename -flag traceFlags -level traceLevel

sessionname 只是用于标记跟踪会话的任意标识符(稍后停止跟踪会话时需要引用此会话名称)。 ADSI 跟踪提供程序的 GUID 为“7288c9f8-d63c-4932-a345-89d6b060174d”。 filename 指定将事件写入其中的日志文件。 traceFlags 应为下列值之一:

标志
DEBUG_SCHEMA
0x00000001
DEBUG_CHANGEPWD
0x00000002
DEBUG_SETPWD
0x00000004
DEBUG_BINDCACHE
0x00000008

这些标志根据下表确定将跟踪哪些 ADSI 方法:

标记 方法
DEBUG_SCHEMA
  • LdapGetSchema
  • GetSchemaInfoTime
  • LdapReadSchemaInfoFromServer
  • ProcessSchemaInfo
  • HelperReadLdapSchemaInfo
  • ProcessClassInfoArray
  • ReadSchemaInfoFromRegistry
  • StoreSchemaInfoFromRegistry
  • AttributeTypeDescription
  • ObjectClassDescription
  • DITContentRuleDescription
  • DirectoryString
  • DirectoryStrings
  • DITContentRuleDescription

DEBUG_CHANGEPWD
  • CADsUser::ChangePassword

DEBUG_SETPWD
  • CADsUser::SetPassword

DEBUG_BINDCACHE
  • GetServerBasedObject
  • GetServerLessBasedObject
  • GetGCDomainName
  • GetDefaultDomainName
  • GetUserDomainFlatName
  • BindCacheLookup
  • EquivalentPortNumbers
  • CanCredentialsBeReused
  • BindCacheAdd
  • BindCacheAddRef
  • AddReferralLink
  • CommonRemoveEntry
  • BindCacheDerefHelper
  • NotifyNewConnection
  • QueryForConnection
  • LdapOpenBindWithCredentials
  • LdapOpenBindWithDefaultCredentials

通过组合 traceFlags 参数中的相应位,可以组合标志。 例如,若要指定 DEBUG_SCHEMADEBUG_BINDCACHE 标志,相应的 traceFlags 值应为 0x00000009。

最后,traceLevel 标志应为以下值之一:

标志
TRACE_LEVEL_ERROR
0x00000002
TRACE_LEVEL_INFORMATION
0x00000004

TRACE_LEVEL_INFORMATION 会导致跟踪进程记录所有事件,而 TRACE_LEVEL_ERROR 会导致跟踪进程仅记录错误事件。

若要终止跟踪,请运行以下命令:

tracelog.exe -stop sessionname

在前面的示例中,sessionname 与随启动跟踪节的命令提供的会话名称相同。

注解

通过指定特定 PID 来仅跟踪特定进程比跟踪计算机上的所有进程更有效。 如果需要在同一台计算机上跟踪多个应用程序,可能会对性能造成影响;代码中面向性能的部分存在大量调试输出。 此外,管理员必须小心,在跟踪多个进程时需正确设置日志文件的权限;否则,任何用户都可能能够读取跟踪日志,其他用户将能够跟踪包含安全信息的进程。

例如,假设管理员为应用程序“Test.exe”设置了跟踪,但未在注册表中指定 PID 来跟踪进程的多个实例。 现在,另一个用户想要跟踪应用程序“Secure.exe”。 如果未正确限制跟踪日志文件,则用户只需将“Secure.exe”重命名为“Test.exe”,即可进行跟踪。 通常,最好在进行故障排除时仅跟踪特定进程,并在故障排除完成后立即删除跟踪注册表项。

由于启用事件跟踪将生成额外的日志文件,因此管理员应仔细监视日志文件大小;本地计算机上的磁盘空间不足可能会导致拒绝服务。

示例方案

方案 1:管理员在为用户帐户设置密码的应用程序中发现意外错误,因此他们将执行以下步骤来使用事件跟踪解决问题。

  1. 编写重现问题的脚本,并创建注册表项

    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\adsi\Tracing\cscript.exe

  2. 使用以下命令启动跟踪会话,将 traceFlags设置为 0x2 (DEBUG_CHANGEPASSWD),并将 traceLevel 设置为 0x4 (TRACE_LEVEL_INFORMATION):

    tracelog.exe -start scripttrace -guid #7288c9f8-d63c-4932-a345-89d6b060174d -f .\adsi.etl -flag 0x2 -level 0x4

  3. 使用测试脚本运行 cscript.exe 以重现问题,然后终止跟踪会话:

    tracelog.exe -stop scripttrace

  4. 删除注册表项

    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\adsi\Tracing\cscript.exe

  5. 运行 ETW 工具 Tracerpt.exe,以解析日志中的跟踪信息:

    tracelog.exe -start scripttrace -guid #7288c9f8-d63c-4932-a345-89d6b060174d -f .\adsi.etl -flag 0x2 -level 0x4

方案 2:管理员希望跟踪某个 ASP 应用程序中的架构解析和下载操作,该应用程序名为 w3wp.exe 且已在运行。 为此,管理员将执行以下步骤:

  1. 创建注册表项

    HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\adsi\Tracing\w3wp.exe

    并在该项中,创建名为 PID 的 DWORD 类型的值,并将其设置为当前在本地计算机上运行的 w3wp.exe 实例的进程 ID。

  2. 然后,创建跟踪会话,将 traceFlags 设置为 0x1 (DEBUG_SCHEMA),并将 traceLevel 设置为 0x4 (TRACE_LEVEL_INFORMATION):

    tracelog.exe -start w3wptrace -guid #7288c9f8-d63c-4932-a345-89d6b060174d -f .\w3wp.etl -flag 0x1 -level 0x4

  3. 重现需要故障排除的操作。

  4. 终止跟踪会话:

    tracelog.exe -stop w3wptrace

  5. 删除注册表项 HKEY_LOCAL_MACHINE\System\CurrentControlSet\Services\adsi\Tracing\w3wp.exe

  6. 运行 ETW 工具 tracerpt.exe,以解析日志中的跟踪信息:

    tracerpt.exe .\w3wp.etl -o -report