Что такое код ldap_first_reference


Содержание

Linux.yaroslavl.ru

Учебник РНР
Назад Вперёд

ldap_first_entry — возвращает первый результирующий id.

Описание

resource ldap_first_entry (resource link_identifier, resource result_identifier)

Возвращает результирующий идентификатор первого вхождения при успехе, FALSE при ошибке.

Вхождения в LDAP-результате читаются последовательно с использованием функций ldap_first_entry() и ldap_next_entry() . ldap_first_entry() возвращает идентификатор вхождения для первого вхождения в результате. Этот идентификатор затем предоставляется утилите lap_next_entry() для получения последующих вхождений в результате.

XLIX. Функции LDAP

LDAP это Lightweight Directory Access Protocol — протокол, используемый для доступа к «Directory Servers». Directory это особый вид базы данных, которая содержит информацию как древовидную структуру.

Концепция аналогична структуре директорий жёсткого диска, но в данном контексте root/корневая директория это «The world/Земной шар», а первый уровень поддиректорий это «countries/страны». Ещё ниже идут уровни структуры директорий, содержащие вхождения для companies/компаний, organisations/организаций или мест, а ещё ниже находятся вхождения директорий для people/людей и, возможно, оборудования или документов.

Чтобы обратиться к файлу в поддиректории на жёстком диске, вы вводите что-нибудь вроде

Слэш отделяет каждое подразделение ссылки, а последовательность читается слева направо.

Эквивалентом для полной квалифицированной ссылки на файл в LDAP является «distinguished name/различительное имя», называемое просто «dn». Примером dn может быть:

cn=John Smith,ou=Accounts,o=My Company,c=US

Запятая работает как слэш, а последовательность читается справа налево. Вы можете прочитать это dn как .

country = US
organization = My Company
organizationalUnit = Accounts
commonName = John Smith

Точно так же, поскольку нет твёрдых правил организации структуры директорий на жёстком диске, directory server manager (менеждер сервера директорий) может настроить любую структуру, необходимую для осуществления поставленных задач. Однако есть некоторые соглашения, которые при этом используются: вы не можете записать код для доступа к серверу директорий, если не знаете его структуру, хотя можете использовать БД без знания того, что доступно.

Запрашиваем информацию для всех вхождений, где фамилия начинается с «S», с сервера директорий и отображаем их с именем и email-адресом.

Пример 1. Пример поиска LDAP

Вам нужно получить и скомпилировать клиентские библиотеки LDAP из пакета ldap-3.3 University of Michigan или Netscape Directory SDK 3.0. Вам нужно также перекомпилировать PHP с включённой поддержкой LDAP, прежде чем вызовы PHP к LDAP заработают.

Прежде чем начать использование вызовов LDAP, вам необходимо знать:


Имя или адрес сервера директорий, который вы будете использовать

«base dn» сервера (часть world-директории, которая содержится на этом сервере, которая может быть «o=My Company,c=US»)

Нужен ли вам пароль для доступа к этому серверу (многие серверы предоставляют доступ для чтения для «anonymous bind», но требуют пароля для других действий)

Типичная последовательность вызова LDAP в вашем приложении будет соответствовать такому патэрну:

ldap_connect() // установить соединение с сервером
|
ldap_bind() // anonymous/анонимный или аутентифицированный «login»
|
сделать что-нибудь типа поиска или обновления директории
и вывести результаты
|
ldap_close() // «logout»

Большое количество информации о LDAP можно найти на:

Netscape SDK содержит хороший Programmer’s Guide в формате .php.

Что такое код ldap_first_reference

LDAPMessage *ldap_first_entry(LDAP *ld , LDAPMessage *result );
LDAPMessage *ldap_next_entry(LDAP *ld , LDAPMessage *entry );
ldap_count_entries(LDAP *ld , LDAPMessage *result );
LDAPMessage *ldap_first_reference(LDAP *ld , LDAPMessage *res );
LDAPMessage *ldap_next_reference(LDAP *ld , LDAPMessage *res );
int ldap_count_references(LDAP *ld , LDAPMessage *res );

DESCRIPTION

These functions are used to parse results received from ldap_result(3LDAP) or the synchronous LDAP search operation functions ldap_search_s(3LDAP) and ldap_search_st(3LDAP).

The ldap_first_entry() function is used to retrieve the first entry in a chain of search results. It takes the result as returned by a call to ldap_result(3LDAP) or ldap_search_s(3LDAP) or ldap_search_st(3LDAP) and returns a pointer to the first entry in the result.

This pointer should be supplied on a subsequent call to ldap_next_entry() to get the next entry, the result of which should be supplied to the next call to ldap_next_entry() , etc. ldap_next_entry() will return NULL when there are no more entries. The entries returned from these calls are used in calls to the functions described in ldap_get_dn(3LDAP), ldap_first_attribute(3LDAP), ldap_get_values(3LDAP), etc.

A count of the number of entries in the search result can be obtained by calling ldap_count_entries() .

ldap_first_reference() and ldap_next_reference() are used to step through and retrieve the list of continuation references from a search result chain.

The ldap_count_references() function is used to count the number of references that are contained in and remain in a search result chain.

ERRORS

If an error occurs in ldap_first_entry() or ldap_next_entry() , NULL is returned and the ld_errno field in the ld parameter is set to indicate the error. If an error occurs in ldap_count_entries() , -1 is returned, and ld_errno is set appropriately. See ldap_error(3LDAP) for a description of possible error codes.

ATTRIBUTES

See attributes(5) for a description of the following attributes:

Что такое код ldap_first_reference

The ldap_first_reference function returns the first reference from a message.

Syntax

Parameters

The session handle.

The search result, as obtained by a call to one of the synchronous search routines or ldap_result.


Return value

If the search returned valid results, this function returns a pointer to the first result reference. If no entry or reference exists in the result set, it returns NULL. This is the only error return; the session error parameter in the LDAP data structure is cleared to 0 in either case.

Remarks

Use ldap_first_reference in conjunction with ldap_next_reference to step through and retrieve a list of continuation references from a search result chain.

The function returns subordinate referrals (references) that are returned in search responses. A subordinate referral is one in which the server has returned some data and the referral has been passed to other naming contexts below the current level in the tree. To step through external references in which the naming context does not reside on the server, use ldap_parse_result instead.

You do not have to explicitly free the returned reference as it is freed when the message itself is freed.

ldap_first_reference function

The ldap_first_reference function returns the first reference from a message.

Syntax

Parameters

The session handle.

The search result, as obtained by a call to one of the synchronous search routines or ldap_result.

Return Value

If the search returned valid results, this function returns a pointer to the first result reference. If no entry or reference exists in the result set, it returns NULL. This is the only error return; the session error parameter in the LDAP data structure is cleared to 0 in either case.

Remarks

Use ldap_first_reference in conjunction with ldap_next_reference to step through and retrieve a list of continuation references from a search result chain.

The function returns subordinate referrals (references) that are returned in search responses. A subordinate referral is one in which the server has returned some data and the referral has been passed to other naming contexts below the current level in the tree. To step through external references in which the naming context does not reside on the server, use ldap_parse_result instead.

You do not have to explicitly free the returned reference as it is freed when the message itself is freed.

2. Понятия и обзор LDAP

Если Вы уже понимаете, что из себя представляет LDAP, для каких целей он подходит, что такое схемы данных, объектные классы, атрибуты, правила соответствия, операционные объекты и вся эта кухня — можете пропустить этот раздел. Однако, если Вы собираетесь делать нечто большее, чем вслепую следовать рецептам HOWTO, Вы должны понимать все эти вещи.

LDAP и X.500 имеют много общих терминов, некоторые из них важны, некоторые — просто ерунда. Для Вашего удобства мы создали глоссарий. Термины в него включены либо потому, что они важны, либо потому, что они часто используются в литературе.

Небольшое замечание о чувствительности к регистру в LDAP: здесь есть некоторая путаница, по крайней мере, мы считаем это путаницей. По правде говоря, путаниц тут хватает на каждом шагу. Единственные чувствительные к регистру вещи в LDAP — это пароли и содержимое отдельных (очень малоизвестных) атрибутов, в зависимости от их правил соответствия. Всё. В этой и других документациях Вы будете встречать и objectclass, и objectClass, и даже ObjectClass. Все эти формы работают. Точка. После первых шести лет изучения LDAP (шутка, конечно, хватит и четырёх) Вы уже не будете хвататься за сердце всякий раз, когда Вам доведётся опечататься в каком-нибудь имени. Итак, использование «верблюжьей» нотации — это, возможно, и неплохая практика, но даже если Вы где-то ошибётесь, солнце не упадёт на землю.

О букве D в LDAP: официально буква D в аббревиатуре LDAP означает Directory (каталог) — Lightweight Directory Access Protocol. Связано это главным образом с историческими истоками LDAP (и его предшественника DAP), которые были ориентированы на взаимодействие с классическими приложениями для работы с каталогом адресов электронной почты типа «белые страницы». Однако, любая терминология в конечном итоге может начать загонять саму себя и тех, кто ею пользуется, в какие-то рамки. Не заблуждайтесь, рассуждая о LDAP, мы говорим о доступе к данным, и если термин Directory ограничивает Ваше мышление из-за существующих ментальных моделей каталогов (наше уж точно ограничивает, хотя, возможно, мы просто сами по себе умственно ограничены), то, размышляя о LDAP, просто мысленно заменяйте его термином Data (данные), и получится Lightweight Data Access Protocol. Только никому не говорите, а то прослывёте вероотступником.

2.1 Краткая история LDAP

Когда-то в тёмном и далёком прошлом (конец 70-х — начало 80-х) ITU (International Telecommunication Union) начал работу над почтовыми стандартами серии X.400. Для этого стандарта требовался каталог имён (и другой информации), который мог бы быть доступен по сети в иерархической манере, схожей с DNS (для тех из Вас, кто знаком с её архитектурой).

Эта потребность в глобальном сетевом каталоге сподвигла ITU к разработке стандартов серии X.500 и, в частности X.519, которые определяют DAP (Directory Access Protocol), протокол для доступа к сетевой службе каталогов.

Серии стандартов X.400 и X.500 разрабатывались как составная часть полного стека OSI и были большими, громоздкими и потребляли много ресурсов. Фактически, стандартная ситуация для ITU.

Перенесёмся в начало 90-х. IETF осознала необходимость доступа к глобальным службам каталогов (первоначально, во многом, по тем же самым причинам хранения адресов электронной почты, что и ITU), но не поднимая при этом всех этих ужасных перенагруженных протоколов (OSI), и начала работу над Lightweight Directory Access Protocol (LDAP). LDAP разрабатывался так, чтобы обеспечить почти столько же функциональности, что и оригинальный стандарт X.519, но с использованием стека протоколов TCP/IP, при этом оставляя возможность взаимодействия с каталогами, основанными на X.500. Действительно, взаимодействие с X.500 (DAP) и его отображение всё ещё является частью серии RFC о LDAP от IETF.

Большинство вопросов в спецификациях LDAP, вызывающих серьёзную головную боль, как раз связаны с обратной совместимостью с X.500 и концепцией глобальной службы каталогов. Самый показательный из них — соглашение об именовании корневой записи.

В широком смысле, LDAP отличается от DAP в следующих аспектах:

  1. В LDAP используется TCP/IP — DAP использует OSI в качестве транспортного/сетевого слоёв.
  2. Некоторое сокращение функциональности — неясные, дублирующиеся и редко используемые функции X.519 (конёк ITU) тихо и благополучно отброшены.
  3. Замена в LDAP некоторых из ASN.1-нотаций (X.519) текстовым представлением (LDAP URL и поисковые фильтры). В этом вопросе IETF не снискала нашей безграничной благодарности: значительное большинство ASN.1-нотаций всё ещё остаются в прежнем виде.

2.2 Обзор LDAP

Технически, LDAP — это всего лишь протокол, определяющий методы, посредством которых осуществляется доступ к данным каталога. Он также определяет и описывает, как данные представлены в службе каталогов (Модель данных или Информационная модель). Наконец, он определяет, каким образом данные загружаются (импортируются) и выгружаются (экспортируются) из службы каталогов (с использованием LDIF). LDAP не определяет, как происходит хранение и манипулирование данными. С точки зрения стандарта хранилище данных и методы доступа к нему — это «чёрный ящик», за который, как правило, отвечают модули back-end (механизмы манипуляции данными) какой-либо конкретной реализации LDAP (обычно в них используется некоторая форма транзакционной базы данных).

LDAP определяет четыре модели, которые мы перечислим и кратко обсудим, а затем Вы можете спокойно забыть о них, поскольку для понимания LDAP они мало что дают.

Информационная модель: мы склонны использовать термин модель данных, на наш взгляд он более интуитивный и понятный. Модель данных (или информационная модель) определяет, каким образом информация или данные представлены в системе LDAP. Это может совпадать или не совпадать с фактическим методом представления данных в хранилище на физическом носителе. Как упоминалось выше, вопрос хранилищ данных лежит за пределами стандартов LDAP.

