dsquery 结果不一致

dsquery 结果不一致

我有一个带有 2 个域控制器的域(my.local):

  • 192.168.3.63 - DC1
  • 192.168.3.64-DC2(主 DC)

我正在测试请求以查找用户是否是某个组的成员。这是一个查询过滤器:

(&(&(objectClass=user)(sAMAccountName=adtest2))(memberOf:1.2.840.113556.1.4.1941:=CN=Test.NestedB,CN=Users,DC=my,DC=local))

如果我在两个控制器上都使用“Active Directory 用户和计算机”(ADUaC)管理单元,我会得到相同的结果:

在此处输入图片描述

但是当我运行 dsquery 时,没有得到任何结果:

C:\Users\admin>dsquery * domainroot -filter "(&(&(objectClass=user)(sAMAccountName=adtest2))(memberOf:1.2.840.113556.1.4.1941:=CN=Test.NestedB,CN=Users,DC=my,DC=local))" 
C:\Users\admin>

更有趣的是,如果我指定-s参数,dsquery 会返回结果,但只有当我传递另一个 DC 时才会返回,而不是我运行 dsquery 的 DC

在 DC1 (192.168.3.63) 上: 注意根据 -s 开关的行为变化

C:\Users\admin>dsquery * domainroot -s 192.168.3.63 -filter "(&(&(objectClass=user)(sAMAccountName=adtest2))(memberOf:1.2.840.113556.1.4.1941:=CN=Test.NestedB,CN=Users,DC=my,DC=local))"
C:\Users\admin>
C:\Users\admin>dsquery * domainroot -s 192.168.3.64 -filter "(&(&(objectClass=user)(sAMAccountName=adtest2))(memberOf:1.2.840.113556.1.4.1941:=CN=Test.NestedB,CN=Users,DC=my,DC=local))"
"CN=adtest2,CN=Users,DC=my,DC=local"
C:\Users\admin>

在 DC2 (192.168.3.64) 上:

C:\Users\admin>dsquery * domainroot -s 192.168.3.63 -filter "(&(&(objectClass=user)(sAMAccountName=adtest2))(memberOf:1.2.840.113556.1.4.1941:=CN=Test.NestedB,CN=Users,DC=my,DC=local))"
"CN=adtest2,CN=Users,DC=my,DC=local"
C:\Users\admin>
C:\Users\admin>dsquery * domainroot -s 192.168.3.64 -filter "(&(&(objectClass=user)(sAMAccountName=adtest2))(memberOf:1.2.840.113556.1.4.1941:=CN=Test.NestedB,CN=Users,DC=my,DC=local))"
C:\Users\admin>

我尝试使用 和 - 运行 dsquery domainrootforestroot"DC=my,DC=local"没有效果。我还尝试指定-scope subtree,但这是默认设置。

  • 为什么不指定 DC 的 dsquery 总是无法找到用户而 ADUaC 却总是成功?
  • 为什么 dsquery 仅返回来自不同 DC 的结果,但是当指定 -s 开关时却返回来自当前 DC 的结果?
  • 为了使 dsquery 持续工作,我可以/应该做哪些改变?

答案1

这不会是一个完整的答案,因为验证需要太长时间,而且我也不清楚具体细节,但我希望它与包含的具体查询有关1.2.840.113556.1.4.1941

这是LDAP_MATCHING_RULE_IN_CHAINOID,它特定于 Active Directory LDAP。如果您指定forestroot,则您正在访问 GC。对于domainroot,它显然是域根。我认为这里的问题是,这种方法不是通过递归遍历结构来搜索对象的传统方法。例如,如果您按名称进行匹配。

LDAP_MATCHING_RULE_IN_CHAIN是一种特定于 AD 的“快捷方式”方法 - 有点像 SQL 中的存储过程。因此,要使用它,您需要绑定到在协议级别提供该特定功能的 LDAP 服务器 (DC)。就像能够查看数据库表很容易一样,但要使用存储过程,您需要使用 SQL 功能。

通过运行 LDP.exe 并绑定到 DC,您可以了解我的意思 - 当您执行绑定时,DC 将在 下列出它支持的 LDAP 功能SupportedControl。有了这些,它们通常具有可以进一步查询的子控件,我认为LDAP_MATCHING_RULE_IN_CHAIN可能是其中之一。

请记住,GUI 在后台为您做了很多工作。它给您的并不是纯粹的 LDAP - 它使用 DLL 和 .NET 钩子来检索数据并以友好的方式对其进行格式化。

因此,为了使您的查询更加一致,您需要绑定到特定的 DC 来访问LDAP_MATCHING_RULE_IN_CHAIN协议方法,因为您不仅仅是“浏览”目录。我没有看到您使用开关的示例-d [domain DNS name]。这将绑定到任何站点/域中的可用 DC。

dsquery user -name *test -d mydomain.org

最后,为了让你的生活很多更简单,使用这样的 LDAP 查询对于 DSQuery 来说实际上相当不寻常。它的重点是它应该是 LDAP 的一个友好(更)“包装器”,有点像 GUI。它有一些“助手”来使查询更容易和格式化数据。

如果您想要组 samAccountNames,获取用户所属组的通常方法如下。

dsquery user -samid %USERNAME% | dsget user -memberof | dsget group -samid

如果您只想要组 DN,则只需删除| dsget group -samid

这篇文章很好地介绍了该工具- 我建议您阅读它以获得关于常用语法和方法的良好提示。

这些天,我建议你开始掌握 AD Powershell。Powershell 确实更灵活,尽管 dsquery 仍然有一些技巧。

相关内容