Работаем с AD на PHP

Чтение данных. Часть 2. Полноценный пример работы с AD

Comments

Серия контента:

Этот контент является частью # из серии # статей: Работаем с AD на PHP

Следите за выходом новых статей этой серии.

Этот контент является частью серии:Работаем с AD на PHP

Следите за выходом новых статей этой серии.

Для выполнения основных операций по работе с AD, таких как добавление или удаление пользователя, изменение данных или членства в группах, и в особенности для массовых операций (например, сформировать список всех пользователей по отделам) вовсе не обязательно изучать Visual Basic или PowerShell - для этого достаточно знания PHP (а также наличия пользователя с необходимыми правами).

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

  • AD - Active Directory (служба каталогов);
  • LDAP - облегченный протокол доступа к каталогу (lightweight directory access protocol);
  • DN - отличительное имя (distinguished name).

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

Основной скрипт

Скрипт начинается с вводной части, которая определяет места подгрузки функций, пути по умолчанию к файлам журнала и конфигурации, открывает файл журнала, читает и разбирает конфигурационный файл и опции командной строки. Конфигурационный файл разбирается функцией parse_config_file, размещенной в файле parseconfig.php и не приводимой здесь, но присутствующей в полной версии скрипта на [4]. Вводная часть программы приведена в Листинге 1.

Листинг 1. Вводная часть основного скрипта.
<?php
// Расположение файла журнала и конфигурационного файла
$logfile = "./ldaptest.log";
$config = "./ldaptest.conf";
// Путь к файлам функций
$PATH_LIB = "./lib";
require_once "Console/Getopt.php";
// В этом файле содержится опущенная нами функция разбора конфигурационного файла
require_once $PATH_LIB."/parseconfig.php";
require_once $PATH_LIB."/ldapdataquery.php";
function _usage($version) {
// эта функция опущена из-за ограниченного объема статьи
// она присутствует только в полной версии скрипта
 }
function parse_options(&$_config, &$_params) {
// Эта функция опущена из-за ограниченного объема статьи
// она присутствует только в полной версии скрипта
 }
// Параметры запуска программы
$_params = array( "modes" => array ( "debug" => 0,
                                     "clean" => 0,
                                     "verbose" => 0));
// Открыть файл журнала
$handle = fopen($logfile, "a") or die(sprintf("Log file %s cannot open", $logfile));
// Разобрать конфигурационный файл
$_config = parse_configfile($config);
// Разобрать опции командной строки
$rev = parse_options($_config, $_params);
// Началный запуск программы закончен
safe_logger(sprintf("PHPListADUsers ver. %s started", $rev), "");

Далее идет собственно чтение данных из LDAP - это самая короткая часть скрипта, потому что все делается функциями: подключиться, запросить, получить. Часть, в которой выполняется чтение данных, приведена в Листинге 2. Стоит обратить внимание на то, как строится массив атрибутов, которые будут прочитаны для передачи в ldap_data_query: если консоль поддерживает UTF-8, то параметр recode можно поставить в false.

Листинг 2. Чтение данных из LDAP-сервера.
// Подключиться к LDAP-серверу
if (!$ldapconn = ldap_server_connect($_config))
  safe_logger(sprintf("Cannot connect to LDAP server $s",
                                $_config["root"]["ldap_server"]), "DIE");
// Построить путь к выходном файлу
$_sarglist = sprintf("%s/%s", $_config["root"]["etcdir"],
                					$_config["root"]["sarglist"]);
// Счетчик обработанных записей
$_processed = 0;
// Из AD будут запрошены вот эти атрибуты
$attrs = array(0 => array("name" => "cn", "recode" => "true"),
               1 => array("name" => "samaccountname", "recode" => "true"));
// Получить данные из AD
$info = ldap_data_query($_config, $ldapconn, $attrs);

Далее идет чтение существующего файла, если он есть и его не надо удалять. Если файл существует, то он считывается, и из логинов, указанных в нем (первый столбец), формируется массив уже присутствующих в файле записей - для того, чтобы пропускать уже существующие. Часть, занимающаяся чтением файла, приведена в Листинге 3.

Листинг 3. Чтение существующего файла sarglist.
// Записи, которые уже есть в выходном файле
$presented = array();
// Удалить файл, если надо
if ($_params["modes"]["clean"])
  unlink($_sarglist);
// Если файл существует, то прочитать его
if (file_exists($_sarglist))
  {
    // Если существует, но не читается, аварийно завершить
    if (!is_readable($_sarglist))
      safe_logger(sprintf("File %s cannot open to read", $_sarglist), "DIE");
    // Получить данные существующего файла
    $lines = file($_sarglist);
    // Разбить каждую строку и выбрать логин
    foreach ($lines as $_oneline)
     {
       $pieces = explode(" ", $_oneline);
       $presented[] = $pieces[0];
     }
    // Вывести, сколько записей прочитано из файла
    safe_logger(sprintf("Read %d records from file %s",
                                        count($presented), $_sarglist),"");
  }

Ну и, собственно, основная часть скрипта - до этого, вообще говоря, все шла подготовка: получить данные из одного места, получить данные из другого... Каждая запись, прочитанная из AD, проверяется на наличие в файле, и если она там отсутствует, то в файле формируется новая запись с необходимыми данными, иначе же запись просто пропускается. В конце работы скрипт пишет, сколько он добавил записей, закрывает соединения и завершается. Основная часть скрипта приведена в Листинге 4.

Листинг 4. Основная часть скрипта.
// Основной цикл обработки - берется одна запись, полученная из AD и ищется в файле
// Если она уже есть - пропускается, иначе добавляется
$add = fopen($_sarglist, "a+")
  or safe_logger(sprintf("Sorry, I could not open file %s for writing",
                         $_sarglist), "DIE");
$ignored = explode(",", $_config["root"]["ignore_list"]);

for ($i = $_processed = 0, $j = count($info); $i < $j; $i++)
 {
   // Если логин отсутствует в файле и в списке игнорируемых
   if ((!in_array($info[$i]["samaccountname"], $presented)) &&
                (!in_array($info[$i]["samaccountname"], $ignored)))
     {
       // Вывести строку в файл
       $oneadd = sprintf("%s \t%s\n", $info[$i]["samaccountname"],
                                                        $info[$i]["cn"]);
       fwrite($add, $oneadd);
       $_processed++;
     }
  }
if ($_processed)
  safe_logger(sprintf("Added %d records in file %s",
                                        $_processed, $_sarglist), "");
ldap_unbind($ldapconn);
fclose($add);
fclose($handle);
?>

Заключение

Как совершенно очевидно, языки высокого уровня предоставляют несравнимо большее удобство при программировании взаимодействия с AD. Фактически все в данном скрипте сводится к манипулированию элементами массивов. И хотя PHP вовсе не считается языком для программирования консольных приложений, это может оказаться всего лишь предубеждением: вот вам вполне полноценная программа.


Ресурсы для скачивания


Похожие темы


Комментарии

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

static.content.url=http://www.ibm.com/developerworks/js/artrating/
SITE_ID=40
Zone=Linux, Open source
ArticleID=856601
ArticleTitle=Работаем с AD на PHP: Чтение данных. Часть 2. Полноценный пример работы с AD
publish-date=01292013