Модель именования: определяет все вещи наподобие ‘dc=example,dc=com’, с которыми Вы сталкиваетесь в системах LDAP. Здесь мы максимально придерживаемся спецификации, поскольку эти термины используются очень широко.

Функциональная модель: при чтении, поиске, записи или модификации LDAP Вы используете функциональную модель — кто бы мог подумать!

Модель безопасности: Вы можете контролировать, причём весьма детально, кто, что и с какими именно данными может сделать. Это сложная, но мощная штука. Мы постепенно внедрялись в данную концепцию и посвятили ей отдельную главу. На начальном этапе можно забыть о безопасности. Вы всегда можете вернуться и модернизировать безопасность в LDAP. Если модернизация впоследствии будет невозможна, мы будем описывать реализацию безопасности по тексту. Эта модель также включает в себя защиту данных при передаче по сети, такую как TLS/SSL. Хорошая, но на редкость сложная штука.

Сфера стандартов LDAP показана на диаграмме ниже. Обозначенные красным вещи (1, 2, 3, 4) определены в протоколе (различных RFC, определяющих LDAP). Происходящее же в «чёрных ящиках» (или, в данном случае, в зелёных, жёлтых и сиреневых ящиках), а также показанное чёрной стрелкой обращение к базам данных (5) выходит за рамки стандартов.

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

LDAP не определяет, каким образом данные хранятся, только каким образом к ним осуществляется доступ. НО большинство реализаций LDAP используют стандартные базы данных в качестве механизмов манипуляции данными, и лишь OpenLDAP предлагает выбор поддерживаемых механизмов манипуляции данными.

Когда Вы общаетесь с сервером LDAP, Вы понятия не имеете, откуда поступают данные: на самом деле одна из ключевых задач стандарта — скрывать такой уровень детализации. Теоретически, данные могут поступать из одной ИЛИ НЕСКОЛЬКИХ локальных баз данных, либо одной или нескольких служб X.500 (в наши дни это большая редкость). Откуда и каким образом Вы будете получать данные — это детали реализации, они важны только на этапе определения рабочей конфигурации Вашего LDAP-сервера (серверов).

Две концепции, — доступ к службе LDAP и эксплуатация службы LDAP, — должны быть чётко разделены в Вашем сознании. Когда Вы проектируете каталог, сконцентрируйтесь на том, чего Вы хотите от него добиться, для чего он будет предназначен (организация данных) и не думайте о реализации. Затем, во второй фазе, во время составления рабочей конфигурации LDAP, сконцентрируйтесь на том, где данные будут располагаться, какие будут применяться системы хранения.

Ряд коммерческих продуктов баз данных предоставляет LDAP-представление (LDAP-обёртку или LDAP-абстракцию) реляционной базы данных или базы данных другого типа.

2.3 LDAP и базы данных

LDAP характеризуется как сервис «один раз записал — много раз прочитал». Другими словами, от данных, обычно хранящихся в каталоге LDAP, не ожидается, чтобы они менялись при каждом доступе. Для иллюстрации: LDAP не подходит для ведения учета банковских операций, так как они, по своей природе, изменяются почти при каждом доступе (бизнес-транзакции). С другой стороны, LDAP как нельзя лучше подходит для учёта различных аспектов деятельности банка, меняющихся значительно реже: списка отделений, часов работы, сотрудников и т.д.

Оптимизация на чтение

Во фразе «один раз записал — много раз прочитал» до конца не ясно, насколько много это много?

Где проходит грань разумного использования между LDAP и классическими, ориентированными на транзакции реляционными базами данных, к примеру, SQLite, MySQL, PostGreSQL? Если обновление происходит при каждом втором доступе, будет ли разумно использовать в таком приложении LDAP, или нужно, чтобы обновления происходили раз в тысячу или в миллион обращений?


Литература по этой теме крайне редка и имеет тенденцию придерживаться таких беспроигрышных LDAP-приложений, как адресные книги, которые изменяются, возможно, раз в столетие.

Простого ответа на этот вопрос нет, однако следующие замечания могут оказаться полезными:

Увеличение нагрузки при операциях записи происходит из-за обновления индексов. Чем больше индексов (для ускорения поиска), тем, по возможности, реже должны выполняться обновления каталога. Соотношение чтение:запись в хорошо оптимизированных на чтение каталогах должно быть 1000:1 и даже больше. Для умеренно оптимизированных каталогов (2-3 индекса) разумным будет соотношение 500:1 и выше.

Репликация LDAP генерирует несколько транзакций для каждого обновления, таким образом, желательно снизить практическую нагрузку, связанную с обновлениями (следует ориентироваться на соотношение чтение:запись 500:1 или выше).

Если объём данных велик (скажем, больше 100 000 записей), то даже при небольшом количестве индексов время обновления может быть значительным. Поэтому желательно снизить количество обновлений до минимально возможного (10 000:1 или выше).

Если объём данных относительно невелик (скажем, меньше 1000 записей, чего обычно хватает для большинства стандартных применений каталогов LDAP), индексов немного (не более 2-3) и отсутствует репликация, мы не видим рационального объяснения, почему Вы не можете использовать LDAP в форме, приближенной к транзакционной системе, то есть соотношение чтение:запись 5:1 или 10:1. При добавлении репликации более подходящим будет соотношение 50:1 или 100:1.

Мы полагаем, что настоящий ответ на этот вопрос (с уважением к памяти ушедшего от нас Douglas Noel Adams): оптимальное соотношение количества чтений к количеству записей составляет 42!

Представление организации данных

Применяемые для доступа к каталогам LDAP примитивы (элементы протокола LDAP) используют модель данных, которая (возможно) абстрагирована от её физической организации. Эти примитивы обеспечивают представление данных в виде объектной модели и не заботятся об актуальной структуре данных. В действительности, относительная простота LDAP происходит именно от этой характеристики. Конкретная реализация сервера LDAP будет выполнять отображение примитивов LDAP в физическую организацию данных, используя свой механизм манипуляции данными как «чёрный ящик» в чистом виде.

В этом резкий контраст со, скажем, SQL, поскольку в SQL-запросах, используемых для получения данных, присутствует полное и детальное представление структур данных, их организация в таблицы, объединения, наличие первичных ключей и т.д.

Синхронизация и репликация данных

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

Главный LDAP-сервер и подчинённые ему серверы (или равноправные ему серверы в среде с несколькими главными серверами (multi-master)) используют простой асинхронный процесс репликации данных. В связи с этим во время цикла репликации возможна рассинхронизация данных в главной и подчинённой (или равноправной) системах. Во время этого (обычно очень короткого) периода времени запрос к главному и подчинённому серверам может дать разные результаты. Если вследствие такого расхождения мир с треском расколется пополам, значит для подобного приложения LDAP не подойдёт. Если же Bob Smith на несколько секунд (или даже меньше) будет числиться в бухгалтерии на одном LDAP-сервере, а на другом — в отделе продаж, вряд ли это кого-то сильно огорчит. В эту категорию попадает удивительно большое количество приложений.

Примечание: Современные реализации LDAP, особенно те, которые поддерживают конфигурации с несколькими главными серверами (Multi-master), становятся всё более изощренными в репликации обновлений. Кроме того, высокоскоростные сети связи позволяют значительно быстрее выполнять операции репликации. Однако, подобные решения всего лишь уменьшают промежуток времени, в течение которого две какие-либо системы будут рассинхронизированы, они не устраняют саму природную особенность LDAP, заключающуюся в возникновении рассинхронизации, даже если в большинстве современных реализаций таковая длится всего лишь доли секунды.

2.3.1 Использование LDAP — резюме

Так в чём же преимущества LDAP (каталогов), и почему каждый здравомыслящий человек будет их использовать?

Прежде чем попытаться ответить на этот вопрос, давайте абстрагируемся от тактических соображений производительности. В целом, реляционные СУБД всё ещё значительно быстрее реализаций LDAP. По мере разработки служб каталогов второго поколения это положение меняется, и, хотя реляционные СУБД всегда будут оставаться быстрее LDAP, разрыв значительно сократился вплоть до точки, в которой различия становятся уже практически несущественными, если, конечно, Вы сравниваете подобное с подобным (единичные сетевые транзакции, а не обновление высокоиндексированного атрибута при каждой операции — в этом случае, не обессудьте, Вы получите (или не получите) ровно столько, сколько заслужили).

Так почему же нужно использовать LDAP? Вот наш список ключевых характеристик, которые делают высокий (всё ещё) уровень боли терпимым:

LDAP предоставляет стандартизированные как удалённый, так и локальный методы доступа к данным. Таким образом, вполне реально заменить одну реализацию LDAP на другую, совершенно не влияя на внешний интерфейс доступа к данным. Реляционные СУБД в основном реализуют стандарты локального доступа, такие как SQL, но удалённые интерфейсы всегда остаются проприетарными.

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

LDAP предоставляет метод, посредством которого данные могут быть перемещены (делегированы) в несколько мест, не затрагивая при этом внешнего доступа к этим данным. Используя метод отсылок LDAP, данные могут быть перемещены на альтернативные LDAP-серверы путём только изменения операционных параметров. Таким образом, можно построить распределенные системы, возможно, с данными, поступающими из отдельных автономных организаций, обеспечивая при этом для своих пользователей единое, последовательное представление этих данных.

Системы LDAP могут быть настроены на репликацию данных на один или несколько серверов LDAP или одному или нескольким приложениям только за счет операционных параметров, без необходимости добавления дополнительного кода или изменения внешнего доступа к данным.

Эти характеристики концентрируют внимание исключительно на стандартной природе доступа к данным LDAP, не учитывая отношения количества чтений к количеству записей, которое, как отмечалось выше, зависит от количества обслуживаемых операционных индексов. Они неявно сбрасывают со счетов использование систем LDAP для обработки транзакций, хотя есть тенденция, что некоторые реализации LDAP учитывают такие возможности.

2.4 Информационная модель (модель данных или объектная модель) LDAP

Каталоги LDAP используют модель данных, которая представляет данные как иерархию объектов. Это не означает, что LDAP является объектно-ориентированной базой данных. Как уже отмечалось выше, LDAP сам по себе является протоколом, позволяющим получить доступ к службам LDAP, и не определяющий, каким образом данные хранятся, — но операционные примитивы (чтение, удаление, модификация) работают с моделью (описанием/представлением) данных, имеющих (в основном) объектоподобные характеристики.

2.4.1 Структура дерева объектов

В этом разделе определяется сущность LDAP. Если Вы поймёте этот раздел и различные термины и отношения, с ним связанные, Вы поймёте LDAP.

В LDAP-системе данные представлены как иерархия объектов, каждый из которых называется записью. Полученная в результате древовидная структура называется Информационным деревом каталога (Directory Information Tree, DIT). Верхнюю часть данного дерева обычно называют корнем (root), (а также базой (base) или суффиксом (suffix)).

У каждой записи есть одна родительская запись (объект) и ноль или более дочерних записей (объектов). Каждая дочерняя запись (объект) является одноуровневой (братской) по отношению к другим дочерним записям своей родительской записи.

Каждая запись состоит из (является экземпляром) одного или нескольких объектных классов (objectClass). Объектные классы содержат ноль или более атрибутов (attribute). Атрибуты имеют имена (и, иногда, аббревиатуры или псевдонимы) и обычно содержат данные (наконец-то!).

Характеристики (свойства) объектных классов и их атрибутов описываются определениями ASN.1.

Уф! Теперь Вы знаете всё, что только можно знать о LDAP. Остальное — детали. Да, этих деталей, пожалуй, очень много. Но суть LDAP именно в этом.

Представленная ниже диаграмма иллюстрирует эти отношения:

Информационная модель (модель данных) LDAP DIT

Каждая запись (1) состоит из одного или нескольких объектных классов (2).

У каждого объектного класса (2) есть имя. Объектный класс представляет собой контейнер для атрибутов (в его определении идентифицируются атрибуты, которые он может или должен содержать).

У каждого атрибута (3) есть имя, он является членом одного или нескольких объектных классов (2) и содержит данные.

При наполнении DIT каждая запись будет уникально идентифицирована в иерархии (относительно своей родительской записи) данными, которые содержатся в этой записи (в атрибутах, которые содержатся в её объектном классе (классах)).

Теперь можно смело брать выходной на остаток дня и хорошенько отпраздновать!

2.4.2 Объектные классы

Объектные классы являются, по существу, контейнерами атрибутов. Они описываются с помощью определений ASN.1. У каждого объектного класса есть уникальное имя. Существует огромное число предопределённых объектных классов, в каждом из которых полным-полно атрибутов для почти всех возможных применений каталогов LDAP. Однако, само собой разумеется, что среди всех этих предопределённых объектных классов нет того, который Вам просто необходим! У объектных классов есть ещё три характеристики:

Объектный класс определяет, должен (MUST) ли входящий в него атрибут присутствовать в записи (обязательный атрибут), или он может (MAY) присутствовать (необязательный атрибут).

Каждый объектный класс принадлежит к определённому типу: он может быть структурным (STRUCTURAL), вспомогательным (AUXILIARY) или абстрактным (ABSTRACT) (детально эти типы описаны в следующей главе). На этом этапе достаточно знать, что в записи должен быть один и только один структурный (STRUCTURAL) объектный класс и может быть ноль или более вспомогательных (AUXILIARY) объектных классов.

Объектный класс может быть частью иерархии, в этом случае он наследует все характеристики своего родительского объектного класса (классов) (включая все содержащиеся в них атрибуты).

Объектные классы являются контейнерами и управляют тем, какие атрибуты могут быть добавлены к каждой записи. В целом же они, как правило, остаются вне поля зрения, когда речь идет о доступе и опросе (поиске) по DIT. Здесь на первый план выходят атрибуты и записи.

Больше (значительно больше) об объектных классах, — но только если Вы хорошо разобрались с данным материалом (в любом случае, мы будем разбираться с этим в следующей главе), — в противном случае продолжайте читать здесь.

Об уникальности: Каждое используемое в LDAP имя является уникальным. Имя каждого объектного класса уникально среди объектных классов, но на этом дело не заканчивается. Уникальное имя объектного класса (или имя любого другого элемента LDAP) также является глобально уникальным именем во всём LDAP. Например, существует объектный класс с уникальным именем person (с ним мы будем пересекаться позже), но это имя также является глобально уникальным именем во всём LDAP. Не существует атрибута (или любого другого элемента) с именем person.

2.4.3 Атрибуты

Каждый атрибут имеет имя (а также может иметь короткое имя или псевдоним) и обычно содержит данные. Атрибуты всегда связаны (являются членами) с одним или несколькими объектными классами. У атрибутов есть ряд интересных особенностей:

Все атрибуты являются членами одного или нескольких объектных классов.


Каждый атрибут определяет тип данных, которые он может содержать (ключевое слово SYNTAX в определении атрибута).

Атрибуты могут быть частью иерархии, в этом случае дочерний атрибут наследует все характеристики родительского атрибута. В данном случае иерархия атрибутов используется для упрощения и сокращения определений атрибутов (в ASN.1) там, где у нескольких атрибутов имеются одинаковые общие свойства, такие как максимальная длина, чувствительность/нечувствительность к регистру символов, или что-то ещё. Никакого другого смысла в иерархии атрибутов нет.

Атрибуты могут быть необязательными (ключевое слово MAY) или обязательными (ключевое слово MUST), согласно определениям ASN.1 того объектного класса, членами которого они являются. Атрибут может быть необязательным в одном объектном классе и обязательным в другом. Это свойство определяется в рамках объектного класса.

В разных местах этой документации в записях-примерах подобраны совершенно различные атрибуты, что может показаться путаницей. На самом же деле так происходит из-за необязательного характера большинства атрибутов. Это позволяет при составлении записей использовать подход «выбирай и соединяй»: находим нужный нам атрибут, находим объектный класс, членом которого является этот атрибут (таких классов может быть несколько), и надеемся, что все остальные атрибуты из данного объектного класса, которые мы не хотим использовать, окажутся необязательными! Чтобы яснее это себе представить, попробуйте посмотреть здесь.

У атрибутов может быть одно (SINGLE-VALUE) или несколько (MULTI-VALUE) значений (как описано в их определениях ASN.1). SINGLE-VALUE означает, что только одно значение данных может быть задано для этого атрибута. MULTI-VALUE означает, что этот атрибут может появляться в записи несколько раз с разными значениями данных. Если атрибут описывает, скажем, адрес электронной почты, может быть одно, два или 500 включений этого атрибута в запись, каждое с разным адресом электронной почты (атрибут многозначный (MULTI-VALUE)) — это один из ряда методов работы с почтовыми псевдонимами, применяемых при построении каталога. Значением по умолчанию для атрибута является MULTI-VALUE (что позволяет иметь несколько значений).

У атрибутов есть имя и, иногда, псевдоним (как описано в их определениях ASN.1), например, атрибут с именем cn является членом объектного класса, называемого person (и многих других), и имеет псевдоним commonName. Для ссылки на этот атрибут может использоваться как commonName, так и cn.

На всех уровнях иерархии данные, содержащиеся в каком-то из атрибутов, могут использоваться для однозначной идентификации записи. Это может быть любой атрибут в записи. Это может быть даже комбинация двух или более атрибутов.

Атрибут (атрибуты), выбранные для хранения данных, составляющих уникальность записи, иногда называются атрибутом (атрибутами) именования или относительным уникальным именем (Relative Distinguished Name, RDN) — но подробнее об этом в следующем разделе.

Взгляните на некоторые распространённые объектные классы и атрибуты. На данном этапе всё это выглядит очень страшно. Просто забудьте о том, что Вы только что видели, и продолжим чтение.

Больше (значительно больше) об атрибутах, — но только если Вы хорошо разобрались с данным материалом (в любом случае, мы будем разбираться с этим в следующей главе), — в противном случае продолжайте читать здесь.

2.4.4 Описание дерева путём добавление записей (данных)

В конце концов мы хотим поместить немного данных в наш каталог и использовать-таки эту замороченную штуку.

Описание древовидной структуры и первоначальное наполнение данными осуществляется путем добавления записей (с ассоциированными с ними объектными классами и атрибутами), начиная от корневой записи DIT и двигаясь вниз по иерархии. Таким образом, родительская запись всегда должна быть добавлена перед тем, как пытаться добавить дочерние записи.

Записи состоят из одного или нескольких объектных классов (единственного структурного объектного класса и нуля или более вспомогательных классов), которые выступают в качестве контейнеров для атрибутов. Именно атрибуты, а не объектные классы, содержат данные.

Ранее мы определили, что при создании/наполнении DIT каждая запись будет уникально идентифицироваться (относительно своей родительской записи) в иерархии. Единственным уникальным элементом любой структуры данных являются данные. Чтобы однозначно идентифицировать запись, нам нужно определить уникальные данные среди тех, которые содержатся в ней. Данные, содержащиеся в записи, определяются в атрибутах (присутствующих в объектных классах), таким образом, нам нужно определить атрибут, содержащий данные, являющиеся уникальными. Напомним, что многие атрибуты являются многозначными, — они могут присутствовать в записи несколько раз с разным содержимым, — поэтому для создания абсолютной, несомненной уникальности нам нужно определить сразу и атрибут, и содержащиеся в нём данные. Это делается с использованием формата имя_атрибута=значение_(или_данные), который в терминологии LDAP зовётся утверждением значения атрибута (Attribute Value Assertion, AVA).

Для иллюстрации, если в данной записи (на данном уровне иерархии) уникальными данными является слово fred (да-да, мы знаем, пример так себе, маловероятно, чтобы это слово было уникальным, но вдруг мы находимся в Узбекистане?), и оно содержится в атрибуте с именем cn, то нашим AVA (утверждением значения атрибута) станет cn=fred. В данном случае, если мы хотим пооригинальничать или нам просто некуда девать время, мы можем записать его иначе: commonName=fred (у атрибута cn есть псевдоним commonName).

Но вдруг так случится, что cn=fred не будет абсолютно уникальным (Кто там хихикает на заднем плане? Мы всё слышим!), а значит не сможет быть уникальным идентификатором для данной записи. Мы можем либо изменить выбранное нами значение (в записи может оказаться несколько значений cn=value, из которых мы можем выбрать), либо изменить выбранный нами атрибут (может неплохо подойти sn=de Gamma, если, конечно, мы не в Португалии). Кроме того, мы можем использовать второе AVA для обеспечения уникальности. В этом случае мы сохраним наше cn=fred, но добавим AVA drink=tamarind juice (внесём элемент экзотики в наши серые будни). Тогда уникальное значение будет записываться как cn=fred+drink=tamarind juice. Уникальней просто некуда.

Добавление записей может происходить разными путями, один из которых — использовать файлы формата LDAP Data Interchange Files (LDIF), который полностью описан в одной из последующих глав. Файлы LDIF — это текстовые файлы, описывающие древовидную иерархию — информационное дерево каталога (Directory Information Tree, DIT), и данные, добавляемые в каждый атрибут. Ниже приведён простой пример LDIF-файла, описывающий корневое DN (dc=example,dc=com) и добавляющий три дочернии записи в ветку people.

На данном этапе не так важно досконально разбираться во всех значениях этого LDIF-файла. В примерах главы 5 охвачены подробности настройки LDIF-файлов, а в главе 8 LDIF-файлы разъясняются в красочных деталях. На данном этапе достаточно знать, что LDIF-файлы могут использоваться для создания DIT и выглядят примерно так, как приведено ниже (данный LDIF создаёт DIT со структурой, приведённой на русинке 2.4.4-1).

Добавление LDAP-записей может быть также выполнено с помощью LDAP-клиентов, таких как LDAP-браузеры общего назначения (смотрите LDAPBrowser/Editor) или специализированные приложения.

Важное замечание: Строки в приведённом выше LDIF-файле, начинающиеся с ‘dn:’, по существу сообщают LDAP-серверу, каким образом структурировать или располагать запись в DIT (об этом в следующем разделе). В общем случае не важно, значение какого атрибута используется для этой цели, при условии уникальности ‘dn:’. В первой записи ВТОРОГО уровня (третьей записи LDIF-файла) приведённого примера для этой цели было выбрано «dn: cn=Robert Smith, ou=people, dc=example, dc=com». Точно также могло быть выбрано, скажем, «dn: u становится чрезвычайно важным и определяет идентификатор входа в систему (в качестве которого, как правило, используется uid), или, на жаргоне, DN подсоединения. Иногда (особенно в контексте LDAP, используемого в Microsoft AD) имя записи называется DN принципала (Principal DN), хотя этот термин не используется в определениях стандартов LDAP. Дополнительная информация по этой теме.

Если данное примечание кажется вам белибердой, можете пока забыть о нём. Позже мы это подробнейшим образом осветим.

Мы расскажем о LDIF-файлах позже, поскольку они нам ещё понадобятся, а приведённый выше LDIF определяет следующую структуру:

Рисунок 2.4.4-1: Структура DIT, созданная LDIF-файлом

После того, как DIT определён и запущен в работу, в дальнейшем информацию в него можно добавлять с помощью LDIF, LDAP-браузера, web-интерфейса или другого программного интерфейса.

Используя LDIF-файлы, данные также можно экспортировать (сохранить) в качестве резервной копии или для других целей.

2.4.5 Навигация по дереву

После того, как мы поместили данные в наше дерево (DIT), обычно самое время начать с ними работать!

Для этого мы должны посылать команды (на чтение, поиск, модификацию и т.д.) нашему LDAP-серверу, а чтобы сделать это, мы должны быть в состоянии сообщить LDAP-серверу, где находятся данные (для записи) или хотя бы где они примерно находятся (для поиска/чтения).

Короче говоря, мы должны осуществлять навигацию (ориентироваться) в каталоге.

Но для начала давайте введём ещё немного существенной терминологии.

В предыдущем разделе мы определили, что каждая запись должна быть уникально идентифицируемой (относительно своей родительской записи) с использованием одного (или нескольких) AVA (утверждений значения атрибута), например, cn=fred или, как в примере выше, cn=Robert Smith. Из правила, что каждое идентифицирующее AVA (или несколько AVA) должны быть уникальными (относительно родительской записи) в иерархии, следует, что путь к любой записи на любом уровне также должен быть уникальным (он представляет собой сумму индивидуально уникальных записей).

Терминология LDAP в области адресации заставляет задуматься об ограниченности английского языка. До сих пор для описания AVA записи мы использовали термин уникальное (unique), достаточно распространённое и понятное английское слово. Мы можем также сказать, что каждая запись имеет различное (different) имя. Кроме того (начинается!), мы можем также несколько извилисто выразиться, что, в силу своей уникальной идентификации, каждая запись отлична (distinguished) от своих соседей. Мы у цели! Основоположники служб каталогов в своей бесконечной мудрости решили использовать слово «Distinguished» («Отличительное», обычно в русскоязычной документации переводится как «Уникальное» — примечание переводчика).

Итак, AVA, например, cn=Robert Smith, уникально идентифицирующее запись, называется относительным уникальным именем (Relative Distinguished Name, RDN), то есть именем, уникальным по отношению к родительской записи. Путь от корневой записи DIT (она же базовая запись или суффикс) к данной записи представляет собой сумму всех RDN (соединённых через запятую (,) в порядке слева направо от младшей до старшей) называется уникальным именем (Distinguished Name, DN). Красота! Какими бы ни были Ваши взгляды на достоинства (или недостатки) LDAP и X.500, способность групп их стандартизации генерировать уникальную (или отличительную) терминологию не подлежит сомнению.

