Работа с данными Active Directory c помощью сценариев: Часть 1. Обзор LDAP

Источник: ibm
Рашид Ачилов

Введение

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

В приведенных ниже примерах используется имя домена - shelton.int, короткое имя - CATS.

Часто используемые сокращения:

  • AD - Active Directory (служба каталогов);
  • LDAP - Lightweight Directory Access Protocol (облегченный протокол доступа к каталогам);
  • DN - Distinguished Name (уникальное имя).

Подключение к службе Active Directory и просмотр объектов

Если рассматривать любой контроллер домена Windows как LDAP-сервер, то становится очевидным, что с ним можно работать стандартными средствами, предназначенными для чтения и записи данных в LDAP. Так, на нем можно обнаружить список открытых портов, похожий на приведенный в листинге 1 (из списка удалены порты, не относящиеся к LDAP):

Листинг 1. Список открытых портов типичного контроллера домена Windows

Starting Nmap 4.62 ( http://nmap.org ) at 2008-08-01 01:45 NOVST
Interesting ports on bigcat (192.168.50.1):
Not shown: 1699 closed ports
PORT     STATE SERVICE
88/tcp   open  kerberos-sec
389/tcp  open  ldap
464/tcp  open  kpasswd5
636/tcp  open  ldapssl
3268/tcp open  globalcatLDAP
3269/tcp open  globalcatLDAPssl

Как видно из листинга 1, контроллер домена предоставляет все необходимые сервисы: ldap на порту 389ldap over ssl на порту 636 и т.д. В данном случае компания Microsoft не стала разрабатывать собственное решение, а воспользовалась хорошо известной и документированной службой LDAP. Правда, сама схема LDAP от Microsoft значительно отличается от существующих аналогов, так в листинге 2 приведено описание стандартного объекта "пользователь" (некоторые поля были опущены), полученное с помощью утилиты ldapsearch.

Листинг 2. Поля стандартного объекта AD "пользователь", создаваемые по умолчанию.

dn: CN=LDAP Reader,CN=Users,DC=shelton,DC=int
objectClass: top
objectClass: person
objectClass: organizationalPerson
objectClass: user
cn: LDAP Reader
sn: Reader
givenName: LDAP
distinguishedName: CN=LDAP Reader,CN=Users,DC=shelton,DC=int
instanceType: 4
displayName: LDAP Reader
name: LDAP Reader
objectGUID:: S2M6nZo2XkCfS2jjHt4XBg==
userAccountControl: 66048
badPwdCount: 0
countryCode: 0
badPasswordTime: 128634384464218750
lastLogoff: 0
lastLogon: 128634384682968750
pwdLastSet: 128634383003906250
primaryGroupID: 513
objectSid:: AQUAAAAAAAUVAAAAtInjRe4dmI0lvJgpVwQAAA==
accountExpires: 9223372036854775807
logonCount: 0
sAMAccountName: ldapread
sAMAccountType: 805306368
userPrincipalName: ldapread@shelton.int
objectCategory: CN=Person,CN=Schema,CN=Configuration,DC=shelton,DC=int

Для просмотра и редактирования объектов, загруженных из LDAP, существуют различные программы, например, GUI-приложение ldapbrowser, написанное на Java, или ldapsearch - программа, работающая из командной строки.

Программа ldapsearch - это важный инструмент администратора LDAP-сервера, примерно как ping и traceroute для системного администратора. Она позволяет загружать и использовать практически любые данные, существующие в LDAP. Некоторая проблема может возникнуть из-за того, что в этой программе используется собственный язык запросов. Он построен в соответствии с принципом "обратной польской записи", как в старинных программируемых калькуляторах, когда сначала задается знак операции, а потом перечисляются операнды. Все операнды разделяются отдельными скобками, из-за чего выражения становятся очень громоздкими. Поскольку это язык запросов, то в нем присутствуют только логические операции - И (&), ИЛИ (/), НЕ (!). Рассмотрим несколько примеров с использованием данного языка запросов.

  • (description=*) - любой объект, у которого определено поле description. При этом совершенно неважно какой будет длина этого поля, так, один символ точно так же попадет под фильтр "*", как и длинная строка.
  • (&(objectClass=user)(mail=*)) - любой объект, у которого поле objectClass равно user И определено полеmail.
  • В листинге 3 приведен огромный запрос, используемый для загрузки глобальной адресной книги из LDAP (все содержимое запроса - это одна строка).

Листинг 3. Пример запроса к LDAP-серверу

(&(&(&(mailnickname=*)(/(&(objectCategory=person)(objectClass=user)
(!(homeMDB=*))(!(msExchHomeServerName=*)))(&(objectCategory=person) 
(objectClass=user)(/(homeMDB=*)(msExchHomeServerName=*)))
(&(objectCategory=person)(objectClass=contact))(objectCategory=group)
(objectCategory=publicFolder)))))

Это запрос можно упросить, если воспользоваться знанием структуры каталога AD:

(&(sAMAccountName=*)(/(sAMAccountType=805306368)(sAMAccountType=268435456))(mail=*)).

В значениях sAMAccountType нет ничего секретного - это просто 0x30000000 и 0x10000000 в десятичной форме, обозначающие соответственно тип объекта "пользователь" или "контакт". Ссылку на подробное описание языка запросов можно найти в разделе "Ресурсы".

После изучения языка запросов остается решить вопрос - как подключиться к LDAP из командной строки? При этом необходимо учитывать несколько моментов.

  1. В Windows Server отсутствует так называемый anonymous bind (возможность подключения к LDAP без указания имени пользователя и пароля). Эту возможность можно активировать при наличии необходимых полномочий, но по умолчанию она отключена. Поэтому перед тем, как начать работать с LDAP через ldapsearch или создавать сценарии, необходимо получить отдельную учетную запись и установить достаточно простой пароль. Я обычно использую пароль "qwerty{123}", так как Windows 2003 Server считает его достаточно сложным, и имя пользователя ldapread. Для ldapsearch (и далее повсюду) в качестве значения параметра bind dn указывается строка <имя_пользователя>@<ДОМЕН>, где домен - это имя AD, переведенное в верхний регистр, напримерldapread@SHELTON.INT.
  2. Что указывать в качестве исходной точки для подключения (base dn)? Обычно base dn формируется следующим образом: если AD называется shelton.int, то соответствующим значением base dn будет dc=shelton,dc=int. Если же оно называется kitten.cats.shelton.int (такие длинные имена возможны в больших инсталляциях), то соответствующим значением base dn будет dc=kitten,dc=cats,dc=shelton,dc=int. Разумеется, при подключении можно указать не корень AD, а какую-либо его ветку, например,CN=Computers,DC=shelton,DC=int, но в таком случае поиск никогда не поднимется выше ее границы. Проблема состоит в том, что логически правильным является создание организационных единиц (ou - Organizational Unit), соответствующих разным филиалам, непосредственно в корне AD, поскольку эти ou будут содержать объекты разных типов - пользователей, компьютеры, группы и т.д. Поэтому для просмотра всей структуры AD лучше указывать корневой элемент.
  3. Как в AD хранится не-ASCII информация, т.е. данные на национальных (и на русском, в том числе) языках? Подобная информация хранится в виде текста в кодировке UTF-8, преобразованного с помощью Base64 в набор символов ASCII (см. соответствующую ссылку в разделе "Ресурсы").
  4. Сразу же после установки OpenLDAP необходимо внести в файл /usr/local/etc/openldap/ldap.conf (который может храниться и в другом месте) строку "REFERRALS off". Это необходимо сделать для всех версий AD, начиная с Windows 2003 Server.

После подготовки можно переходить к практическому использованию ldapsearch.

Листинг 4. Пример использования ldapsearch

# ldapsearch -D ldapread@SHELTON.INT -w qwerty{123}              -LLL -h 192.168.50.1 -b dc=shelton,dc=int -P 3              -a always (sAMAccountName=ld*) distinguishedName sAMAccountType
dn: CN=LDAP Reader,CN=Users,DC=shelton,DC=int
sAMAccountType: 805306368

Использованные ключи имеют следующее значение:

  • -D задает значение bind dn;
  • -w - пароль для подключения;
  • -LLL обеспечивает максимальное упрощение выводимой информации;
  • -h - адрес сервера;
  • -b задает значение base dn;
  • -P - версия протокола LDAP;
  • -a описан в man ldapsearch.

Далее приводится простой фильтр отбора записей и перечень атрибутов, которые нужно вывести. Если ничего не указывать, то будут выведены все атрибуты. В данном случае мы запросили атрибуты distinguishedName иsAMAccountType. Обратите внимание, что атрибуты, которые необходимо вывести, перечисляются через пробел, а не через запятые. Теперь можно попробовать добавить в информацию о пользователе (средствами Microsoft) поле title, равное "Читатель" и запросить его через ldapsearch.

Листинг 5. Пример использования ldapsearch

# ldapsearch -D ldapread@SHELTON.INT -w qwerty{123}              -LLL -h 192.168.50.1 -b dc=shelton,dc=int -P 3              -a always (sAMAccountName=ld*) title sAmAccountType
dn: CN=LDAP Reader,CN=Users,DC=shelton,DC=net
title:: 0KfQuNGC0LDRgtC10LvRjA==
sAMAccountType: 805306368
//проверка
# echo 0KfQuNGC0LDRgtC10LvRjA== / mmencode -u / iconv -f utf-8 -t koi8-r
Читатель

Заключение

В статье был представлен краткий обзор протокола LDAP и утилиты ldapsearch, использующейся для выполнения запросов к LDAP-серверам. В следующей статье мы рассмотрим использование ldapsearch из сценариев Bourne Shell.


Страница сайта http://www.interface.ru
Оригинал находится по адресу http://www.interface.ru/home.asp?artId=29551