Добавление элементов при помощи 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, который уже существовал в каталоге.