Pull to refresh

PHP: почтовая книга на лету из LDAP или Active Directory

Reading time3 min
Views17K
active directory logoВаша компания медленно, но верно выходит из кризиса, открываются новые офисы или магазины, появляются рабочие места — растет количество сотрудников. Вы, как системный администратор, уже позаботились об этом заранее и внедрили Active Directory или LDAP. Фух, проблем с учетками больше нет.
Но в нашем деле проблемы не заставляют себя долго ждать: вчера взяли пять бухгалтеров, троих продавцов и кладовщика. Всем нужна корпоративная электропочта. Отлично, если вы продумали достаточное количество ходов наперед и вместе с установкой AD перевели авторизацию почтосервера на домен. Тратим пять минут на добавление учеток, вписываем правильные данные, отдаем вашим помошникам — они настроят почтоклиенты этим сотрудникам. Но как теперь сообщить новые адреса всем остальным сотрудникам? Написать каждому письмо? Скинуть в чат? Слишком много работы для среднестатистического и вечно ленящегося сисадмина.

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

Познакомимся поближе с php-ldap


Условимся, что наш сайт написан на php, вебсервер имеет прямой доступ к серверу AD и на нем установлено расширение php-ldap.

Согласно мануалу, нам потребуется горстка функций. Это ldap_connect, ldap_bind, ldap_search, ldap_get_entries, ldap_unbind. Кроме того, для работы с AD нужно будет принудительно указать версию протокола, в этом нам поможет ldap_set_option.

Пишем фильтр


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

Раз. Мы строим онлайновую почтовую книгу, поэтому будем показывать только пользоваталей, другие объекты каталога нам не пригодятся.
(objectCategory=user)

Два. А я уже говорил, что это почтовая книга? Учетки без вписанных почтоадресов мы тоже показывать не будем.
(mail=*)

Три. Сотрудники имеют свойство увольняться, уходить в отпуск, декрет или на больничный. Такие учетки мы блокируем и показывать, как вы догадались, не станем.
(!(userAccountControl:1.2.840.113556.1.4.803:=2))

Четыре. Это необязательно, но полезно знать запись подобного фильтра. Я проверяю пользователей на членство в определенной группе (в примере это «web_mail_catalog»). Здесь ou=groups — organization unit, в котором обитает такая группа, а dc=mycompany,dc=crimea,dc=ua — запись имени домена.
(memberOf=cn=web_mail_catalog,ou=groups,dc=mycompany,dc=crimea,dc=ua)

Попробуем объединить все в одно целое. Запись получилась без пробелов, и я ее разбил на удобочитабельные кусочки.
(&
(mail=*)
(objectCategory=user)
(memberOf=cn=web_mail_catalog,ou=groups,dc=mycompany,dc=crimea,dc=ua)
(!(userAccountControl:1.2.840.113556.1.4.803:=2))
)

Определяемся с атрибутами


Теперь взглянем на каталог атрибутов (например, вот такой). Давайте прикинем, какие поля нам пригодятся. Я думаю, достаточно будет показать ФИО, почтоадрес, должность, отдел и название компании. Согласно таблице, это поля cn, mail, title, department и company.
Их чуть позже мы передадим как массив в качестве одного из аргументов функции ldap_search.

Начнем кодить


Нет, пожалуй, сначала включим индийскую музыку. Для мотивации. PHP — не мой конек, поэтому увлекаться с ООП и MVC я не буду. Желающие перепишут код так, как им заблагорассудится.

Обозначим пачку переменных, которые в дальнейшем будем использовать.
code1fr

Да, чуть не забыл. Вам предстоит создать отдельную учетку без прав, под которой в AD будет стучаться php-ldap. Кроме того, вы можете использовать префиксы в $srv — ldap:// или ldaps:// для обычного и зашифрованного общения. Насколько я помню, для ldaps AD понадобится ssl-сертификат.

Шагаем дальше. Фильтр и набор атрибутов — в такие же красивые переменные.
code2fr

Теперь неплохо бы подключиться к AD и выполнить вожделенный поиск.
code3fr

Скомпонуем и добавим немного html-обвязочки. Должно получиться что-то вроде этого.

code4fr

Настал момент истины: посмотрим, что у нас получилось.

code5fr

На этом, думаю, можно завершить статью. К сожалению, для наглядности пришлось перегнать код в изображения, местами не все влезало, поэтому знайте — на месте символа "\" в коде — был вынужденный перенос строки, которого быть не должно. Разумеется, могут встречаться помарки — результат моей неаккуратности, пишите об этом в комментариях, я исправлю.
Целиком рабочий вариант кода я выкладываю вот тут, используйте его так, как посчитаете нужным :)
За сим разрешите откланяться.
Tags:
Hubs:
Total votes 10: ↑5 and ↓50
Comments13

Articles