Для иллюстрации, в DIT из нашего примера путь от корневой записи до записи, уникально идентифицируемой AVA cn=Robert Smith, идёт от (RDN) dc=example,dc=com через (RDN) ou=people, и заканчивается на (RDN) cn=Robert Smith. Итоговое DN будет записываться как cn=Robert Smith,ou=people,dc=example,dc=com.

Три дополнительных момента, пока Вы ещё способны воспринимать информацию.

Напоминаем, что для создания уникального идентификатора можно применять несколько AVA, в этом случае RDN может выглядеть так: cn=Robert Smith + u >

DN записи ou=people: ou=people,dc=example,dc=com. DN описывает путь к любой записи в DIT.

В dc=example, dc=com, очевидно, два RDN (dc=example и dc=com). Это стандартная и легитимная конструкция (в дальнейшем мы её обсудим), используемая для определения корневой записи (она же базовая запись или суффикс). (Если Вы в настроении помудрствовать лукаво на эту тему, можно было бы назвать эту конструкцию много-RDN-ной RDN, но, честное слово, не стоит).

Для навигации по DIT мы можем задать путь (DN) к месту, где находятся наши данные (cn=Robert Smith, ou=people,dc=example, dc=com приведёт нас к уникальной записи), либо мы можем задать путь (DN) к месту, где, как мы предполагаем, находятся наши данные (скажем, ou=people,dc=example,dc=com), а затем выполнить поиск по паре или нескольким парам атрибут=значение, чтобы найти целевую запись (или записи). Если мы хотим выполнить изменения в каталоге (модификацию на жаргоне LDAP), как правило, следует указывать уникальную запись. Однако, если мы устраиваем DIT допрос с пристрастием, достаточно лишь примерной точности — мы получим всё, что соответствует критериям поиска.

Следующая диаграмма иллюстрирует DN и RDN:

2.5 Отсылки и репликация LDAP

Одним из наиболее мощных аспектов LDAP (и X.500) является вложенная в них способность делегировать ответственность за поддержание части каталога другому серверу, сохраняя при этом общую картину каталога как единого целого. Таким образом, можно создать в каталоге компании делегирование ответственности (отсылку (referral) в терминологии LDAP) той части всего каталога, в которой описан конкретный отдел, LDAP-серверу этого отдела. В этом аспекте LDAP почти полностью отражает концепцию делегирования DNS, если эта концепция Вам знакома.

В отличие от системы DNS, в стандартах не предусмотрена возможность сообщить LDAP-серверу проследовать по отсылке (разрешить отсылку), LDAP-клиенту оставлена возможность напрямую обращаться к новому серверу, используя возвращённую отсылку. Равным образом, поскольку в стандарте не определена организация данных LDAP, возможность перехода LDAP-сервера по ссылке (разрешение ссылки) не противоречит стандартам и некоторые LDAP-серверы выполняют эту функцию автоматически, используя процесс, обычно называемый сцеплением (chaining).

OpenLDAP буквально следует стандартам и по умолчанию не выполняет сцепление, а всегда возвращает отсылку. Однако OpenLDAP может быть настроен на выполнение сцепления с помощью директивы overlay chain.

Встроенная функция репликации LDAP позволяет создать одну или несколько подчинённых копий каталога (DIT) от одной главной (и даже, в некоторых реализациях, распространять изменения между несколькими главными копиями DIT), таким образом, по сути, создаётся устойчивая структура.

Важно, однако, подчеркнуть разницу между LDAP и транзакционными базами данных. При выполнении обновления в главном каталоге LDAP, для обновления подчинённых копий каталога (или других главных копий в конфигурации с несколькими главными серверами) может потребоваться некоторое время (в компьютерной терминологии) — главный и подчинённый каталоги (или разные главные каталоги в конфигурации с несколькими главными серверами) могут быть рассинхронизированы в течение какого-то периода времени.


В контексте LDAP, временное отсутствие синхронизации DIT считается несущественным. В случае же транзакционной базы данных, даже временное отсутствие синхронизации считается катастрофическим. Это подчёркивает различия в характеристиках данных, которые должны храниться в каталоге LDAP и в транзакционной базе данных.

Конфигурация репликации и отсылок рассматривается далее, а также в приводимых примерах.

2.5.1 Отсылки LDAP

Рисунок 2.5-1 демонстрирует поисковый запрос с базовым DN dn:cn=thingie,o=w >

Рисунок 2.5-1 — Запрос, удовлетворяемый только от LDAP1

Рисунок 2.5-2 демонстрирует поисковый запрос с базовым DN dn:cn=cheri,ou=uk,o=grommets,dc=example,dc=com к LDAP-системе с отсылками, ответ на который возвращается в результате серии отсылок к серверам LDAP2 и LDAP3, а LDAP-клиенты всегда следуют по отсылкам:

Рисунок 2.5-2 — Запрос, генерирующий отсылки к LDAP2 и LDAP3

  1. Все клиентские запросы начинаются с обращения к глобальному каталогу LDAP1.
  2. На сервере LDAP1 запросы любых данных, содержащие widgets в качестве RDN в DN, удовлетворяются непосредственно из LDAP1, например:
  3. На сервере LDAP1 запросы любых данных, содержащие grommets в качестве RDN в DN, генерируют отсылку на сервер LDAP2, например:
  4. На сервере LDAP2 запросы любых данных, содержащие uk в качестве RDN в DN, генерируют отсылку на сервер LDAP3, например:

Если LDAP-сервер сконфигурирован на выполнение сцепления (то есть на следование отсылкам, как показано альтернативными пунктирными линиями), то LDAP-клиенту будет отправлен один единственный ответ. Сцепление контролируется конфигурацией LDAP-сервера и значениями в поисковых запросах. Информация по сцеплению здесь.

На рисунках показано явное сцепление с использованием объектного класса referral. Серверы OpenLDAP могут быть настроены так, чтобы возвращать общую отсылку в случае, если запрашиваемый DN не был найден во время операции поиска.

2.5.2 Репликация LDAP

Функции репликации позволяют копировать обновления LDAP DIT на одну или несколько LDAP-систем в целях резервирования и/или повышения производительности. В этом контексте стоит подчеркнуть, что репликация работает на уровне DIT, а не на уровне LDAP-сервера, поскольку на одном LDAP-сервере может обслуживаться несколько DIT. Репликация происходит периодически, в течение промежутка времени, известного как время цикла репликации (по сути, это время, необходимое для отправки обновленных данных на сервер-реплику и получения подтверждения об успешном завершении операции). В общем случае, существуют методы уменьшения времени цикла репликации с помощью настроек, но обычно они приводят к снижению производительности или увеличению нагрузки на сеть. Исторически для выполнения репликации в OpenLDAP использовался отдельный демон (slurpd), но, начиная с версии 2.3, стратегия репликации коренным образом изменилась, были достигнуты серьёзные улучшения в гибкости и возможностях настройки времени цикла репликации. Существует два возможных типа конфигураций репликации, у каждого из которых есть несколько вариантов.

Главный-подчиненный (Master-Slave): В конфигурации главный-подчинённый обновляется одно единственное DIT (на жаргоне OpenLDAP оно называется главным (master) или поставщиком репликации (provider)), и эти обновления реплицируются или копируются на один или несколько указанных LDAP-серверов, на которых запущены подчинённые DIT (на жаргоне OpenLDAP они называются потребителями репликации (consumer)). Подчинённые серверы оперируют с доступной только для чтения копией главного DIT. Пользователи, которые выполняют только чтение, будут превосходно себя чувствовать, работая с серверами, содержащими подчинённые DIT, а пользователи, которым нужно вносить изменения в каталог, должны обращаться к серверу, содержащему главное DIT. При определённых условиях конфигурация главный-подчинённый позволяет существенно сбалансировать нагрузку. Однако, у неё есть два очевидных недостатка:

Если всем (большинству пользователей) дана возможность (требуется) вносить изменения в DIT, то либо им потребуется получать доступ к одному серверу (с подчинённым DIT) для осуществления чтения и к другому серверу (с главным DIT) для выполнения обновлений, либо они всегда будут обращаться к серверу, на котором запущено главное DIT. В последнем случае репликация выполняет только функцию резервного копирования.

Поскольку существует только один сервер, содержащий главное DIT, он представляет собой единую точку отказа для операций записи, которая может повлиять на работоспособность всей системы (хотя, в случае серьёзного сбоя, подчинённое DIT может быть переконфигурировано для работы в качестве главного).

Несколько главных (Multi-Master): В конфигурации с несколькими главными серверами могут обновляться несколько главных DIT, запущенных на одном или нескольких серверах, и результаты обновлений распространяются на другие главные серверы.

Исторически OpenLDAP довольно долго не поддерживал операции с несколькими главными серверами, но в версии 2.4 окончательно введены такие возможности. В этом контексте, наверное, стоит отметить две вариации общей проблемы конкуренции обновлений, специфичной для всех конфигураций с несколькими главными серверами. Эта проблема выявлена проектом OpenLDAP для своей конфигурации с несколькими главными серверами, но она относится ко всем системам LDAP:

Конкуренция значений. Если выполняется два обновления одного и того же атрибута в одно и то же время (в пределах времени цикла репликации) и при этом атрибуту назначаются разные значения, то, в зависимости от типа атрибута (SINGLE или MULTI-VALUED), результирующая запись может быть в неправильном или непригодном для использования состоянии.

Конкуренция удаления. Если один пользователь добавляет дочернюю запись в то же самое время (в пределах времени цикла репликации), когда другой пользователь удаляет оригинальную запись, то удалённая запись вновь появится.

Рисунок 2.5-3 показывает несколько возможных конфигураций репликации и объединяет их с отсылками из предыдущего раздела, чтобы показать всю мощь и гибкость LDAP. Следует отметить, что большинство конфигураций LDAP не настолько сложны.

Рисунок 2.5-3 — Конфигурации репликации

RO = только чтение, RW = чтение-запись

В случае LDAP1 клиент взаимодействует с подчинённой системой, доступной только для чтения. Для выполнения операций модификации (записи) клиенты должны обращаться к главной системе.

В случае LDAP2 клиент взаимодействует с главной системой, которая реплицируется на две подчинённые.

LDAP3 является системой с несколькими главными серверами и для выполнения операций чтения (поиска) и/или записи (модификации) клиенты могут обращаться к любому серверу. В данной конфигурации каждый главный сервер может, в свою очередь, иметь одно или несколько подчинённых DIT.

Глава 3 — Схема данных, объектные классы и атрибуты LDAP

Проблемы, комментарии, предположения, исправления (включая битые ссылки) или есть что добавить? Пожалуйста, выкроите время в потоке занятой жизни, чтобы написать нам, вебмастеру или в службу поддержки. Оставшийся день Вы проведёте с чувством удовлетворения.

Основы протокола LDAP: иерархия данных и компоненты записей

LDAP (или Lightweight Directory Access Protocol) – открытый протокол, используемый для хранения и извлечения данных из иерархической структуры каталогов. Обычно используется для хранения информации об организации и ее активах и пользователях. LDAP – это гибкое решение для определения любого объекта и его качеств.

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

Что такое служба каталогов?

Служба каталогов используется для хранения, организации и представления данных в формате «ключ-значение». Как правило, каталоги оптимизированы для операций поиска и чтения, а не записи, поэтому они очень хорошо работают с данными, на которые часто ссылаются, но меняют редко.

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

Что такое LDAP?

LDAP (или lightweight directory access protocol) – это протокол, который определяет методы, с помощью которых можно получить доступ к службе каталогов. В более широком смысле LDAP формирует способ отображения данных в службе каталогов для пользователей, определяет требования к компонентам, используемым для создания записей данных, и описывает способ использования разных примитивных элементов для составления записей.

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

Основные компоненты данных LDAP

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

Атрибуты

Сами данные в системе LDAP в основном хранятся в элементах, называемых атрибутами. Атрибуты – это в основном пары ключ-значение. В отличие от некоторых других систем, ключи – это предопределенные имена, которые продиктованы объектными классами записи (мы обсудим это немного позже). Кроме того, данные в атрибуте должны соответствовать типу, указанному в первоначальном определении атрибута.

Атрибут состоит из имени атрибута и значения, которые разделяются двоеточием и пробелом. Например, атрибут mail, который определяет адрес электронной почты, будет выглядеть так:

Когда речь идет об атрибуте и его данных, обе части соединяются знаком равенства:

Значения атрибутов содержат большинство фактических данных, которые нужно сохранить в системе LDAP. Другие элементы в LDAP используются для определения структуры, организации и т. д.

Записи

Атрибуты сами по себе бессмысленны. Чтобы иметь смысл, они должны быть связаны с чем-то. В LDAP атрибуты находятся внутри записи. Запись представляет собой набор атрибутов под описательным именем.

