LDAP (Lightweight Directory Access Protocol) - Протокол Доступа к Директориям (каталогам), является протоколом, используемым для доступа к "Серверам Каталогов". Директория является специальной разновидностью базы данных, которая хранит информацию используя древовидную структуру.
Эта концепция аналогична структуре каталога на вашем жестком диске, за исключением того что в данном контексте корневой каталог рассматривается как "весь мир" а подкаталоги первого уровня как "страны". Более низкие уровни структуры директории содержат входы для компаний, организаций или мест, на уровне еще ниже находятся входы каталога для людей, и возможно для оборудования или документов.
Для ссылки на файл в подкаталоге на жестком диске используется нечто подобное
/usr/local/myapp/docs
Прямая косая черта отмечает каждый раздел в ссылке, а вся последовательность символов ссылки читается слева направо.
Эквивалентом полностью определенной ссылки в LDAP является "distinguished name" (различаемое имя), обозначаемое просто как "dn". Примером dn может быть:
cn=John Smith,ou=Accounts,o=My Company,c=US
Каждый раздел такой ссылки отмечается запятой, а вся последовательность читается справа налево. Ссылка читается как ..
country = US
organization = My Company
organizationalUnit = Accounts
commonName = John Smith
Так же как и при организации структуры каталога на жестком диске, в данном способе нет жестких правил по организации структуры, и менеджер сервера директории LDAP допускает любую структуру, подходящую для выбранной цели. Однако имеется ряд соглашений. Суть их в том, что вы не можете написать код доступа к серверу директории, не зная его структуры, так же как вы не можете использовать базу данных без представления о ее предназначении. Пример полной программы
Поиск информации для всех записей, где фамилия начинается с "S", в сервере директории, вывод на дисплей и извлечение с именем и email-адресом.
Пример 1. Пример поиска в LDAP <?php // базовая последовательность в LDAP это соединение, связь, // поиск, интерпретация поиска, результат, закрытие соединения echo "<h3>LDAP тест запроса</h3>"; echo "Соединение ..."; $ds=ldap_connect("localhost"); // должен существовать LDAP-сервер! echo "результат соединения ".$ds."<p>"; if ($ds) { echo "Установка связи ..."; $r=ldap_bind($ds); // это "anonymous" связь, обычно доступ // только для чтения, вывод "Результат связи.." echo "Результат связи ".$r."<p>"; echo "Поиск для (sn=S*) ..."; // Поиск записи с фамилией $sr=ldap_search($ds,"o=My Company, c=US", "sn=S*"); echo "Результат поиска ".$sr."<p>"; echo "Количество возвращенных записей ".ldap_count_entries($ds,$sr)."<p>"; echo "Получение записей ...<p>"; $info = ldap_get_entries($ds, $sr); echo "Данные для ".$info["count"]." объектов возвращены:<p>"; for ($i=0; $i<$info["count"]; $i++) { echo "dn is: ". $info[$i]["dn"] ."<br>"; echo "первая запись cn: ". $info[$i]["cn"][0] ."<br>"; echo "первая запись email: ". $info[$i]["mail"][0] ."<p>"; } echo "Закрытие соединения"; ldap_close($ds); } else { echo "<h4>Нет соединения с LDAP сервером</h4>"; } ?> |
Вам потребуется установить и скомпилировать библиотеки LDAP-клиента или из пакета University of Michigan ldap-3.3, или из Netscape Directory SDK. Вам также потребуется перекомпилировать PHP с поддержкой LDAP для того чтобы применение PHP LDAP вызовов стало доступным.
Прежде чем использовать LDAP вызовы, необходимо знать ..
Типичная последовательность LDAP-вызовов, которую вы можете применять в приложениях, представлена в следующем щаблоне:
ldap_connect() // установка
соединения с сервером
|
ldap_bind() // анонимный
или идентифицируемый "вход"
|
действия подобные поиску или обновлению
каталога
с выводом результата
|
ldap_close() // "выход"
Большое количество информации по LDAP может быть найдено:
Netscape SDK одержит полезное Руководство Программиста в .html формате.
ldap_add -- добавляет записи в LDAP каталог
int ldap_add
(целочисленный link_identifier, строковое dn,
массив записи);
возвращает true при успехе и false при ошибке.
Функция ldap_add() используется для добавления записей в LDAP каталог. DN добавляемой записи выражается посредством dn. Массив записи определяет информацию о записи. Значения записей индексируются посредством индивидуальных атрибутов. В случае множественных значений для атрибута, они индексируются целыми числами начиная с 0.
запись["атрибут1"] = значение
запись["атрибут2"][0] = значение1
запись["атрибут2"][1] = значение2
Пример 1. Полный прример с идентифицируемой связью <?php $ds=ldap_connect("localhost"); // проверка наличия LDAP сервера на хосте if ($ds) { // связь с подходящим dn для получения обновленного доступа $r=ldap_bind($ds,"cn=root, o=My Company, c=US", "secret"); // подготовка данных $info["cn"]="John Jones"; $info["sn"]="Jones"; $info["mail"]="jonj@here.and.now"; $info["objectclass"]="person"; // добавление данных в каталог $r=ldap_add($ds, "cn=John Jones, o=My Company, c=US", $info); ldap_close($ds); } else { echo "Нет соединения с LDAP сервером"; } ?> |
ldap_bind -- связь с LDAP каталогом
int ldap_bind
(целое link_identifier, строковое bind_rdn,
строковое bind_password);
Связь с LDAP каталогом с определенным RDN и паролем. Возвращает true при успехе и false при ошибке.
ldap_bind() осуществляет операцию связи с каталогом. bind_rdn и bind_password используются факультативно. Если не определено, применяется связь anonymous.
ldap_close -- закрывает связь с LDAP сервером
int ldap_close
(целое link_identifier);
Возвращает true при успехе, false при ошибке.
ldap_close() закрывает связь с LDAP сервером, которая ассоциировалась с определенным link_identifier.
Этот вызов внутренне идентичен ldap_unbind(). LDAP API использует вызов ldap_unbind(), поэтому возможно он предпочтительнее вызова ldap_close().
ldap_connect -- соединение с LDAP сервером
int ldap_connect
(строковое hostname, целое port);
Возвращает положительный LDAP идентификатор связи при успехе, false при ошибке.
ldap_connect() устанавливает соединение с LDAP сервером по определенным hostname и port. Оба аргумента факультативные. Если аргументы не определены, то будет возвращен идентефикатор уже открытого соединения. Если определено только hostname, то по умолчанию используется порт 389.
ldap_count_entries -- подсчет количества записей при поиске
int ldap_count_entries
(целое link_identifier, целое
result_identifier);
Возвращает количество записей в результате или false при ошибке.
ldap_count_entries() возвращает количество записей хранимых в результате от предыдущей операции поиска. result_identifier идентифицирует внутренний ldap результат.
ldap_delete -- удаляет запись из каталога
int ldap_delete
(целое link_identifier, строковое dn);
Возвращает true при успехе и false при ошибке.
ldap_delete() удаляет отдельную запись из LDAP каталога, определенную по dn.
ldap_dn2ufn -- конвертирует DN в User Friendly Naming формат
string ldap_dn2ufn
(строковое dn);
ldap_dn2ufn() преобразует DN в более дружественную для пользователя форму, удаляя имена типа.
ldap_explode_dn -- разбивает DN на составные части
array ldap_explode_dn
(строковое dn, целое with_attrib);
ldap_explode_dn() разбивает DN возвращаемое по ldap_get_dn() на составные части. Каждая часть известна как Relative Distinguished Name, или RDN. ldap_explode_dn() возвращает массив всех компонентов. with_attrib используется для запроса, возвращать ли RDN толъко со значениями или также с их атрибутами. Чтобы получить RDN-части с атрибутами (т.е. в формате атрибут=значение) установите with_attrib в 1, чтобы получить только значения установите его в 0.
ldap_first_attribute -- возвращает первый атрибут
string ldap_first_attribute
(целое link_identifier, целое
result_entry_identifier, целое ber_identifier);
Возвращает первый атрибут в записи при успехе и false при ошибке.
Подобно чтению записей, атрибуты также читаются один за другим из отдельной записи. ldap_first_attribute() возвращает первый атрибут в записи, отмеченной идентификатором записи. Оставшиеся атрибуты ищутся последовательными вызовами ldap_next_attribute(). ber_identifier является идентификатором указателя положения внутренней памяти. Он передается по ссылке. Аналогичный ber_identifier передается ldap_next_attribute() функции, которая изменяет этот указатель.
См. также ldap_get_attributes()
ldap_first_entry -- возвращает первый идентификатор (id) результата
int ldap_first_entry
(целое link_identifier, целое result_identifier);
Возвращает идентификатор записи для первой записи результата при успехе и false при ошибке.
Записи в LDAP-результате считываются последовательно с использованием функций ldap_first_entry() и ldap_next_entry(). ldap_first_entry() возвращает идентификатор записи для первой записи в результате. Этот идентификатор записи передается затем в процедуру lap_next_entry() для получения последовательных записей из результата.
См. также ldap_get_entries().
ldap_free_result -- освобождает память результата
int ldap_free_result
(целое result_identifier);
Возвращает true при успехе и false при ошибке.
ldap_free_result() освобождает внутреннюю память, предназначенную для хранения результата и отмечаемую посредством result_identifier. Вся память результата автоматически освобождается когда скрипт завершается.
Обычно вся память, выделяемая для ldap результата освобождается при окончании скрипта. В случае, когда скрипт выполняет последовательные поиски, которые возвращают большие наборы записей в результате, ldap_free_result() может быть вызвана для сохранения работоспособности оперативной памяти для следующей части скрипта..
ldap_get_attributes -- получает атрибуты записи в результате от поиска
array ldap_get_attributes
(целое link_identifier, целое
result_entry_identifier);
Возвращает полную информацию о записи в многоразмерном массиве при успехе и false при ошибке.
ldap_get_attributes() используется для упрощения чтения атрибутов и значений из записи в результате от поиска. Возвращаемым значением функции является многоразмерный массив атрибутов и значений.
Разместив определенную запись в каталоге, вы можете узнать какая информация хранится для этой записи, используя данный вызов. Вы могли бы использовать этот вызов в приложении которое "просматривает" каталог записей и/или когда вам не известна структура каталога записей. Во многих приложениях вы можете искать определенные атрибуты, такие как email-адрес или фамилия, не озадачиваясь при этом содержимым других данных.
return_value["count"] = количество
атрибутов в записи
return_value[0] = первый атрибут
return_value[n] = n-ый атрибут
return_value["attribute"]["count"] = количество
значений атрибута
return_value["attribute"][0] = первое значение
атрибута
return_value["attribute"][i] = i-тое значение
атрибута
Пример 1. Показывает список атрибутов отдельной записи каталога // $ds является идентификатором связи для каталога // $sr допустимый результат поиска от предыдущего вызова к // текущему при вызовах поиска по ldap каталогу $entry = ldap_first_entry($ds, $sr); $attrs = ldap_get_attributes($ds, $entry); echo $attrs["count"]." атрибуты для данной записи:<p>"; for ($i=0; $i<$attrs["count"]; $i++) echo $attrs[$i]."<br>"; |
См. также ldap_first_attribute() и ldap_next_attribute()
ldap_get_dn -- получает DN записи результата
string ldap_get_dn
(целое link_identifier, целое
result_entry_identifier);
Возвращает DN записи результата или false при ошибке.
ldap_get_dn() используется для нахождения DN записи в результате.
ldap_get_entries -- получает все записи результата
array ldap_get_entries
(целое link_identifier, целое
result_identifier);
Возвращает полную информацию о результате в многомерном массиве при успехе и false при ошибке.
ldap_get_entries() используется для упрощения чтения множества записей из результата и затем чтения атрибутов и множественных значений. Информация о записи возвращается по одиночному вызову функции в многомерном массиве. Структура массива представлена ниже.
Индекс атрибута преобразуется к нижнему регистру. (Атрибуты серверов каталогов нечувствительны к регистру, но не в том случае когда они используются в качестве индексов массива).
return_value["count"] = количество
записей в результате
return_value[0] : ссылается на детали первой записи
return_value[i]["dn"] = DN i-той записи в
результате
return_value[i]["count"] = количество атрибутов i-той
записи
return_value[i][j] = j-тый атрибут i-той записи
результата
return_value[i]["attribute"]["count"] = количество
значений атрибута в i-той записи
return_value[i]["attribute"][j] = j-тое значение атрибута в
i-той записи
См. также ldap_first_entry() и ldap_next_entry()
ldap_get_values -- получение всех значений из записи результата
array ldap_get_values
(целое link_identifier, целое
result_entry_identifier, строковое attribute);
Возвращает массив значений атрибута при успехе и false при ошибке.
ldap_get_values() используется для чтения всех значений атрибута в записи в данном результате. Запись определяется по result_entry_identifier. Количество значений может быть получено при индексации "счетчика" в результирующем массиве. Отдельные значения доступны по целочисленному индексу в массиве. Первый индекс начинается с 0.
Для данного вызова необходим result_entry_identifier, поэтому нужно предварительно сделать один вызов ldap поиска, и один из вызовов для получения отдельной записи.
Ваше приложение или может быть жестко настроено на поиск определенных атрибутов (таких как "фамилия" или "почта") или вы должны использовать вызов ldap_get_attributes() для получения информации о том, какие атрибуты существуют для данной записи.
В LDAP может быть более одной записи для атрибута, поэтому можно, например, хранить несколько адресов email в записи каталога для одной персоны, при этом все записи будут отмечены с атрибутом "mail"
return_value["count"] = количество
значений для атрибута
return_value[0] = первое значение атрибута
return_value[i] = i-тое значение атрибута
Пример 1. Список значений атрибута "mail" для записи каталога // $ds допустимый идентификатор связи для сервера каталога // $sr допустимый результат поиска от предыдущего вызова к // текущему при вызовах поиска по ldap каталогу // $entry допустимый идентификатор записи от предыдущего // вызова к текущему от вызовов возвращающих запись каталога $values = ldap_get_values($ds, $entry,"mail"); echo $values["count"]." email адрес для данной записи.<p>"; for ($i=0; $i < $values["count"]; $i++) echo $values[$i]."<br>"; |
ldap_list -- одноуровневый поиск
int ldap_list
(целое link_identifier, строковое base_dn,
строковое filter);
Возвращает идентификатор результата поиска или false при ошибке.
ldap_list() выполняет поиск с определенным фильтром по каталогу с областью LDAP_SCOPE_ONELEVEL.
LDAP_SCOPE_ONELEVEL означает что такой поиск может вернуть только информацию, находящуюся на уровне непосредственно ниже базового dn, заданного в вызове. (Эквивалентно вводу "ls" и получению списка файлов и папок в текущем рабочем каталоге).
Этот вызов берет факультативно четвертый параметр который является массивом требуемых атрибутов. См. примечание к ldap_search().
Пример 1. Составление списка всех подразделений организации // $ds допустимый идентификатор связи для сервера каталога $basedn = "o=My Company, c=US"; $justthese = array("ou"); $sr=ldap_list($ds, $basedn, "ou=*", $justthese); $info = ldap_get_entries($ds, $sr); for ($i=0; $i<$info["count"]; $i++) echo $info[$i]["ou"][0] ; |
ldap_modify -- изменение записи LDAP
int ldap_modify
(целое link_identifier, строковое dn, массив
entry);
Возвращает true при успехе и false при ошибке.
ldap_modify() используется для изменения существующих записей в каталоге LDAP. Структура записи такая же как и в ldap_add().
ldap_next_attribute -- получает следующий атрибут в результате
string ldap_next_attribute
(целое link_identifier, целое
result_entry_identifier, целое ber_identifier);
Возвращает следующий атрибут в записи или false при ошибке.
ldap_next_attribute() вызывается для поиска атрибутов в записи. Внутреннее положение указателя устанавливается по ber_identifier. Он посылается в данную функцию по ссылке. Первый вызов ldap_next_attribute() осуществляется с result_entry_identifier получаемым от ldap_first_attribute().
См. также ldap_get_attributes()
ldap_next_entry -- получает следующую запись в результате
int ldap_next_entry
(целое link_identifier, целое
result_entry_identifier);
Возвращает идентефикатор записи для следующей записи в результате, записи которого начинали считываться функцией ldap_first_entry(). Если больше нет записей в результате, то возвращается false.
ldap_next_entry() используется для поиска записей, хранящихся в результате. Последовательные вызовы ldap_next_entry() возвращают записи одну за другой пока не закончатся все записи. Первое обращение к ldap_next_entry() осуществляется после вызова ldap_first_entry() с параметром result_identifier, который возвращается от ldap_first_entry().
См. также ldap_get_entries()
ldap_read -- чтение записи
int ldap_read
(целое link_identifier, строка base_dn, строка
filter, массив [attributes]);
Возвращает идентификатор результата поиска или false при ошибке.
ldap_read() выполняет поиск при определенном фильтре по каталогу с областью LDAP_SCOPE_BASE. Таким образом, это эквивалентно чтению записи из каталога.
Пустой фильтр не допустим. Если вы хотите получить абсолютно всю информацию для данной записи, используйте фильтр "objectClass=*". Если вы знаете какие типы записей используются в сервере каталога, вы можете применить подходящий фильтр, такой как "objectClass=inetOrgPerson".
Этот вызов берет факультативно четвертый параметр который является массивом требуемых атрибутов. См. примечание ldap_search().
ldap_search -- поиск по дереву LDAP
int ldap_search
(целое link_identifier, строковое base_dn,
строковое filter, массив [attributes]);
Возвращает идентификатор результата поиска или false при ошибке.
ldap_search() осуществляет поиск для определенного фильтра по каталогу с областью LDAP_SCOPE_SUBTREE. Это эквивалентно поиску по всему каталогу. base_dn определяет базовый DN для данного каталога.
Имеется факультативный четвертый параметр, который может быть добавлен для ограничения атрибутов и значений возвращаемых сервером, если это требуется. Это значительно эффективнее чем действие по умолчанию (которое возвращает все атрибуты и их соответствующие значения). Использование четвертого параметра может поэтому рассматриваться как хорошая практика.
Четвертый параметр является стандартным строковым массивом PHP с требуемыми атрибутами, т.е. array("mail","sn","cn"). Заметим, что "dn" требуется всегда, независимо от того, какие типы атрибутов запрашиваются.
Отметим также, что некоторые хосты каталога сервера могут быть сконфигурированы так, что будут возвращать количество записей не превышающее предварительно установленное количество. Если это происходит, сервер будет показывать что он будет возвращать только ограниченные наборы результатов.
Поисковый фильтр может быть простым или расширенным, использующим булевы операторы в формате описанном в документации LDAP (См. Netscape Directory SDK для дополнения информации по фильтрам).
Приведенный ниже пример отыскивает the отдел организации, фамилию, данное имя и адрес email для всех людей в "My Company" где фамилия или данное имя содержат подстроку $person. Этот пример использует логический фильтр для указания серверу на поиск информации более чем в одном атрибуте.
Пример 1. LDAP поиск // $ds допустимый идентификатор связи сервера каталога // $person вся часть имени персоны, т.е. "Jo" $dn = "o=My Company, c=US"; $filter="(|(sn=$person*)(givenname=$person*))"; $justthese = array( "ou", "sn", "givenname", "mail"); $sr=ldap_search($ds, $dn, $filter, $justthese); $info = ldap_get_entries($ds, $sr); print $info["count"]." записей возвращено<p>"; |
Когда вы выполняете поиск, и слишком много данных возвращается (много записей) вы получите предупреждение, и ldap_get_entries() выдаст сбой. Рассматриваемый здесь прием должен выключить это предупреждение, потом проверить полученную запись.
$normerr = error_reporting ();
error_reporting (0); // выключает
предупреждение!
$sr = ldap_search ($ds, $dn, $searchfor);
$normerr = error_reporting ($normerr);
if (!$sr) {
print "слишком много записей!";
} else .....
Вы можете попробовать сузить эту область, добавив особый фильтр, т.е. (cn=a*), но было бы лучше иметь возможность захватить результаты в битах (т.е. 1-100, 101-200...).
ldap_unbind -- прекращение связи из каталога LDAP
int ldap_unbind
(целое link_identifier);
Возвращает true при успехе и false при ошибке.
ldap_unbind() прекращает связь из каталога LDAP.
Назад | Содержание | Вперед