Perl для системного администрирования

       

Добавление элементов при помощи LDIF



Добавление элементов при помощи LDIF

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

LDIF, определенный в нескольких стандартах RFC предлагает простое текстовое представление для элементов каталогов. Вот простой пример LDIF из последнего чернового стандарта Гордона Гуда (Gordon Good):

version: 1

dn: cn=Barbara Jensen, ou=Product Development, ac=airius, dc=com

objectclass: top

objectclass: person

objectclass: organizationalPerson

en: Barbara Jensen

en: Barbara J Jensen

en: Babs Jensen

sn: Jensen

uid: bjensen

telephonenumber: +1 408 555 1212



description: A big sailing fan.

dn: cn=Bjorn Jensen, ou=Accounting, dc=airius, dc=com

objectclass: top

objectclass: person

objectclass: organizationalPerson

en: Bjorn Jensen

sn: Jensen

telephonenunber: +1 408 555 1212

Формат должен быть вам понятен. После номера версии LDIF перечислены DN-имена каждого элемента, определения objectclass и атрибуты. Разделителем элементов является пустая строка.

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

При обсуждении поиска в LDAP было показано, как вывести элементы в формате LDIF. Изменим код предыдущего примера так, чтобы он записывал данные в файл:

use Mozilla::LDAP::Conn: use Mozilla::LDAP::LDIF:

<выполняем связывание и поиск>

open(LDIF,">$LDIFfile1") or die ""Невозможно записать в SLDIFfile:$!\n": П создаем новый объект LDIF и передаем дескриптор Sldif = new Mozula: :LDAP: :LDIF(\*LDIF);

while (Sentry) (

$ldif->wr :reOneEntry($entry): Sentry = $c->nextEntry():

$c->close(); close(LDIF):

Модуль Mozilla: : LDAP располагает методом writeEntries(), позволяющим принять массив элементов и записать их подобным образом.

Используя Net: : LDAP, изменить первоначальную программу еще проще. Вместо:

$ldif = new Net::LDAP::LDIF("-"); применим:

Sldif = new Net::LDAP::LDIF($filename,"w");

для записи выводимых данных в указанный файл, а не на стандартный вывод.

Теперь совершим обратное действие и прочитаем файлы LDIF (вместо того, чтобы в них записывать). Методы объекта из модуля, о котором пойдет речь, позволяют легко добавить элементы в каталог.

При чтении LDIF-данных из Perl осуществляется процесс, обратный тому, который применялся в предыдущих примерах для записи. Каждый список элементов считывается и преобразуется в экземпляр объекта элемента, который затем передается соответствующему методу изменения каталога. Оба модуля считывают и анализируют данные, так что процесс довольно прост. Например, с использованием Mozilla I DAP можно написать такую программу:

use Mozilla::LDAP::Conn; use Mozilla::LDAP::LDIF;

Sserver = $ARGV[0];

SLDIFfile = $ARGV[1]

Sport = getservbynameC'ldap"."tcp") II "389"

Srootdn = "cn=Manager, ou=Systems, dc=ccs, dc-hogwarts, dc=edu"; $pw = "secret";

считываем файл LDIF, указанный втооым азгумо--о« в

и командной строке

open(LDIF,"SLDIFflie") or die "Невозможно отквыгь $LDIF*iie:$!\n";

Sldif = rew Mozilla::LOAP::LDIF(\*LDIF):

анализируем все элеменгь сохраняем их з 3ertri.es

Gentries = $ldif->readEnrnes():

close(LOIF):

tt неанонимное соединение

$c = new Mozilla::LDAP::Conn($server,$port.Srootdn,$pw);

die "Невозможно соединиться с $server\n" unless $c:

№ обходим в цикле список элементов, добавляя их на каждой итерации for (gentries)!

$c->add($_); ft добавляем этот элемент в каталог

warn "Ошибка при добавлении ". $_->getDN(),": ".$c->getErrorString()."\n"

if $c->getErrorCode(); } $c->close():

В этом примере отражено применение методов getErrorCodeO и getErrorString() для получения любых ошибок (и сообщения о них), происходящих в процессе загрузки данных. Ошибки могут появиться по целому ряду причин, включая дублирование DN/RDN-имен, нарушение схемы, проблемы с иерархией и т. д., так что очень важно проверить их при изменении элемента.

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

Для Net: : LDAP программа, добавляющая LDIF-элемент, выглядит таким образом:

use Net::LDAP;

use Net::LDAP::LDIF:

$server = SARGV[0]:

SLDIFfile = SARGV[1]:

Sport = getserveyfiaTiei. "Idap" 'tcu") || '389';

Srootdn = 'cn=Manager, ou=Systems. dc=ccs, dc="ogwarts. cc=ea^':

spw = ' secret ': П считываем файл LDIF. указанный вторым аргументом в 8 командной строк-з

» последний 'nipaw'-rp '>" для чтения, "w" для запис.' $ldif = пел Ne*' .'_CAP'-LDIF($LDIFfile. "r"): Gentries = $1(1:f >-^ad():

$с = new Net::LDAPfSserver, port => $por*) n<-

die "Невозможно соединиться с Sserver: $д'-п"

$c->bind(dn => $rootdn, password => $pw) or die л^'бка пр/ с-зязкаа-^:.- $@\n";

for (@entries)i

$res - $c->add($_):

warn "Ошибка при добавлении ". $_-^dri(). -.од ошибки ". $'ts->cudc?.

if $res->code(); }

$c->unbind();

Несколько замечаний к этому примеру:

  • При желании можно объединить два оператора чтения LDIF в одну строку:

gentries = new Net::LDAP::LOIF($LDIFflie."r")->read;

  • Если попытка add() не удалась, следует запросить десятичный код ошибки. Например, возможно такое сообщение:

Ошибка при добавлении cn=Ursula Hampster, oiJ=Almnn.i Association.

ou=People,

o=University of Michigan, c=US: код ошибки 68

Если сервер возвращает текстовое сообщение, метод его г () получает его так же, как это было в примере с Moziila: : LDAP:

print "Сообщение об ошибке: ".$res->error."\п":

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

  • 68 в десятичной системе счисления - ото 44 в шестнадцатеричной.

Теперь нам известно, что мы пытались добавить элемент из файла LDIF, который уже существовал в каталоге.



Содержание раздела