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

    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

    На этом, думаю, можно завершить статью. К сожалению, для наглядности пришлось перегнать код в изображения, местами не все влезало, поэтому знайте — на месте символа "\" в коде — был вынужденный перенос строки, которого быть не должно. Разумеется, могут встречаться помарки — результат моей неаккуратности, пишите об этом в комментариях, я исправлю.
    Целиком рабочий вариант кода я выкладываю вот тут, используйте его так, как посчитаете нужным :)
    За сим разрешите откланяться.

    Комментарии 13

      +2
      Для полного счастья не хватает в табличке еще номеров сотрудников, внутренних и внешних.
        0
        И… если в LDAP каталоге сотрудников… эдак… много-много. То что мы увидим? Длинный список на одной странице? (Так… мысли вслух)
          +2
          я не ставил перед собой цели сотворить код, который внедряется на предприятие методом ctrl+c & ctrl+v, это уже работа программиста-профессионала. я лишь показал метод, написал пример, вот и все.
            +1
            всех сотрудников можно раскидывать на разделы.
            тут все зависит уже от фантазии разработчика :)
              +1
              если это все локально просматривать, а не через тЫрнет — подойдет jQuery Tabledata, как наиболее простой способ не городить огорода на PHP. Если же вариант не подходит — городим примитивный класс\функцию для пагинашена… на вкус\цвет\коэффиЦент ленивости = )
              0
              дельная мысль. в АД с десяток возможных полей для телефонов, причем каждое, емнип, позволяет сохранять несколько значений.
              надо экспериментировать :)
                +1
                как раз по аналогичному способу делал в своей бывшей конторе телефонный справочник…
                web.chtp.net/temp/phone.jpg
                  0
                  я заметил, что у некоторых в карточке есть и ip — это просто справочная инфа, или вы использовали это поле для выдачи его по dhcp?
                    +1
                    в данном случае связка с ocs inventory
                    а почта — связка с mysql portfix'а
                0
                Подумывал об этом. Потестил несколько вариантов и получилось что проще всего просто адресную книгу почтового клиента привязать напрямую к AD или LDAP серверу. Налицо плюсы — поиск по адресной книге и автоматическое проставление адресата в письме.
                А php_ldap действительно хорошая штука, она у меня из AD имена людей таскает для lightsquid =)
                  0
                  Отличная идея выкладывать код как картинку, а на сырцы давать мертвую ссылку.
                    0
                    а вы на дату публикации топика смотрите перед попытками троллинга автора?
                    ссылку обновил. надеюсь, не зря.
                    0
                    Спасибо и за статью и за обновленную ссылку.

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

                    Самое читаемое