查询Active Directory

目录

查询Active Directory

BaseDN

过滤规则

LDAP高级搜索语法

LDAP 查找中的位操作

LDAP 查找中的objectCategory和objectClass


查询Active Directory

通过查询目录,可以直接收集到要求的数据。查询目录需要指定两个要素

  • BaseDN
  • 过滤规则

BaseDN

BaseDN指定了这棵树的根。比如指定BaseDN为DC=xie,DC=com就是以DC=xie.DC=com为根往下搜索

BaseDN为CN=Users,DC=xie.DC=com就是以CN=Users,DC=xie.DC=com为根往下搜索

过滤规则

LDAP 过滤规则相对简单,很方便入手

LDAP 搜索过滤器语法有以下子集:

  • 用与号 (&) 表示的 AND 运算符。
  • 用竖线 (|) 表示的 OR 运算符。
  • 用感叹号 (!) 表示的 NOT 运算符。
  • 用名称和值表达式的等号 (=) 表示的相等比较。
  • 用名称和值表达式中值的开头或结尾处的星号 (*) 表示的通配符。

下面举几个例子:

  • (uid=testuser):匹配 uid 属性为testuser的所有对象
  • (uid=test*):匹配 uid 属性以test开头的所有对象
  • (!(uid=test*)):匹配 uid 属性不以test开头的所有对象
  • (&(department=1234)(city=Paris)):匹配 department 属性为1234且city属性为Paris的所有对象
  • (|(department=1234)(department=56*)):匹配 department 属性的值为1234或者以56开头的所有对象。

一个需要注意的点就是运算符是放在前面的,跟我们之前常规思维的放在中间不一样。

关于查询目录还有一些高级点的用法,比如 LDAP 控件,位掩码等。

LDAP高级搜索语法

LDAP 查找中的位操作

在LDAP 里面,有些字段是位字段,这里以userAccountControl举例,关于这个字段的详细意义,后面会详细介绍,这里先把他当做一个普通的位字段,不去考虑他的具体含义,这里先看下他的内容。

他的属性类位于架构分区的 CN=User-Account-Control,CN=Schema,CN=Configuration,DC=xie,DC=com

attributeSyntax2.5.5.9,oMSyntax2

查表可知是32位的Integer类型。

之所以我们说他是位字段,是因为他是由一个个位构成。

比如说一个账户,他只有LOCKOUT和NOT_DELEGATED有值,其他位都没有。那这个用户的属性userAccountControl的值就为0x100000+0x0010。是个32 位 int 类型。

现在如果我要搜索域内所有设置了NOT_DELEGATED的所有对象。那么用之前简单的LDAP语法就显得力不从心。简单的LDAP搜索语法只能对某个属性进行过滤,还不能对属性里面的某个具体位进行过滤。所以这也是我们这一节要讲的内容。LDAP的语法支持按位搜索。

执行过滤器以搜索位字段,必须遵循以下语法:

<属性名称>:<BitFilterRule-ID>:= <十进制比较值>

其中的<BitFilterRule-ID>,内容如下。

我们最常的是LDAP_MATCHING_RULE_BIT_AND ,也就是1.2.840.113556.1.4.803

我们举几个例子。

我们想查询哪些对象设置了 TRUSTED_FOR_DELEGATION 

TRUSTED_FOR_DELEGATION对应的十进制比较值为524288

根据语法,我们就可以构造以下过滤规则

(userAccountControl:1.2.840.113556.1.4.803:=524288)

adfind的查询命令如下

adfind.exe -b dc=xie,dc=com -f "(userAccountControl:1.2.840.113556.1.4.803:=524288)" -bit -dn

但是使用这种语法我们还得去记BitFilterRule,于是adfind提供了一个更为快捷的方式。

adfind.exe -b dc=xie,dc=com -f "(userAccountControl:AND:=524288)" -bit -dn

LDAP 查找中的objectCategory和objectClass

(1) objectClass

在前面一节里面说过,在对象的objectClass 属性里面,可以看到这个对象是哪个类的实例,以及这个类的所有父类,比如说CN=jane,CN=Users,DC=test,DC=localobjectClasstop,person,organizationalPerson,user。那我们通过过滤语句(objectClass=user),(objectClass=organizationalPerson)都能找到这个对象。

所有的类都是top类的子类。因此当我们过滤(objectClass=top)可以找到域内的所有对象。

