Заметки о Windows и других программных продуктах Microsoft...

LDAP-фильтры для поиска объектов в Active Directory. Часть 2

LDAP-фильтры для поиска объектов в Active Directory. Часть 2

Продолжаем разговор об использовании LDAP-фильтров в Active Directory, начатый в предыдущей статье. Сегодня речь пойдет о расширенных фильтрах поиска.

Начнем издалека.

Типы фильтров

LDAP-фильтры условно можно разделить на четыре базовых типа — simple, present, substring и extensible. Элемент simple формируется следующим образом:

(<Атрибут><оператор><значение>)

Например, все пользователи с именем Vasya:

(cn=Vasya)

Элемент present используется для отбора записей, у которых присутствует определённый атрибут и формируется так:

(<Атрибут>=*)

Например, все пользователи с заполненным описанием (Description):

(Description=*)

Элемент substring используется для отбора по подстрокам и формируется следующим образом:

(<Атрибут>=<Начальное значение>*<Конечное значение>)

Например, все пользователи с именем, начинающимся на V и оканчивающимся на a:

(cn=V*a)

Начальное и конечное значение вовсе не обязательны, например:

(cn=V*)

Расширенные фильтры

Вот теперь мы и добрались до расширенных (extensible) фильтров. Они составляются таким образом:

(<Атрибут>:<Правило соответствия>:=<Значение>)

Правило соответствия (Matching Rule) — правило, которое будет применено к искомому компоненту. Правила соответствия определены в RFC 2251 и представляют из себя средство выражения того, как сервер должен сравнивать значение, указанное в фильтре поиска с данными, полученными в результате поиска. Правило может определяться по имени или по OID.

К сожалению, реализация LDAP от Microsoft не поддерживает большинство расширяемых правил, описанных в RFC. Поэтому в Active Directory доступны всего три правила соответствия.

 

Matching rule OID String identifier Описание
1.2.840.113556.1.4.803 LDAP_MATCHING_RULE_BIT_AND Совпадение будет найдено только в том случае, если все биты атрибута совпадут со значением. Это правило эквивалентно операции побитового И (bitwise AND)
1.2.840.113556.1.4.804 LDAP_MATCHING_RULE_BIT_OR Совпадение будет найдено в том случае, если любые биты из атрибута совпадают со значением. Это правило эквивалентно операции побитового ИЛИ (bitwise OR)
1.2.840.113556.1.4.1941 LDAP_MATCHING_RULE_IN_CHAIN Специальный расширенный оператор соответствия, проходящий по цепи наследования к корню до тех пор, пока не найдет совпадение. Выявляет вложенность групп. Применяется только к DN-атрибутам. Доступен на контроллерах домена с Windows Server  2003 SP2 и более поздних версий.

 

Первые два правила представляют из себя операторы побитового сравнения. Дело в том, что значения некоторых атрибутов в AD хранятся в виде битовой маски (Bitmask). Например, атрибут Group-Type (тип группы), определяющий тип и область действия группы в AD, представляет из себя битовую маску со следующими значениями:

0x00000001 (1) — BuiltIn Group;
0x00000002 (2) — Global Group ;
0x00000004 (4) — Domain Local Group ;
0x00000008 (8) — Universal Group;
0x80000000 (2147483648) — Security Group.

При использовании правил синтаксис фильтра выглядит так:

<Атрибут>:<rule OID>:=<Десятичное значение>

К примеру, нам требуется отобрать все универсальные группы. Для этого необходимо с помощью правила LDAP_MATCHING_RULE_BIT_AND проверить в значении атрибута наличие четвертого бита (0x00000008 или 00001000 в двоичном виде). Для этого воспользуемся фильтром:

(groupType:1.2.840.113556.1.4.803:=8)

список всех универсальных групп

 

Если условий несколько, то значения можно складывать. Так если необходимо отобрать все универсальные группы безопасности, то получим значение 2147483656 (2147483648 + 8), а фильтр будет такой:

(groupType:1.2.840.113556.1.4.803:=2147483656)

список всех универсальных групп безопасности

 

Можно пойти от обратного и отобрать группы, не являющиеся группами безопасности (т.е. все группы распространения):

(!(groupType:1.2.840.113556.1.4.803:=2147483648))

список всех универсальных групп распространения

 

Еще один пример битовой маски — это атрибут userAccountControl, в котором хранятся свойства пользователя. Вот некоторые из значений атрибута:

0x00000002 (2) — учетная запись отключена;
0x00000010 (16) — учетная запись заблокирована;
0x00000020 (32) — пароль не требуется;
0x00000040 (64) — запретить смену пароля пользователем;
0x00000200 (512) — учетная запись по умолчанию (учетная запись пользователя со всеми снятыми флагами);
0x00010000 (65536) — срок действия пароля не ограничен;
0x00800000 (8388608) — срок действия пароля истек.

Например, выведем все отключенные (Disabled) учетные записи фильтром:

(userAccountControl:1.2.840.113556.1.4.803:=2)

список отключенных пользователей

 