Например, в вашей системе может быть запись пользователя или запись для каждого элемента в инвентаре. Эти записи похожи на строки в реляционной базе данных или на странице в адресной книге (здесь атрибуты будут представлять различные поля). Хотя атрибут определяет качество или характеристику чего-либо, запись описывает сам элемент, просто собирая эти атрибуты в единое целое.

Запись, отображаемая в LDIF (LDAP Data Interchange Format), будет выглядеть примерно так:

dn: sn=Amber,ou=people,dc=8host,dc=com
objectclass: person
sn: Amber
cn: Justin Amber

Вышеприведенный пример может быть допустимой записью в системе LDAP.


Возможно, вы уже заметили, что данные, определенные атрибутами, представляют собой часть доступной информации об объекте. Остальное – это размещение записи в системе LDAP и отношения, которые она подразумевает.

Например, если возможно иметь записи для пользователя и для элемента инвентаря, как их отличить? Один из способов различать записи разных типов – это установить отношения и группы. Это по сути функция, где помещается запись при ее создании. Все записи добавляются в систему LDAP в виде веток в деревьях, называемых информационными деревьями каталога, или DIT.

DIT представляет собой организационную структуру, похожую на файловую систему, где каждая запись (отличная от записи верхнего уровня) имеет ровно одну родительскую запись и может содержать любое количество дочерних записей под ней. Поскольку записи в дереве LDAP могут представлять собой что угодно, некоторые записи будут использоваться в основном для организационных целей, аналогично каталогам в файловой системе.

Таким образом, у вас может быть запись people и отдельная запись inventoryItems. А фактические записи данных могут быть дочерними по отношению к ним, что позволит различать их тип. Ваши организационные записи можно произвольно определить для наилучшего представления ваших данных.

В примере, приведенном в предыдущем разделе, мы видим один признак DIT в строке dn:

Эта строка называется различительным именем записи (подробнее об этом позже) и используется для идентификации записи. Она функционирует как полный путь назад к root DIT. В этом случае есть запись sn=Amber. Прямым родителем является запись по имени ou=people, которая, вероятно, используется в качестве контейнера для записей, описывающих людей. Родители этой записи происходят из домена 8host.com, который функционирует как root DIT.

Компоненты данных LDAP

В последнем разделе мы обсудили, как данные представлены в системе LDAP. Однако также нужно поговорить о том, как определяются компоненты, хранящие данные. Например, ранее мы упоминали, что данные должны соответствовать типу, определенному для каждого атрибута. Откуда берутся эти определения? Давайте начнем с самых простых компонентов.

Определения атрибутов

Атрибуты определяются с помощью довольно запутанного синтаксиса. Они должны содержать имя атрибута, любые другие имена, которые могут использоваться для ссылки на атрибут, тип данных, а также множество других метаданных. Эти метаданные могут описывать атрибут, помогать сортировать или сравнивать значения атрибута и описывать, как он относится к другим атрибутам.

Например, это определение атрибута name:

attributetype ( 2.5.4.41 NAME ‘name’ DESC ‘RFC4519: common supertype of name attributes’
EQUALITY caseIgnoreMatch
SUBSTR caseIgnoreSubstringsMatch
SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 <32768>)

‘name’ – это имя атрибута. Число в первой строке – это глобальный уникальный идентификатор OID (Object ID), присвоенный атрибуту, чтобы отличать его от остальных атрибутов. Остальная часть записи определяет, как ее можно сравнивать во время поиска, и указывает, где найти информацию о типе данных атрибута.

Важной частью определения атрибута является то, может ли атрибут быть определен в записи более чем один раз. Например, фамилия может быть определена только один раз для каждой записи, но атрибут родства (например niece) может присутствовать в одной записи несколько раз. Атрибуты по умолчанию многозначны; если атрибут можно установить только один раз для каждой записи, он должен содержать флаг SINGLE-VALUE.

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

Определения ObjectClass

Атрибуты собираются внутри объектов, называемых objectClasses. ObjectClasses – это просто группы связанных атрибутов, которые были бы полезны при описании конкретной вещи. Например, «person» является objectClass.

Записи получают возможность использовать атрибуты objectClass, устанавливая специальный атрибут objectClass, который нужно использовать. Фактически, objectClass – единственный атрибут, который вы можете установить в записи без указания дополнительного objectClass.

Поэтому, если вы создаете запись для описания человека, в том числе objectClass person, вы можете использовать в нем все атрибуты:

dn: . . .
objectClass: person

Тогда у вас будет возможность установить эти атрибуты внутри записи:

  • cn: имя
  • description: удобочитаемое описание записи
  • seeAlso: ссылка на соответствующие записи
  • sn: фамилия
  • telephoneNumber: номер телефона
  • userPassword: пароль для пользователя

Атрибут objectClass можно использовать несколько раз, если вам нужны атрибуты из разных objectClasses, но есть правила, их использования.

Два основных типа ObjectClasses – это структурный и вспомогательный. Запись должна иметь ровно один структурный класс, но может иметь ноль или больше вспомогательных классов, используемых для расширения атрибутов класса. Структурный objectClass используется для создания и определения записи, в то время как вспомогательные objectClasses вносят дополнительную функциональность через новые атрибуты.

Определения ObjectClass указывают, требуются ли предлагаемые атрибуты (указывается спецификацией MUST) или их использовать необязательно (обозначается спецификацией MAY). Несколько objectClasses могут предоставлять одинаковые атрибуты, а атрибут MAY или MUST может отличаться.

Например, objectClass person определяется так:

objectclass ( 2.5.6.6 NAME ‘person’ DESC ‘RFC2256: a person’ SUP top STRUCTURAL
MUST ( sn $ cn )
MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )

Он определяется как структурный objectClass, что означает, что его можно использовать для создания записи. Созданная запись должна указывать атрибуты surname и commonname и может указывать атрибуты userPassword, telephoneNumber, seeAlso или description.

Схемы

Определения ObjectClass и определения атрибутов, в свою очередь, группируются в схемы. В отличие от традиционных реляционных баз данных, схемы в LDAP – это просто коллекции связанных объектов и атрибутов. Один DIT может иметь множество разных схем, чтобы создавать записи и атрибуты, которые ему нужны.

Схемы часто включают дополнительные определения атрибутов и могут потребовать атрибуты, определенные в других схемах. Например, objectClass person, о котором мы говорили ранее, требует, чтобы атрибут surname или sn были установлены во всех записях, которые используют objectClass person. Если они не определены на LDAP-сервере, схема, содержащая эти определения, может использоваться для добавления этих определений в словарь.

Формат схемы в основном представляет собой комбинацию указанных выше записей, например:

. . .
objectclass ( 2.5.6.6 NAME ‘person’ DESC ‘RFC2256: a person’ SUP top STRUCTURAL
MUST ( sn $ cn )
MAY ( userPassword $ telephoneNumber $ seeAlso $ description ) )
attributetype ( 2.5.4.4 NAME ( ‘sn’ ‘surname’ )
DESC ‘RFC2256: last (family) name(s) for which the entity is known by’ SUP name )
attributetype ( 2.5.4.4 NAME ( ‘cn’ ‘commonName’ )
DESC ‘RFC4519: common name(s) for which the entity is known by’ SUP name )
. . .

Организация данных

Мы рассмотрели общие элементы, которые используются для создания записей в системе LDAP, и узнали о том, как эти блоки определяются в системе. Теперь нужно посмотреть, как в LDAP DIT организована и структурирована информация.

Размещение записей в DIT

DIT – это просто иерархия, описывающая взаимосвязь существующих записей. При создании каждая новая запись должна «подключаться» к существующему DIT, помещая себя как дочерний элемент существующей записи. Это создает древовидную структуру, которая используется для определения отношений и присвоения значения.

Вершина DIT – это самая широкая категория, которая так или иначе является родительской для всех узлов. Как правило, самая верхняя запись просто используется как метка, указывающая организацию, для которой используется DIT. Эти записи могут быть представлены любыми объектными классами, но обычно они создаются с помощью компонентов домена (dc=example,dc=com для example.com), расположения (l=new_york,c=us) или организационных сегментов (ou=marketing,o=Example_Co).

Записи организации (папки) часто используют организационный объект object >

Именование и ссылки на записи в DIT

Мы ссылаемся на записи по их атрибутам. Это означает, что каждая запись должна иметь атрибут или группу атрибутов, которые однозначны на своем уровне в иерархии DIT. Этот атрибут или группа атрибутов называется относительным отличительным именем записи (или RDN) и функционирует как имя файла.

Чтобы однозначно сослаться на запись, используйте RDN записи в сочетании со всеми RDN-элементами своих родительских записей. Эта цепочка RDN возвращает к вершине иерархии DIT и обеспечивает однозначный путь к рассматриваемой записи. Эта цепочка называется отличительным именем записи (или DN). DN для записи указывается во время создания, чтобы система LDAP знала, где разместить новую запись (тогда RDN записи не будет использоваться другой записью).

Аналогично вы можете представить RDN как относительное имя файла или каталога в файловой системе. DN же больше похож на абсолютный путь. Важным отличием является то, что LDAP DN содержат наиболее специфическое значение в левой части, а пути к файлам – наоборот, в правой части. В DN значения RDN разделяются запятой.

Например, запись для человека по имени John Smith может быть помещена под записью «People» для организации example.com. Поскольку в организации может быть несколько человек по имени John Smith, ID пользователя может быть лучшим выбором для RDN записи. Запись может быть указана следующим образом:

dn: u > objectClass: inetOrgPerson
cn: John Smith
sn: Smith
uid: jsmith1

Здесь нужно использовать objectClass inetOrgPerson, чтобы получить доступ к атрибуту uid в этом экземпляре (у вас все еще есть доступ ко всем атрибутам, определенным в объекте personClass).

Наследование LDAP

В основном отношения данных в LDAP-системе определяются иерархиями, наследованием и вложенностью. LDAP изначально кажется сложным средством, потому что он реализует некоторые объектно-ориентированные концепции в своей структуре. Это главным образом связано с использованием классов и наследования, о чем мы поговорим сейчас.

Наследование objectClass


Каждый objectClass – это класс, который описывает характеристики объектов этого типа.

Однако, в отличие от простого наследования, объекты в LDAP могут быть и часто являются экземплярами нескольких классов (некоторые языки программирования предоставляют аналогичную функциональность посредством множественного наследования). Это возможно, потому что концепция LDAP класса – это просто набор атрибутов, которые он должен или может иметь (MUST или MAY). Это позволяет указать для записи несколько классов (хотя может и должен присутствовать только один objectClass STRUCTURAL), в результате чего объект просто имеет доступ к объединенной коллекции атрибутов с наивысшим объявлением MUST или MAY.

В своем определении objectClass может идентифицировать родительский objectClass, из которого можно наследовать его атрибуты. Это делается с помощью SUP, за которым следует objectClass для наследования. Например, objectClass organizationalPerson начинается следующим образом:

objectclass ( 2.5.6.7 NAME ‘organizationalPerson’ SUP person STRUCTURAL
. . .

Родительский objectClass следует за идентификатором SUP. Родитель должен использовать тип objectClass определяемого objectClass (например, STRUCTURAL или AUXILIARY). Дочерний objectClass автоматически наследует атрибуты и требования родительского.

При назначении objectClass нужно указать только конкретного потомка цепочки наследования, чтобы получить доступ ко всем атрибутам. В последнем разделе мы использовали это, чтобы указать inetOrgPerson как единственный objectClass для записи John Smith, все еще имея доступ к атрибутам, определенным в классах person и organizationPerson. Иерархия наследования inetOrgPerson выглядит следующим образом:

inetOrgPerson -> organizationalPerson -> person -> top

Почти все деревья наследования objectClass заканчиваются специальным objectClass под названием «top». Это абстрактный objectClass, единственная цель которого – потребовать, чтобы объект objectClass был установлен. Он используется для обозначения верхушки цепочки наследования.

Наследование атрибутов

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

Это часто используется для создания более конкретных версий общего атрибута. Например, surname является типом имени и может использовать все те же методы для сравнения и проверки равенства. Атрибут может наследовать эти качества, чтобы получить общую форму атрибута name. Фактически определение surname может содержать немного больше, чем указатель на родительский атрибут.

Наследование атрибута surname, которое мы обсуждали здесь, помогает людям различать фамилию и более общее имя, но помимо значения между фамилией и именем системы LDAP мало различий.

Варианты протокола LDAP

В начале мануала мы упоминали, что LDAP фактически является протоколом, который определяет интерфейс связи для работы со службами каталогов.

Стоит отметить некоторые варианты LDAP в обычном формате:

  • ldap://: Это базовый протокол LDAP, который позволяет осуществлять структурированный доступ к службе каталогов.
  • ldaps://: Этот вариант используется для поддержки LDAP по протоколу SSL/TLS. Обычный LDAP-трафик не зашифрован, хотя большинство реализаций LDAP поддерживают его. Этот метод шифрования соединений LDAP фактически устарел, и вместо этого рекомендуется использовать шифрование STARTTLS. Если вы работаете с LDAP по небезопасной сети, настоятельно рекомендуется перестать это делать и настроить шифрование.
  • ldapi://: Поддержка LDAP на IPC. Это часто используется для безопасного соединения с локальной системой LDAP в административных целях. Он связывается с внутренними сокетами вместо открытого сетевого порта.

Все три формата используют протокол LDAP, но последние два указывают дополнительную информацию о том, как именно он используется.

Заключение

Теперь вы знакомы с основами протокола LDAP и понимаете, как реализации LDAP представляют данные для пользователей. Зная, как элементы системы связаны друг с другом и где они берут свои свойства, вы сможете лучше разобраться с управлением и использованием систем LDAP.

Что такое код ldap_first_reference

The ldap_first_reference function returns the first reference from a message.

Syntax

Parameters

The session handle.

The search result, as obtained by a call to one of the synchronous search routines or ldap_result.

Return value

If the search returned valid results, this function returns a pointer to the first result reference. If no entry or reference exists in the result set, it returns NULL. This is the only error return; the session error parameter in the LDAP data structure is cleared to 0 in either case.

Remarks

Use ldap_first_reference in conjunction with ldap_next_reference to step through and retrieve a list of continuation references from a search result chain.

The function returns subordinate referrals (references) that are returned in search responses. A subordinate referral is one in which the server has returned some data and the referral has been passed to other naming contexts below the current level in the tree. To step through external references in which the naming context does not reside on the server, use ldap_parse_result instead.

You do not have to explicitly free the returned reference as it is freed when the message itself is freed.

Использование протокола LDAP в скриптах

Введение

Протокол LDAP (Lightweight Directory Access Protocol, упрощённый протокол для доступа к каталогу) служит для доступа к службам каталогов, в том числе Active Directory в Windows 2000/2003. Провайдер LDAP является одним из провайдеров ADSI (Active Directory Service Interface). Все примеры сценариев в настоящей статье будут приводиться на языке Python.

Служба каталогов Active Directory является LDAP-совместимой реализацией службы каталогов Microsoft для операционных систем семейства Windows и хранит информацию о сетевых ресурсах — пользователях, компьютерах, файлах, папках и принтерах, а также информацию безопасности, касающуюся этих ресурсов. Active Directory упрощает администрирование путём централизации управления. Домен — это логическая группа компьютеров и метод организации административной безопасности. Логическая структура Active Directory состоит из доменов, лесов и деревьев, а физическая структура состоит из серверов — контроллеров домена и сайтов (IP-подсетей). Active Directory использует модель репликации, когда копия каталога существует на каждом контроллере домена, что повышает отказоустойчивость (домен может содержать один или более контроллеров домена). Сайт (Site) Active Directory — это совокупность одной или нескольких IP-подсетей, объединенных высокоскоростными каналами связи. Сайт может содержать один или более доменов, а домен может быть размещен в нескольких сайтах. Сайты предназначены для управления репликацией Active Directory между сетями, соединёнными каналами связи с низкой пропускной способностью.

Домены в Active Directory организованы в иерархические структуры — деревья. Ветви такого дерева называются поддоменами. Имя дочернего домена включает имя родительского, например: microsoft.com, msdn.microsoft.com, vb.msdn.microsoft.com и т.д. Лес представляет собой группу деревьев, связанных доверительными отношениями — контроллеры домена в одном домене доверяют пользователям из другого домена (дают возможность использовать свои ресурсы). Отношения доверия транзитивны, то есть если домен А доверяет домену Б, а домен Б доверяет домену В, то домен А также доверяет домену В. Все деревья в лесу используют общую схему и общий глобальный каталог (Global Catalog, GC). Доверительными отношениями связываются корневые домены деревьев леса.

Схема (Schema) содержит формальное описание содержания и структуры хранилища Active Directory, включая все атрибуты, классы и свойства классов. Для каждого класса объектов схема определяет, какими атрибутами должен обладать экземпляр класса, какие дополнительные атрибуты он может иметь и какой класс объектов является предком текущего класса. При установке Active Directory создаётся стандартная схема, содержащая определения наиболее часто используемых объектов и их свойств, таких как пользователи, группы, компьютеры, принтеры и т.п. Схема Active Directory расширяема, т.е. вы можете определить новые типы объектов каталога и их атрибуты, в том числе и новые атрибуты для существующих объектов. Схема хранится вместе с данными Active Directory в глобальном каталоге и обновляется динамически (т.е. добавленные и изменённые атрибуты можно использовать практически сразу). Схема определяет структуру леса Active Directory, который может содержать несколько деревьев, которые, в свою очередь, могут содержать несколько иерархически структурированных доменов. В лесе Active Directory один из контроллеров объявляется мастером схемы (Schema Master) и отвечает за репликацию данных схемы на все контроллеры доменов. Cтруктурой леса и деревьев Active Directory является конфигурация (Configuration).

Глобальный каталог (Global Catalog, GC) — это центральное хранилище информации об объектах в дереве доменов и лесе Active Directory. Глобальный каталог является физическим хранилищем части атрибутов всех объектов леса Active Directory. Процесс частичной репликации позволяет находить большинство сведений непосредственно в глобальном каталоге, без обращения к исходному домену. По умолчанию в глобальном каталоге хранятся атрибуты, наиболее часто используемые при поиске (например имя пользователя, его учетной записи и т.п.), а также сведения, необходимые для обнаружения объекта (полный LDAP-путь к соответствующему объекту каталога). Хранение только основных атрибутов объектов в глобальном каталоге позволяет уменьшить его размер, поэтому один сервер глобального каталога может обслуживать много контроллеров домена Windows. При установке первого контроллера домена в лесу Active Directory он становится сервером глобального каталога. При наличии нескольких контроллеров домена можно перенести глобальный каталог на другой сервер или настроить несколько серверов на его поддержку.

В ADSI предусмотрен специальный провайдер «ADs», который возвращает ссылку на объект IADsNamespaces, который можно использовать для получения информации об установленных на компьютере провайдерах ADSI:

Корневой объект пространства имён провайдера LDAP (объект IADsNamespace) может быть получен следующим образом:

LDAP имеет иерархическую модель данных. Вы можете исследовать структуру ADSI с помощью оснастки ADSI Edit для MMC из пакета Windows Support Tools (пакет доступен для скачивания на сайте Microsoft). Для идентификации объектов существует два вида имен:

  • Отличительное (характерное) имя — Distinguished Name (DN).
  • Относительное отличительное (характерное) имя — Relatively Distinguished Name (RDN).

Отличительное имя объекта содержит полный путь к этому объекту в иерархии. Относительное отличительное имя объекта — часть отличительного имени, являющаяся именем объекта.

Кроме того, в каталоге существуют организационные блоки (организационные единицы или подразделения) Organization Units — OU, с помощью которых администратор каталога может создавать иерархию логических групп записей. Организационное подразделение — это контейнерный объект, предназначенный для группировки других объектов в логические административные группы в рамках домена. Организационные подразделения могут содержать такие объекты, как учетные записи пользователей, группы, компьютеры, принтеры и т.п. Иерархия организационных единиц домена не зависит от других доменов — каждый домен может поддерживать свою собственную иерархию. Часто групповые политики применяются именно к подразделениям (групповые политики сами являются объектами Active Directory).

Пользователь или группа имеет «дружественное» имя – основное имя пользователя (UPN – User Principal Name). Основное имя пользователя составляется из «сокращённого» имени пользователя и имени домена DNS, где находится объект, определяющий пользователя. UPN известны как адреса электронной почты. Например, пользователь James Smith в дереве microsoft.com может иметь UPN вида «JamesS@Microsoft.com».

Каждый объект каталога обладает глобальным уникальным идентификатором (Globally Unique Identifier, GUID) — 128-битным числом, генерируемым при создании объекта. GUID не изменяется в течение всего срока жизни объекта, даже при его переименовании или перемещении в другой домен. Поэтому приложения могут хранить GUID объекта и всегда однозначно находить его в каталоге.

Аббревиатуры, используемые в строках подключения (в так называемых URL LDAP):


  • OU — Organization Unit — организационный блок (организационная единица или подразделение), которая содержит такие объекты, как пользователи, контакты, группы и др.
  • CN — Common Name — общее (относительное) имя. Пользователь, контакт, группа или другой объект, который как правило не имеет дочерних объектов.
  • DC — Domain Component – компонент доменного имени.

Для связывания (определения) объекта с помощью технологии ADSI можно использовать два способа:

  • «Развёрнутая» форма:
  • «Сокращённая» форма:

Как видно из примеров, строки связывания в разных формах отличаются в основном направлением переходов по иерархии (вверх или вниз по иерархии). Примечание: порт можно указать только во второй форме, порт по умолчанию — 389.

Имя сервера (контроллера домена) и номер порта можно не указывать. В этом случае программные модули ADSI автоматически найдут контроллер домена для указанного вами домена и произведут к нему подключение с параметрами по умолчанию. При этом используются те же механизмы, что и при входе клиентского компьютера в сеть (такой вариант называется привязкой без сервера — serverless binding). Например:

Для просмотра атрибутов записи каталога можно связать запись, а затем использовать метод Get. Если сервер LDAP разрешает анонимный доступ к каталогу, можно использовать следующий подход:

Если сервер LDAP не разрешает анонимный доступ к каталогу, можно использовать следующий подход:

Для просмотра архитектуры существующего каталога LDAP используйте скрипт, приведённый чуть ниже. Изменяя отправную точку (startingPoint), можно просмотреть различные части каталога:

Рекурсивный просмотр архитектуры существующего каталога LDAP, вглубь от указанной отправной точки (startingPoint):

Специальный объект RootDSE (Root Directory Service Entry) автоматически вернёт имя того домена, к которому принадлежит данный компьютер:

Объект RootDSE предоставляет различную информацию о возможностях LDAP-сервера:

Поиск объектов в каталоге

В ADSI реализовано несколько технологий поиска. Основная технология связана с применением для этой цели возможностей объектной модели ADO. При этом подключение к службе каталогов производится при помощи объекта ADODB.Connection, формулировка текста запроса и его выполнение — при помощи объекта ADODB.Command, а результаты запроса возвращаются в виде обычного объекта ADODB.Recordset. Объектная модель ADO полностью поддерживает OLE Automation, поэтому эту технологию можно использовать из любых языков программирования, которые поддерживают OLE Automation, в том числе VBA, VBScript, JScript и т.п. Остальные технологии поиска ADSI могут использоваться в основном только из программ на языке C++, и здесь рассматриваться не будут.

Запросы к службам каталогов в ADSI могут выполняться на двух диалектах — диалекте LDAP (фильтры запроса определяются в соответствии с правилами синтаксиса запросов LDAP по RFC 2254) и диалекте SQL (фильтры запроса определяются в соответствии со стандартом ANSI SQL с учетом особенностей работы со службами каталогов).

Пример запроса на диалекте LDAP:

Первая часть запроса — базовое отличительное имя (base distinguished name) — использует синтаксис вида . Отличительное имя должно принадлежать контейнерному объекту, в котором производится поиск (обычно домену, сайту или организационному подразделению).

Вторая часть запроса (в примере — (object .

Третья часть запроса (в примере — AdsPath, cn) является набором атрибутов (столбцов), которые будут возвращаться в ходе выполнения запроса. Если необходимо вернуть несколько атрибутов для объекта, наименования атрибутов должны быть разделены запятыми.

Четвертая часть запроса (в примере — subTree) задаёт диапазон поиска. Возможные значения:

  • base — поиск производится только по одному объекту, указанному в первой части запроса. Всегда возвращается либо один объект, либо пустой набор объектов. По сути это проверка существования объекта;
  • onelevel — поиск производится только по непосредственным дочерним объектам контейнерного объекта, указанного в первой части запроса. Поиск по вложенным объектам более низких уровней производится не будет. В поиск не попадёт и сам контейнерный объект;
  • subtree — поиск будет производиться по всем объектам вниз по иерархии — глубокий поиск (deep search). В поиск при этом не попадает сам контейнерный объект.

Для поисковых фильтров LDAP предусмотрено два варианта синтаксиса. Первый вариант использует только один фильтр:

Второй вариант использует несколько фильтров, объединённых логическим оператором:

Операторы, используемые в фильтрах поиска LDAP:

=

= Равно.
Приблизительно равно.
= Больше или равно.
& И
| ИЛИ
! НЕ
* Групповой подстановочный символ (любое количество символов).

(object > Для атрибута objectClass может быть использовано любое значение (т.е. вернутся все объекты).
(&(objectCategory=person)(object > Несколько фильтров объединены при помощи оператора «И». Вернутся только те объекты, у которых одновременно: атрибут objectCategory имеет значение «person», атрибут objectClass — значение «user», атрибут cn — значение, не равное «andy».
(&(objectCategory=person)(object > Вернутся все объекты, у которых значение атрибута objectCategory равно «Person», objectClass — «contact», а значение атрибута sn равно либо «Lee», либо «Smith».

Для проверки наличия определенных флагов в атрибутах объектов применяется синтаксис с использованием так называемых объектных идентификаторов (object identifiers, OIDs). LDAP поддерживает два OID:

  • 1.2.840.113556.1.4.803 — совпадение будет признано только тогда, когда совпадут все биты в сравниваемых значениях (bitwise AND);
  • 1.2.840.113556.1.4.804 — совпадение будет признано в случае, если совпадет любой бит в сравниваемых значениях (bitwise OR).

Чаще всего OID используются при проверке флагов типов групп. Например, если необходимо найти все группы безопасности, но не группы распределения, синтаксис может быть таким:

Здесь число 2147483648 — это десятичное представление числа 0x80000000, которое соответствует флагу ADS_GROUP_TYPE_SECURITY_ENABLED в атрибуте groupType.

Некоторые символы в поисковых фильтрах являются зарезервированными и в значениях атрибутов должны заменяться на специальные последовательности:

* \2a
( \28
) \29
\ \5c
NUL \00
/ \2f

Пример скрипта, разыскивающего все объекты в домене, в имени которых используется прямой слеш:

Пример запроса на диалекте языка SQL к службе каталогов:

В разделе SELECT перечисляются атрибуты объектов Active Directory, которые будут возвращаться запросом. В результатах запроса они будут представлены полями объекта ADODB.Recordset. Несколько имен атрибутов должны разделяться запятыми. Вместо списка атрибутов можно использовать ключевое слово ALL или звездочку (*). Эти значения определяют, что должны вернуться все атрибуты.

В разделе FROM указывается отличительное имя базового объекта поиска (то есть того контейнерного объекта, начиная с которого будет производиться поиск). Этот путь обязательно должен быть заключен в одинарные кавычки.

В разделе WHERE указываются условия, поисковые фильтры, которые используются для выбора объектов при поиске. Синтаксис соответствует стандартам языка SQL.

В разделе ORDER BY указывается атрибут объекта службы каталогов, по значению которого будет производиться сортировка возвращаемых результатов. Active Directory поддерживает сортировку только по одному атрибуту. Однако можно указать порядок сортировки при помощи ключевых слов ASC и DESC (по умолчанию используется ASC).

Оператор JOIN в запросах к Active Directory не поддерживается (если запрос производится из SQL Server, а Active Directory используется в качестве внешнего источника данных, то можно производить JOIN между таблицами SQL Server и информацией, возвращаемой Active Directory).

Пример скрипта, разыскивающего все объекты в домене, в имени которых используется прямой слеш:

В случае необходимости подключения под конкретной учётной записью следует использовать строку подключения, аналогично следующему примеру:

Классы ADSI

Интерфейс IADs определяет набор базовых свойств и методов для любого объекта ADSI:

ADsPathЭто свойство возвращает отличительное имя объекта в Active Directory. Значение этого свойства может выглядеть по разному в зависимости от того, как именно получена ссылка на данный объект. Значение этого свойства выглядит как путь LDAP и может использоваться для получения этого объекта функцией GetObject.
ClassЭто свойство возвращает имя класса Active Directory, к которому принадлежит данный объект, согласно схеме Active Directory. Например, «domainDNS» или «user».
GUIDГлобальный уникальный идентификатор объекта Active Directory.
NameЭто свойство возвращает относительное отличительное имя данного объекта (relative distinguished name, RDN), например, «cn=TestUser1».
ParentЭто свойство возвращает значение свойства ADsPath родительского контейнера данного объекта.
SchemaЭто свойство возвращает ADsPath объекта в схеме Active Directory.
GetInfo()Этот метод позволяет заново получить в оперативную память компьютера, на котором создан объект ADSI, информацию о значениях свойств этого объекта с контроллера домена.
SetInfo()Этот метод записывает информацию об изменениях, произведённых с объектом ADSI в оперативной памяти, на контроллер домена, делая таким образом изменения постоянными. Фактически любая операция по внесению изменений в Active Directory средствами ADSI завершается вызовом метода SetInfo(). Контроллер домена по разным причинам может отказаться сохранять внесенные изменения (например, настроенный для пользователя пароль не соответствует парольной политике домена), поэтому лучше всего при вызове этого метода позаботиться об обработке ошибок.
Get()Этот метод, как и метод GetInfo(), обновляет кэш свойств, скачивая значения заново с контроллера домена. Однако GetInfo() обновляет значения всех свойств, а Get() — только указанного. Имя этого свойства передается в качестве параметра.
GetEx()Этот метод делает практически то же, что и метод Get(). Если для какого-то свойства предусмотрено единственное значение (например, строковое), метод Get() вернет просто это строковое значение. Если для этого свойства предусмотрено несколько строковых значений, метод Get() вернет массив строковых значений. Метод GetEx() всегда возвращает массив значений типа Variant, вне зависимости от того, было ли для свойства настроено одно значение или несколько. Поэтому метод GetEx() очень удобно использовать в ситуации, когда неизвестно, вернется одно значение или несколько.
GetInfoEx()Этот метод аналогичен методу GetEx(). Отличием является то, что метод GetEx() принимает в качестве параметра имя единственного свойства, а метод GetInfoEx() — массив с именами свойств. Соответственно, этот метод может обновить значения не для одного свойства, а для набора свойств.
Put()Этот метод позволяет присвоить значение свойству в кэше свойств для объекта ADSI в оперативной памяти. Чаще всего он используется в ситуации, когда объект ADSI только что создан и ещё не сохранен на контроллере домена (в этом случае прямое присвоение значения свойству вызовет ошибку). Потом при вызове метода SetInfo() настроенные значения свойств будут сохранены вместе с объектом в базе данных Active Directory. Обычно метод Put() используется только для присвоения значений обязательным свойствам, без которых сохранение объекта невозможно. Далее вызывается метод SetInfo(), и работа со значениями свойств идёт уже обычным порядком.
PutEx()Этот метод предназначен для тех же целей, что и метод Put(), но в качестве ещё одного параметра принимает информацию о том, что именно нужно сделать с указанным значением свойства (далее указаны значения перечисления ADS_PROPERTY_OPERATION_ENUM):

  • ADS_PROPERTY_CLEAR (1) — очистить данное свойство, убрав все его значения;
  • ADS_PROPERTY_UPDATE (2) — обновить значение для данного свойства, заменив его указанным новым значением;
  • ADS_PROPERTY_APPEND (3) — новое значение должно добавиться к уже существующим (если свойство поддерживает набор значений);
  • ADS_PROPERTY_DELETE (4) — указанное значение должно быть удалено из набора значений для данного свойства.

Интерфейс IADsContainer обеспечивает набор свойств и методов для контейнерных объектов Active Directory (в основном — объектов организационных подразделений и доменов):


Filter Это свойство позволяет настроить фильтр для элементов в данном контейнере. Элементы, которые не соответствуют данному фильтру, при работе с контейнером (переборе его элементов) будут игнорироваться. Это свойство в качестве значения принимает массив значений типа Variant с именами классов объектов Active Directory согласно схеме (например, «user», «computer» и т.п.).
Create() Этот метод позволяет создать новый элемент в данном контейнере. Он принимает два обязательных параметра: имя класса создаваемого объекта (например, «user’, «group», «organizationalUnit», «computer» и т.п.) и относительное отличительное имя для данного объекта (точно в таком же формате, в котором это имя возвращается при помощи свойства IADs.Name). Этот метод возвращает ссылку на созданный объект. Затем можно присвоить значение свойствам данного объекта (лучше при помощи метода IADs.Put(), чтобы гарантировать отсутствие ошибок) и сохранить созданный объект при помощи метода SetInfo().
Delete() Этот метод позволяет удалить элемент из данного контейнерного объекта. Он принимает в качестве параметров имя класса и относительное отличительное имя удаляемого объекта. Если класс в Active Directory уже отключен, вместо имени класса можно передать NULL.
GetObject() Этот метод позволяет вернуть ссылку на элемент в контейнерном объекте. В качестве параметров этот элемент принимает класс объекта и его относительное отличительное имя.
MoveHere() Этот метод позволяет переместить какой-либо элемент в данный контейнерный объект. В качестве параметров принимает полное отличительное имя существующего объекта и его новое относительное отличительное имя. Возвращает ссылку на интерфейс IADs для перемещённого объекта, которую можно использовать для дальнейшей настройки свойств объекта. Если переместить объект в тот же контейнер, в котором он уже находится, указав при помощи второго параметра новое имя, тем самым можно переименовать объект. При помощи этого метода можно перемещать в данный контейнерный объект как объекты из того же домена, так и объекты из других доменов данного леса. Однако для перемещения объектов из других доменов необходимо, чтобы домен назначения работал по крайней мере в режиме Windows 2000 Native, и перемещать можно только конечные объекты (например, объекты пользователей) или пустые контейнерные объекты (например, организационное подразделение, в котором нет никаких вложенных объектов). При перемещении объекта между доменами для объекта создается новый SID, а старый сохраняется при помощи атрибута SIDHistory. Явно предоставленные разрешения для пользователя при этом сохраняются, но теряется его членство в глобальных группах. Для перемещаемых объектов пользователей назначенные им пароли сохраняются.

Интерфейс IADsPropertyList предназначен для работы со свойствами объектов Active Directory. В принципе, работать со свойствами можно и без него (например, при помощи метода Put), однако средствами IADsPropertyList можно получить информацию о всех свойствах конкретного объекта, их типе и т.п. Использовать свойства и методы этого интерфейса можно только после того, как для соответствующего объекта Active Directory будет вызван метод IADs.GetInfo() или GetInfoEx(), или Get(), или GetEx().

Пример получения информации об имени, типе и значениях всех свойств объекта:

Свойства и методы интерфейса IADsPropertyList:

PropertyCount Это свойство интерфейса IADsPropertyList возвращает информацию о количестве свойств, предусмотренных для данного объекта.
GetPropertyItem() Этот метод позволяет вернуть свойство по его имени. В качестве параметров этот метод принимает имя свойства и его тип в виде значения перечисления ADSTYPEENUM (в нём предусмотрено 28 значений). Если тип свойства вам не известен, можно передать специальное значение ADSTYPE_UNKNOWN (26). Этот метод возвращает информацию в виде ссылки на объект IADsPropertyEntry, который можно использовать для получения информации о значении свойства.
Item() Этот метод отличается от метода GetPropertyItem() тем, что позволяет получить свойство (то есть объект IADsPropertyEntry) по имени или номеру. Тип свойства передавать при этом не надо.
Next() Этот метод позволяет вернуть следующее свойство в виде объекта IADsPropertyEntry. Обычно он используется для перебора всех свойств какого-либо объекта.
PurgePropertyList() Этот метод можно считать обратным методу IADs.GetInfo() — он очищает кэш свойств, удаляя из него информацию для всех свойств данного объекта. При этом сам объект Active Directory никак не затрагивается — этот метод работает только с представлением данного объекта в памяти. Обычно он используется, чтобы высвободить память на компьютере, на котором производятся операции с объектами Active Directory средствами ADSI.
PutPropertyItem() Этот метод позволяет присвоить новое значение свойству объекта Active Directory. По своим возможностям этот метод очень похож на метод Put() интерфейса IADs, и после его вызова необходимо вызвать метод IADs.SetInfo(). В качестве параметра метод PutPropertyInfo() принимает объект PropertyEntry, в котором должно быть задано новое значение для свойства.
Reset() Этот метод позволяет вернутся на начало списка свойств после вызова метода Next(), чтобы вернуться к исходному состоянию.
ResetPropertyItem() Этот метод позволяет удалить указанное свойство из кэша свойств. Этому методу можно передать как имя свойства, так и его номер. Этот метод используется только для экономии оперативной памяти, на сам объект Active Directory он никак не влияет.
Skip() Этот метод позволяет переместить курсор для списка свойств на указанное количество позиций. В качестве параметра этот метод принимает количество позиций, на которое следует переместиться. Обычно этот метод используется вместо метода Next() или вместе с ним для сокращения количества выполняемых операций.

Интерфейс IADsPropertyEntry предназначен для работы со значением (или значениями) свойства объекта Active Directory. Он может использоваться как для получения информации о значении свойства, так и для назначения свойству нового значения или значений. Свойства и методы:

NameИмя свойства, которое всегда соответствует наименованию соответствующего атрибута для объекта Active Directory согласно схеме.
ADsTypeТип свойства в соответствии со значением перечисления ADSTYPEENUM.
ControlCodeПозволяет определить тип операции, выполняемой со свойством. Возможные значения (перечисление ADS_PROPERTY_OPERATION_ENUM):

  • ADS_PROPERTY_CLEAR (1) — очистить объект свойства, убрав все настроенные для него ранее значения свойств;
  • ADS_PROPERTY_UPDATE (2) — заменить существующее значение свойства другим значением;
  • ADS_PROPERTY_APPEND (3) — добавить указанное значение к уже существующим;
  • ADS_PROPERTY_DELETE (4) — убрать ранее настроенное конкретное значение.

ValuesОпределяет значения для свойства. Свойство Values работает с массивом объектов типа Variant. Любой из объектов типа Variant, который находится в данном массиве, должен обязательно реализовывать интерфейс IADsPropertyValue.

Интерфейсы IADsPropertyValue и IADsPropertyValue2 используются непосредственно для работы со значениями свойств. Каждому объекту IADsPropertyValue соответствует конкретное значение свойства. Массив значений (то есть массив объектов IADsPropertyValue) передаётся при помощи свойства Values объекта IADsPropertyEntry.

Свойства и методы интерфейса IADsPropertyValue:

ADsType Это свойство позволяет определить тип данных для свойства в соответствии с набором значений, предусмотренных перечислением ADSTYPEENUM.
Clear() Этот метод позволяет очистить все значения, заданные ранее для объекта IADsPropertyValue.
DNString
CaseExactString
CaseIgnoreString
PrintableString
NumericString
Boolean
Integer
OctetString
UTCTime
LargeInteger
SecurityDescriptor
Эти свойства предназначены для работы с атрибутами соответствующих типов (в соответствии с перечислением ADSTYPEENUM). Попытка обращения к свойству несоответствующего типа вернёт ошибку. Если вам потребовалось выполнить какую-либо операцию со значением такого типа, который не представлен в этой таблице, интерфейс IADsPropertyValue для этой цели использовать будет невозможно. Вместо этого вам придётся воспользоваться интерфейсом IADsPropertyValue2.

Методы интерфейса IADsPropertyValue2:

GetObjectProperty() Этот метод позволяет получить значение атрибута объекта Active Directory. Он принимает единственный параметр: тип атрибута в соответствии с перечислением ADSTYPEENUM и возвращает значение этого атрибута при помощи типа данных Variant.
PutObjectProperty() Этот метод позволяет задать значение для атрибута объекта Active Directory. В качестве параметров он принимает тип атрибута в соответствии с перечислением ADSTYPEENUM и само значение (как Variant).

Значения перечисления ADSTYPEENUM:

ADSTYPE_INVALID
ADSTYPE_DN_STRING 1
ADSTYPE_CASE_EXACT_STRING 2
ADSTYPE_CASE_IGNORE_STRING 3
ADSTYPE_PRINTABLE_STRING 4
ADSTYPE_NUMERIC_STRING 5
ADSTYPE_BOOLEAN 6
ADSTYPE_INTEGER 7
ADSTYPE_OCTET_STRING 8
ADSTYPE_UTC_TIME 9
ADSTYPE_LARGE_INTEGER 10
ADSTYPE_PROV_SPECIFIC 11
ADSTYPE_OBJECT_CLASS 12
ADSTYPE_CASEIGNORE_LIST 13
ADSTYPE_OCTET_LIST 14
ADSTYPE_PATH 15
ADSTYPE_POSTALADDRESS 16
ADSTYPE_TIMESTAMP 17
ADSTYPE_BACKLINK 18
ADSTYPE_TYPEDNAME 19
ADSTYPE_HOLD 20
ADSTYPE_NETADDRESS 21
ADSTYPE_REPLICAPOINTER 22
ADSTYPE_FAXNUMBER 23
ADSTYPE_EMAIL 24
ADSTYPE_NT_SECURITY_DESCRIPTOR 25
ADSTYPE_UNKNOWN 26
ADSTYPE_DN_WITH_BINARY 27
ADSTYPE_DN_WITH_STRING 28

В интерфейсе IADsDomain реализованы свойства, обращаться к которым можно только через провайдер WinNT. Пример работы со свойствами объекта домена приведён в статье Введение в Active Directory Service Interface (ADSI): провайдер WinNT. Впрочем, можно работать через значения атрибутов и интерфейсы IADsPropertyList, IADsPropertyEntry, IADsPropertyValue.

Объект организационного подразделения реализует стандартные интерфейсы IADs, IADsContainer, IADsPropertyList, а также специализированный интерфейс IADsOU. Свойства IADsOU (например, BusinessCategory, Description, FaxNumber, LocalityName, TelephoneNumber) достаточно очевидны.

Объект группы поддерживает стандартные интерфейсы IADs и IADsPropertyList, а также специализированный интерфейс IADsGroup. Многие важные свойства групп (например, тип группы) через данный интерфейс недоступны и работать с ними нужно средствами интерфейсов IADsPropertyList, IADsPropertyEntry, IADsPropertyValue. Для атрибута groupType (тип группы) используются значения:

  • 1 — системная группа (такие группы создаются автоматически при создании домена, самостоятельно создать такую группу нельзя);
  • 2 — глобальная группа (по умолчанию);
  • 4 — доменная локальная группа;
  • 8 — универсальная группа;
  • 0x80000000 — группа безопасности. Это значение используется только в сочетании с другими значениями.

Свойства и методы интерфейса IADsGroup:

Description Это свойство представляет текстовое описание для данной группы.
Add() Этот метод позволяет добавить объект Active Directory (чаще всего учетную запись пользователя) в группу. Ему можно передавать путь в формате AdsPath или SID объекта в различных форматах.
IsMember() Этот метод позволяет проверить, является ли объект Active Directory членом данной группы и возвращает True или False. Учитывается только непосредственное членство: если, например, объект пользователя входит в глобальную группу, которая в свою очередь входит в локальную, то проверка членства для пользователя в локальной группе вернет False. Проверка может быть произведена только для объектов того же домена. Метод принимает в качестве параметра путь AdsPath или SID объекта (для провайдера WinNT проверка по SID не поддерживается).
Members() Этот метод возвращает коллекцию объектов Active Directory, которые являются членами данной группы (как Variant).
Remove() Метод, обратный методу Add(), позволяет удалить объект из группы. Этот метод принимает параметры в том же формате, что и метод Add().

Объект пользователя в ADSI поддерживает свойства и методы стандартных интерфейсов IADs и IADsPropertyList. Также для него реализован специализированный интерфейс IADsUser, в который сведены свойства для доступа к наиболее часто используемым атрибутам. Для объекта пользователя в Active Directory предусмотрено огромное количество атрибутов (несколько сотен), и для многих из них доступ возможен только через интерфейсы IADsPropertyList, IADsPropertyEntry, IADsPropertyValue (но не через IADsUser). Большая часть свойств (Department, Division, EmailAddress, FaxNumber, FirstName, FullName и т.п.) очевидна и комментариев не требует. Некоторые не самые очевидные свойства и методы:

AccountDisabled Это свойство определяет, отключена ли учетная запись. По умолчанию объект пользователя создается в отключенном состоянии. Для этого свойства используются значения True и False. Однако для атрибута UserAccountControl объекта пользователя в Active Directory, который соответствует этому свойству, предусмотрено несколько десятков значений. Значению False свойства AccountDisabled соответствует значение атрибута UserAccountControl 544, а значению True (то есть учетная запись отключена) — 546.
AccountExpirationDate Время и дата, когда учётная запись автоматически отключится. Обычно используется для временных сотрудников.
BadLoginAddress Информация о компьютере, с которого была произведена последняя попытка неудачного входа (с неверным паролем) для данной учётной записи. Эту информацию (свойство доступно только на чтение) можно использовать для обнаружения вторжений.
BadLoginCount Информация о количестве неудачных попыток входа (с неверным паролем) после последнего сброса счётчика.
GraceLoginsAllowed Информация о количестве входов в сеть, которые пользователь может произвести после того, как срок его пароля истек.
GraceLoginsRemaining Количество оставшихся входов в сеть для данного пользователя (когда срок действия пароля закончился).
IsAccountLocked Заблокирована ли учетная запись пользователя после превышения порогового значения неверных попыток входа. Это свойство доступно и на чтение, и на запись, поэтому его можно использовать для разблокирования учетной записи.
LastFailedLogin Информация о дате и времени последней неудачной попытки (по причине неверного пароля) входа пользователя. Можно использовать для расследования попыток вторжения.
LastLogin Информация о дате и времени последнего входа в сеть.
LastLogoff Информация о последнем выходе пользователя из сети (если этот выход был произведен корректно).
MaxLogins Информация о максимальном количестве пользователей, которые могут одновременно входить в сеть от имени данной учетной записи.
PasswordExpirationDate Дата и время, когда срок действия пароля данного пользователя истечет.
PasswordLastChanged Дата и время последнего изменения пароля.
PasswordMinimumLength Минимальная длина пароля в символах.
PasswordRequired Это свойство (доступное и на чтение, и на запись) позволяет определить, обязателен ли пароль для данного пользователя.
RequireUniquePassword Это свойство (доступное и на чтение, и на запись) позволяет определить, распространяются ли на данную учетную запись требования по уникальности пароля (то есть будет ли к нему применяться проверка истории паролей).
ChangePassword() Этот метод позволяет поменять пароль пользователя. В качестве параметров этот метод принимает старый пароль и новый пароль. Обычно этот метод используется для того, чтобы создать свой собственный интерфейс, при помощи которого пользователь сможет менять себе пароль.
SetPassword() Этот метод предназначен для администраторов и позволяет поменять пароль, не зная старого. В качестве параметра он принимает только новый пароль.
Groups() Этот метод позволяет вернуть коллекцию объектов групп, в которые входит данный пользователь. При этом системные группы (такие, как Domain Users) не учитываются.

Примеры

Просмотр атрибутов объекта:

Модификация атрибутов объекта:

Отображение всех объектов пользователей, групп или компьютеров указанного контейнера:

Просмотр всех обязательных свойств класса объекта (важно для создания объектов):

Что такое код ldap_first_reference

LDAP это Lightweight Directory Access Protocol — протокол, используемый для доступа к «Directory Servers». Directory это особый вид базы данных, которая содержит информацию как древовидную структуру.

Концепция аналогична структуре директорий жёсткого диска, но в данном контексте root/корневая директория это «The world/Земной шар», а первый уровень поддиректорий это «countries/страны». Ещё ниже идут уровни структуры директорий, содержащие вхождения для companies/компаний, organisations/организаций или мест, а ещё ниже находятся вхождения директорий для people/людей и, возможно, оборудования или документов.

Чтобы обратиться к файлу в поддиректории на жёстком диске, вы вводите что-нибудь вроде

Слэш отделяет каждое подразделение ссылки, а последовательность читается слева направо.

Эквивалентом для полной квалифицированной ссылки на файл в LDAP является «distinguished name/различительное имя», называемое просто «dn». Примером dn может быть:

cn=John Smith,ou=Accounts,o=My Company,c=US

Запятая работает как слэш, а последовательность читается справа налево. Вы можете прочитать это dn как .

country = US
organization = My Company
organizationalUnit = Accounts
commonName = John Smith

Точно так же, поскольку нет твёрдых правил организации структуры директорий на жёстком диске, directory server manager (менеждер сервера директорий) может настроить любую структуру, необходимую для осуществления поставленных задач. Однако есть некоторые соглашения, которые при этом используются: вы не можете записать код для доступа к серверу директорий, если не знаете его структуру, хотя можете использовать БД без знания того, что доступно.

Запрашиваем информацию для всех вхождений, где фамилия начинается с «S», с сервера директорий и отображаем их с именем и email-адресом.

Пример 1. Пример поиска LDAP

Вам нужно получить и скомпилировать клиентские библиотеки LDAP из пакета ldap-3.3 University of Michigan или Netscape Directory SDK 3.0. Вам нужно также перекомпилировать PHP с включённой поддержкой LDAP, прежде чем вызовы PHP к LDAP заработают.

Прежде чем начать использование вызовов LDAP, вам необходимо знать:


Имя или адрес сервера директорий, который вы будете использовать

«base dn» сервера (часть world-директории, которая содержится на этом сервере, которая может быть «o=My Company,c=US»)

Нужен ли вам пароль для доступа к этому серверу (многие серверы предоставляют доступ для чтения для «anonymous bind», но требуют пароля для других действий)

Типичная последовательность вызова LDAP в вашем приложении будет соответствовать такому патэрну:

ldap_connect() // установить соединение с сервером
|
ldap_bind() // anonymous/анонимный или аутентифицированный «login»
|
сделать что-нибудь типа поиска или обновления директории
и вывести результаты
|
ldap_close() // «logout»

Netscape SDK содержит хороший Programmer’s Guide в формате .html.

Илон Маск рекомендует:  Что такое код java_last_exception_clear
Понравилась статья? Поделиться с друзьями:
Кодинг, CSS и SQL