adfind.exe -b dc=xie,dc=com -s subtree -bit -f "(objectclass=*)" -c 
adfind.exe -b dc=xie,dc=com -s subtree -bit -f "(objectclass=top)" -c 

(2) objectCategory

在Windows Server 2008之前默认不对objectClass 属性进行索引。最初认为对多值属性(如objectClass)进行索引会导致性能下降。如此一来,Windows 2000 附带了未索引的objectClass 属性和另一个已建立索引的单值属性,称为objectCategory。

接下来介绍下objectCategory这个属性。对象类的每个实例还具有一个objectCategory属性,该属性是一个单值属性。并且建立了索引。其中包含对象是其实例的类或其父类之一的专有名称。

比如说CN=hack,CN=Users,DC=xie,DC=com 他的objectCategoryCN=Person,CN=Schema,CN=Configuration,DC=xie,DC=com

创建对象时,系统会将其objectCategory属性设置为由其对象类的defaultObjectCategory属性指定的值。无法更改对象的objectCategory属性。

如果我们想过滤所有objectCategory的属性为CN=Person,CN=Schema,CN=Configuration,DC=xie,DC=com的对象,这个很简单。

(objectCategory="CN=Person,CN=Schema,CN=Configuration,DC=test,DC=local")

adfind查询语法如下

adfind.exe -b dc=xie,dc=com -s subtree -bit -f "(objectCategory="CN=Person,CN=Schema,CN=Configuration,DC=xie,DC=com")" -dn

但是这样,又有点不方便,需要记住记住类的DN,所以LDAP在实现上实现了个小技巧。对象类有个属性lDAPDisplayName,指定他的显示名。事实上,我们看objectClass属性里面的类以及父类(比如top.person),他的名字都是这个类的lDAPDisplayName

CN=Person,CN=Schema,CN=Configuration,DC=xie,DC=comlDAPDisplayNameperson.所以LDAP在实现上,支持用类的lDAPDisplayName作为搜索条件。所以如果我们想找所有CN=Person,CN=Schema,CN=Configuration,DC=xie,DC=com的实例,可以简化为以下过滤规则。

(objectCategory=person)

adfind搜索语法为

adfind.exe -b dc=xie,dc=com -s subtree -bit -f "(objectCategory=person)" -dn

(3) objectClass 与objectCategory的结合使用

如果想确保查询在所有版本的Active Directory上都能正常运行,建议使用 objectClass 和objectCategory结合。如果在目录中已经索引了ObjectClass ,或者所有域控制器都在运行Windows Server 2008或更高版本,则可以随意使用 objectClass,而不必担心会对性能产生影响。

这里我们介绍下objectClass 和objectCategory的结合使用。前面我们分别介绍了objectClass 以及objectCategory,但是没讲怎么把他们结合在一起使用。

我们这里再来理一理思路。

CN=jane,CN=Users,DC=test,DC=local这个对象。他的objectClasstop,person,organizationalPerson,user。他的objectCategoryperson

一个对象的objectClass 是一个类的对象类,以及这个对象类的所有父类。

一个对象的objectCategory 是一个类的对象类或者这个对象类的所有父类。

所以说一个对象的objectCategory 必定是objectClass 中的其中一个。

user,person,organizationalPerson类将其defaultObjectCategory设置为person。这允许像(objectCategory= person)这样的搜索过滤器通过单个查询定位所有这些类的实例。

比如说,我们要定位所有的user 类的实例。(CN=jane,CN=Users,DC=test,DC=local就是user类的一个对象)

user 类的继承关系如下。

top => person => organizationalPerson => user

person,organizationalPerson,user都将其defaultObjectCategory设置为person。因此我们可以先过滤。

(objectCategory=person)

但是这样的结果并不精准。我们使用objectClass进一步在过滤后的结果进行过滤

(&(objectCategory=person)(objectClass=user))

这样就能精准匹配到了。其实说通俗点就是,objectCategory建立索引,所以查询时间比较快。我们通过objectCategory划分一个大的范围,然后通过objectClass进行精准匹配。

当然如果在目录中已经索引了ObjectClass ,或者所有域控制器都在运行Windows Server 2008或更高版本,我们直接使用 objectClass((objectClass=user)) 也能很精准地匹配并且不用考虑效率问题。

参考文章:https://daiker.gitbook.io/windows-protocol/ldap-pian/8#0x06-sou-suo-active-directory

猜你喜欢

转载自blog.csdn.net/qq_36119192/article/details/107610208