При необходимости значения можно суммировать между собой. Для  примера с помощью правила LDAP_MATCHING_RULE_BIT_OR найдем всех пользователей, у которых пароль никогда не истекает или не требуется вообще. Значение атрибута при этом будет равно 65568 (65536 + 32):

(userAccountControl:1.2.840.113556.1.4.804:=65568)

список пользователей у которых пароль не истекает или не требуется

 

Правило LDAP_MATCHING_RULE_IN_CHAIN заслуживает особого внимания, поскольку с его помощью можно находить вложенные элементы. Предположим, нам требуется найти все группы, членом которых является пользователь. Для этого потребуется написать функцию, которая будет рекурсивно обходить все группы пользователя, включая вложенные. При этом необходимо учесть ситуацию, когда группа А вложена в группу В, а группа В вложена в группу А.

Так вот, правило LDAP_MATCHING_RULE_IN_CHAIN позволяет решить данную задачу без особых затрат. Для примера найдем все группы пользователя с помощью простого фильтра:

(member=CN=Vasya,OU=Employees,DC=test,DC=local)

А затем используя правило LDAP_MATCHING_RULE_IN_CHAIN:

(member:1.2.840.113556.1.4.1941:=CN=Vasya,OU=Employees,DC=test,DC=local)

Как видите, второй фильтр нашел группу, которую пропустил первый.

поиск всех групп пользователя включая вложенные

 

Теперь возьмем группу и тоже применим к ней два фильтра. Первый фильтр показывает только непосредственных членов группы:

(memberOf=CN=BackOffice,CN=Users,DC=test,DC=local)

А вот второй, в котором используется правило, покажет всех членов группы, включая вложенных:

(memberOf:1.2.840.113556.1.4.1941:=CN=BackOffice,CN=Users,DC=test,DC=local)

поиск всех членов группы включая вложенные

Фильтрация с помощью ANR

Неоднозначное разрешение имен (Ambiguous Name Resolution, ANR) — алгоритм поиска объектов в Active Directory. ANR позволяет задавать сложные фильтры, включающие в себя несколько атрибутов, связанных с именами, причем в одном выражении. Его можно использовать в ситуации, когда вы знаете одно из имен объекта, но не уверены, в каком именно атрибуте это имя присутствует.

ANR включает в поиск следующий список атрибутов:

• displayName
• givenName (First Name)
• sn (Last Name)
• sAMAccountName
• legacyExchangeDN
• Relative Distinguished Name (RDN)
• physicalDeliveryOfficeName
• proxyAddresses
• mail
• mailNickname
• msExchResourceSearchProperties
• msDS-AdditionalSamAccountName
• msDS-PhoneticCompanyName
• msDS-PhoneticDepartment
• msDS-PhoneticDisplayName
• msDS-PhoneticFirstName
• msDS-PhoneticLastName

Например, нам нужно найти пользователя с фамилией Пупкин. В поисках нам поможет вот такой несложный фильтр:

(anr = Пупкин)

В этом случае Active Directory будет искать все объекты, где любой из вышеописанных атрибутов начинается со строки «Пупкин». Если сконвертировать это в стандартный LDAP-фильтр, то получится что то типа такого:

(|(displayName=Пупкин*)(givenName=Пупкин*)(legacyExchangeDN=Пупкин)(physicalDeliveryOfficeName=Пупкин*)(proxyAddresses=Пупкин*)(Name=Пупкин*)(sAMAccountName=Пупкин*)(sn=Пупкин*))

поиск с помощью ANR

 

Если нам известно имя пользователя, к примеру Василий, то можно немного изменить фильтр:

(anr = Василий Пупкин)

В этом случае фильтр будет искать все объекты где любой из вышеописанных атрибутов начинается со строки «Василий Пупкин» плюс объекты, у которых (givenName=Василий*) и (sn=Пупкин*) или (givenName=Пупкин*) и (sn=Василий*). При этом алгоритм поиска учитывает наличие пробела в строке, разбивая ее на два значения.

поиск с помощью ANR

 

Ну и если нам удалось узнать отчество пользователя, к примеру Иванович, тогда получится такой фильтр:

(anr = Василий Иванович Пупкин)

В этом случае фильтр будет искать объекты, у которых любой из атрибутов именования соответствует Василий Иванович Пупкин* плюс объекты, у которых (givenName=Василий*) и (sn=Иванович Пупкин*), плюс объекты с (givenName=Иванович Пупкин*) и (sn=Василий*). В этом случае алгоритм при разбиении строки учитывает только первый пробел.

поиск с помощью ANR

 

При необходимости можно изменить поведение ANR и требовать поиск точного соответствия для любого из атрибутов. Для этого надо перед значением поставить дополнительный знак равенства. Например, этот фильтр выдаст всех пользователей, у которых хотя бы один атрибут из списка точно соответствует строке Василий Иванович:

(anr == Василий Иванович)

поиск с помощью ANR точное соответствие

 

Как видите, LDAP-фильтры имеют много различных возможностей. О том, как их правильно использовать, пойдет речь в следующей статье.

 
 
Комментарии

Пока нет комментариев.