В данной главе описываются различные методы импорта и экспорта записей LDAP и DIT целиком, используя либо LDIF, либо DSML.
Формат LDAP Data Interchange Files (LDIF) определён в RFC 2849, обновлён в RFC 4245 (поддержка инкрементной модификации).
Файлы LDIF используются в пяти основных случаях:
OpenLDAP предоставляет ряд инструментов для импорта и экспорта LDIF-файлов.
LDIF-файл представляет собой простой текстовый файл, который может быть создан и отредактирован с помощью любого текстового редактора. Поскольку каждая строка ограничивается ЛИБО <LF> (unix-формат), ЛИБО <CR><LF> (windows-формат), такие файлы могут быть созданы в любой операционной системе.
LDIF может быть довольно придирчив — наличие (или отсутствие) пробелов является особенно важным. Формат LDIF состоит из нескольких ТИПОВ СТРОК, часть из которых может содержать директивы LDIF. Строки могут быть организованы в последовательности ЗАПИСИ и последовательности ОПЕРАТОРА. Каждая строка ограничивается ЛИБО <LF> (unix-формат), ЛИБО <CR><LF> (windows-формат). Чтобы упростить дальнейшие объяснения, мы провели классификацию и дали названия ТИПАМ СТРОК. Этих названий мы будем придерживаться при последующем описании директив.
В этом разделе определена терминология, которую мы используем при описании LDIF-файлов. Эта терминология была создана для упрощения объяснения некоторых наиболее таинственных особенностей LDIF-файлов.
СТРОКА ДИРЕКТИВЫ (DIRECTIVE LINE) — это строка, которая начинается (первый символ в строке) с любого символа, ЗА ИСКЛЮЧЕНИЕМ ПРОБЕЛА или # (решётки).
СТРОКА ПРОДОЛЖЕНИЯ (CONTINUATION LINE) — это следующая за СТРОКОЙ ДИРЕКТИВЫ строка, которая начинается (первый символ в строке) С ПРОБЕЛА — последующие символы считаются частью предыдущей строки. Может быть любое количество СТРОК ПРОДОЛЖЕНИЯ, вплоть до предельного размера, установленного для атрибута.
ПУСТАЯ СТРОКА (BLANK LINE) — это строка без символов (обычно создаваемая клавишей ENTER). ПУСТЫЕ СТРОКИ обычно используются для разделения последовательностей ЗАПИСИ.
СТРОКА КОММЕНТАРИЯ (COMMENT LINE) — это строка, которая начинается (первый символ в строке) с символа # (решётка).
СТРОКА-РАЗДЕЛИТЕЛЬ (SEPARATOR LINE) — это строка, которая начинается (первый символ в строке) с символа — (тире). СТРОКИ-РАЗДЕЛИТЕЛИ обычно используются для ограничения последовательностей ОПЕРАТОРА.
Последовательность ЗАПИСИ (ENTRY sequence) — это группа директив, обычно начинающаяся с директивы dn:, каждая директива в которой применяется к одной и той же записи в DIT. Последовательность ЗАПИСИ обычно начинается и заканчивается ПУСТОЙ строкой.
Последовательность ОПЕРАТОРА — это группа директив, используемых с директивой changetype: modify, каждая директива в которой применяется к одной и той же операции add, delete или replace. Последовательность ОПЕРАТОРА обычно ограничивается либо строкой-РАЗДЕЛИТЕЛЕМ, либо ПУСТОЙ строкой.
Данный пример LDIF иллюстрирует создание DIT с помощью стандартного файла примера и показывает синтаксис, используемый чаще всего. Такие файлы обычно загружают с помощью утилиты ldapadd:
## DEFINE DIT ROOT/BASE/SUFFIX #### ## используется формат RFC 2377 ## замените встречающиеся ниже example и com на требуемые ## или, для экспериментов, оставьте как есть ## dcObject - это ВСПОМОГАТЕЛЬНЫЙ объектный класс и, кроме него, запись ## ДОЛЖНА иметь СТРУКТУРНЫЙ объектный класс (в данном случае, organization) # это последовательность ЗАПИСИ и ей предшествует ПУСТАЯ СТРОКА dn: dc=example,dc=com dc: example description: Моя замечательная компания. В эту строку можно поместить столько текста, сколько хотите в этой строке продолжение информации из предыдущей строки вплоть до 32Kb строка оканчивается либо на <CR>, либо на <CR><LF>, то есть отрабатывается ENTER с систем как Windows, так и *nix - новая строка ДОЛЖНА начинаться с ОДНОГО ПРОБЕЛА objectClass: dcObject objectClass: organization o: Example, Inc. ## ПЕРВЫЙ уровень иерархии - люди (people) ## для объектных классов используется смешанная форма записи в верхнем и нижнем регистре # это последовательность ЗАПИСИ, она должна предваряться ПУСТОЙ строкой dn: ou=people, dc=example,dc=com ou: people description: All people in organisation objectclass: organizationalunit ## ВТОРОЙ уровень иерархии ## ДОБАВЛЯЕМ одну запись в ПЕРВЫЙ уровень (people) # это последовательность ЗАПИСИ, она должна предваряться ПУСТОЙ строкой # ou: Human Resources - это название подразделения dn: cn=Robert Smith,ou=people,dc=example,dc=com objectclass: inetOrgPerson cn: Robert Smith cn: Robert J Smith cn: bob smith sn: smith uid: rjsmith userpassword: rJsmitH carlicense: HISCAR 123 homephone: 555-111-2222 mail: r.smith@example.com mail: rsmith@example.com mail: bob.smith@example.com description: swell guy ou: Human Resources
Примечания:
<предупреждение> В версиях данного руководства до 0.1.2 в приведённом выше примере мы некорректно определяли dn: dc=example,dc=com как dn: dc=example.com. Это успешно загружалось в OpenLDAP 2.0 и 2.1, но стало отклоняться в OpenLDAP 2.2 (ошибка 64). </предупреждение>
Записи при добавлении начинаются со строки, первыми символами которой являются 'dn:'. В общем случае, для этих целей может использоваться любой атрибут при условии соблюдения уникальности 'dn:', и, во избежание излишней нагрузки при поиске, обычно им становится наиболее часто используемый при доступе к записи DN. Поэтому в последней записи в приведённом выше LDIF используется значение cn=Robert Smith,ou=people,dc=example,dc=com, подразумевая, что cn= будет наиболее часто используемым DN при доступе к записям. Однако, если запись будет использоваться для аутентификации, то данный DN ДОЛЖЕН быть таким, чтобы его можно было использовать во время операций подсоединения. В этом случае более подходящими могут быть DN типа uid=rjsmith,ou=people,dc=example,dc=com. Поскольку для данного начального DN (или DN 'создания') нет специального термина в стандартах LDAP, то, при использовании в целях идентификации, он иногда называется DN принципала (Principal DN). Дополнительная информация по этой теме.
Для упрощения описания некоторых концепций LDIF мы используем некоторые введённые нами термины.
Как упоминалось в комментариях, директива version: не является строго обязательной. Если она присутствует, то (в настоящий момент) она должна быть установлена в 1 для указания версии 1 формата LDIF. Данная директива была включена (сейчас её нет, но в первоначальной версии примера она была, так что поверьте на слово) просто потому, что делать это полезно (Good Thing™). Будущие версии могут быть несовместимы, либо могут налагать более строгие требования к корректности — лучше сразу вырабатывать хорошие привычки. Во время нашего тестирования мы заметили, что некоторые особо бестолковые версии OpenLDAP могут приводиться в ступор директивами version, выдавая сообщения об ошибках с предположениями об отсутствии DN, поэтому мы просто удалили строку version.
Комментарии обозначаются # только в первом символе строки. В следующей строке # интерпретируется как содержимое:
cn: my name #this is my name
В результате атрибут cn будет содержать 'my name #this is my name'.
Между записями должна быть КАК МИНИМУМ одна ПУСТАЯ строка (перед строками, начинающимися с dn:). Это ОЧЕНЬ важно — в противном случае могут возникать странные ошибки.
Предполагается, что строка является строкой ПРОДОЛЖЕНИЯ, если предыдущая строка оканчивается разделителем строк (<CR> или последовательностью <Cr><LF>), а текущая начинается РОВНО С ОДНОГО ПРОБЕЛА.
В именах атрибутов в приведённом выше файле непоследовательно используются символы в верхнем и нижнем регистрах — в частности, эта ужасная псевдовенгерская нотация (она же CamelCase или "ГорбатыйРегистр") objectClass или все буквы в нижнем регистре objectclass. Работает и то, и другое. Следуйте любому стилю на Ваш выбор.
Строка cn: bob smith содержит несколько кажущихся ошибок. Здесь есть два пробела между 'bob' и 'smith' и оба они в нижнем регистре. Ни одна из этих кажущихся ошибок на имеет никакого эффекта в работе каталога, поскольку атрибут cn (дочерний от атрибута name) использует нечувствительное к регистру правило соответствия и LDAP при поиске выполняет некоторые интересные вещи.
В большом количестве руководств Вы встретите objectclass: top и определение всех объектных классов в иерархии. Начиная с OpenLDAP 2.0, это не является обязательным. Принимайте решение, будете ли Вы это делать, исходя из требований Вашей системы, или из того, любите или нет Вы печатать.
Пробел, следующий за : (двоеточием) в каждой строке, ЖИЗНЕННО НЕОБХОДИМ.
Большинство систем каталогов могут быть построены с помощью приведённого выше набора директив LDIF.
Далее следует описание директив LDIF, приводимых в алфавитном порядке.
Формат:
add: attributename
Директива add следует за директивой changetype: modify и определяет имена атрибута (атрибутов), которые будут добавлены в существующую запись. Можно добавить несколько значений для атрибута с одним и тем же именем, если этот атрибут многозначный (MULTI-VALUE).
Примечания:
О том, как добавить к существующей записи вспомогательный (AUXILIARY) объектный класс, смотрите в примерах к changetype: modify.
Примеры:
# добавляем один атрибут с одним значением (атрибут MULTI-VALUE) # текущие значения атрибута не меняются dn: cn=Robert Smith,ou=people,dc=example,dc=com changetype: modify add: telephonenumber telephonenumber: 123-111 # добавляем один атрибут с несколькими значениями (атрибут MULTI-VALUE) # текущие значения атрибута не меняются dn: cn=Robert Smith,ou=people,dc=example,dc=com changetype: modify add: telephonenumber telephonenumber: 555-123-1111 telephonenumber: 111
Примечание: При попытке добавить несколько значений однозначному (SINGLE-VALUE) атрибуту поведение точно не определено, но в большинстве реализаций добавляется только последнее значение.
Формат:
attributename: value
Директива attributename позволяет задать значение атрибуту.
Примечания:
Если атрибут поддерживает несколько значений, любое количество директив attributename может быть добавлено в LDIF-файл.
Директива attributename может быть использована с changetype add или replace
В качестве value может быть:
Строка
Строка Base 64.
URL файла, тогда значение будет получено из файла < file://path/to/file.
Примеры:
# добавляем атрибуты к новой записи dn: cn=Robert Smith,ou=people,dc=example,dc=com changetype: add objectclass: inetorgperson cn: Robert smith cn: Robert J Smith cn: Bob Smith telephonenumber: 123-111 ... # добавляем атрибут с несколькими значениями к существующей записи dn: cn=Robert Ssmith,ou=people,dc=example,dc=com changetype: modify add: telephonenumber telephonenumber: 555-123-1111 telephonenumber: 111 # использование URL файла dn: cn=Robert Ssmith,ou=people,dc=example,dc=com changetype: modify add: jpegphoto # между : и < не должно быть пробела jpegphoto:< file://tmp/my.jpg
Формат:
changetype: type
Директива changetype следует сразу за директивой dn: и определяет операцию, которая должна быть выполнена над записью.
type может принимать одно из следующих значений:
При использовании типа add последующие директивы будут использоваться для добавления (создания) записи. Если запись уже существует, то должна использоваться форма changetype: modify. Если в LDIF отсутствует директива changetype и он обрабатывается с помощью ldapadd, то по умолчанию подразумевается changetype: add.
Примеры:
dn: cn=Robert Smith,ou=people,dc=example,dc=com # добавить запись указанного в предыдущей строке dn changetype: add objectclass: inetorgperson cn: Robert Smith ...
При использовании типа delete запись, указанная в предшествующей директиве dn, будет удалена.
dn: cn=Robert Smith,ou=people,dc=example,dc=com # удалить запись, указанную dn в предыдущей строке changetype: delete
При использовании типа modify последующие команды будут изменять существующую запись, указанную в предшествующей директиве dn. Следующие за modify атрибуты (или объектные классы) могут быть добавлены, заменены или удалены.
Примечания:
Несколько операций modify могут быть собраны в последовательность ОПЕРАТОРА с помощью строк-РАЗДЕЛИТЕЛЕЙ.
Для добавления нового вспомогательного (AUXILIARY) объектного класса к существующей записи перед добавлением нового объектного класса и последующих атрибутов требуется указать существующий объектный класс (вспомогательные объектные классы присоединяются к существующему объектному классу). Смотрите примеры:
Примеры:
dn: cn=Robert Smith,ou=people,dc=example,dc=com # модифицировать запись, указанную dn в предыдущей строке changetype: modify # single operation add: telephonenumber telephonenumber: 555 dn: cn=Robert Smith,ou=people,dc=example,dc=com # модифицировать запись, указанную dn в предыдущей строке changetype: modify # несколько операций add: telephonenumber telephonenumber: 555 # за которыми следует строка-РАЗДЕЛИТЕЛЬ - replace: mail mail: bob.smith@example.com - delete: secretary # чтобы ДОБАВИТЬ новый вспомогательный объектный класс # к существующей записи dn: cn=Robert Smith,ou=people,dc=example,dc=com # модифицировать запись, указанную dn в предыдущей строке changetype: modify # данный объектный класс используется для присоединения objectclass: inetorgperson # к нему будет добавлен вспомогательный объектный класс objectclass: posixaccount # далее включаются обязательные атрибуты # нового объектного класса uidnumber: 200 gidnumber: 207 homedirectory: /home/rsmith ...
modrdn (и его псевдоним moddn) используется для изменения RDN записи (переименования или копирования записи), указанной в предшествующей директиве dn:. За ней ДОЛЖНА следовать директива newrdn:, а также могут следовать директивы deleteoldrdn и newsuperior.
Вы НЕ СМОЖЕТЕ переименовать запись, если у неё есть одна или несколько дочерних записей.
Пример:
dn: cn=Robert Ssmith,ou=people,dc=example,dc=com # следующая последовательность переименовывает указанный в предыдущей строке DN в # cn=Robert Smith,ou=people.dc=example,dc=com # и удаляет запись # cn=Robert Ssmith,ou=people,dc=example,dc=com changetype: modrdn newrdn: cn=Robert Smith deleteoldrdn: 1
Уже совсем скоро (One day Real Soon Now™)
Формат:
delete: attributename
Директива delete следует за директивой changetype: modify. Она выполняет операции с атрибутами и определяет список атрибутов для удаления. Чтобы удалить запись, используйте changetype: delete.
За директивой delete МОЖЕТ следовать одна или несколько директив, определяющих, какие атрибуты удалять. Если за ней не следуют такие директивы (то есть за ней следует конец файла (EOF), ПУСТАЯ строка или строка-РАЗДЕЛИТЕЛЬ, то будут удалены все атрибуты, указанные в attributename.
# удаляем одно значение атрибута dn: cn=Robert Ssmith,ou=people,dc=example,dc=com changetype: modify # удаляются только атрибуты, значения которых 123-111 и 111 # все остальные атрибуты telephonenumber не меняются delete: telephonenumber telephonenumber: 123-111 telephonenumber: 111 # удаляем атрибут с несколькими значениями dn: cn=Robert Ssmith,ou=people,dc=example,dc=com changetype: modify # удаляются все атрибуты telephonenumber delete: telephonenumber
Формат:
deleteoldrdn: action
Директива deleteoldrdn следует за директивой changetype: modrdn и определяет действие, которое будет произведено с оригинальным DN. В качестве action данная директива принимает 0 (ложь), в этом случае оригинальная запись сохраняется, или 1, в этом случае оригинальная запись удаляется.
Пример:
# устраняет ошибки в DN записи и # удаляет текущую запись dn: cn=Robert Ssmith,ou=people,dc=example,dc=com changetype: modrdn # создаётся новое имя (RDN) newrdn: cn=Robert Smith # удаляется текущая запись (Robert Ssmith) deleteoldrdn: 1
Формат:
dn: DN
Директива dn определяет Уникальное имя (Distinguished Name, DN) и используется для указания расположения (или адреса) записи, по которому будут выполняться последующие директивы (последовательность ЗАПИСИ).
Если это не первая запись в LDIF-файле, то директива dn ДОЛЖНА предваряться ПУСТОЙ строкой.
Пример:
... # предыдущая последовательность, затем ПУСТАЯ строка dn: ou=people,dc=example,dc=com ...
Формат:
newrdn: RDN
Директива newrdn следует за директивой changetype: modrdn (или moddn) и создаёт копию записи, указанной в предшествующей директиве dn, используя RDN, указанный в данной (то есть newrdn) директиве.
Обычно за этой директивой следует директива deleteoldrdn.
Совместно с директивой newsuperior может использоваться для копирования или перемещения записи в DIT.
Примеры:
# используем при исправлении ошибок dn: cn=Robert Ssmith,ou=people,dc=example,dc=com changetype: modrdn # корректируется запись newrdn: cn=Robert Smith # удаляется старая запись deleteoldrdn: 1
Формат:
newsuperior: DN
Директива newsuperior позволяет перемещать запись в DIT. Данная директива указывает LDAP переместить текущую запись в указанный данной директивой DN.
Данная директива используется совместно с директивами changetype: modrdn, newrdn и deleteoldrdn.
Примеры:
# перемещение записи из people в expeople dn: cn=Robert Smith,ou=people,dc=example,dc=com changetype: modrdn # rdn не меняется newrdn: cn=Robert Smith # старая запись удаляется deleteoldrdn: 1 # добавляется в иерархию expeople newsuperior: ou=expeople,dc=example,dc=com # копирование записи в expeople dn: cn=Robert Smith,ou=people,dc=example,dc=com changetype: modrdn # rdn не меняется newrdn: cn=Robert Smith # текущая запись сохраняется deleteoldrdn: 0 # добавляется в иерархию expeople newsuperior: ou=expeople,dc=example,dc=com
Формат:
objectclass: objectclassname
Директива objectclass позволяет добавить к записи объектный класс.
Примечания:
В записи должен быть хотя бы один структурный (STRUCTURAL) объектный класс.
Начиная с OpenLDAP 2.0+, нет необходимости определять все объектные классы в иерархии объектных классов, достаточно определить объектный класс самого нижнего уровня в иерархии.
Примеры:
# добавление объекного класса к новой записи dn: cn=Robert Smith,ou=people,dc=example,dc=com changetype: add # inetorgperson - самый нижний уровень в иерархии objectclass: inetorgperson cn: Robert smith cn: Robert J Smith cn: Bob Smith telephonenumber: 123-111 ... # добавление объекных классов к новой записи dn: cn=Robert Smith,ou=people,dc=example,dc=com changetype: add # inetorgperson - самый нижний уровень в иерархии objectclass: inetorgperson # здесь должны присутствовать оба объектных класса # поскольку posixaccount -вспомогательный объектный класс objectclass: posixaccount cn: Robert smith cn: Robert J Smith cn: Bob Smith telephonenumber: 123-111 ... # добавление нового вспомогательного объектного класса # к существующей записи dn: cn=Robert Smith,ou=people,dc=example,dc=com # модифицировать запись, указанную dn в предыдущей строке changetype: modify # данный объектный класс используется для присоединения objectclass: inetorgperson # к нему будет добавлен вспомогательный объектный класс objectclass: posixaccount # далее включаются обязательные атрибуты # нового объектного класса uidnumber: 200 gidnumber: 207 homedirectory: /home/rsmith ...
Формат:
replace: attributename
Директива replace следует за директивой changetype: modify и определяет название атрибута, который будет заменён.
Если у атрибута несколько значений, то ВСЕ текущие значения будут заменены на один или несколько следующих за данной директивой атрибутов.
Если нужно заменить только одно значение атрибута, имеющего несколько значений, используйте delete, а затем add. Смотрите пример ниже.
Примеры:
# заменить одно значение атрибута dn: cn=Robert Ssmith,ou=people,dc=example,dc=com changetype: modify replace: uid uid: bill # заменить атрибут с несколькими значениями dn: cn=Robert Smith,ou=people,dc=example,dc=com changetype: modify # заменяем все атрибуты telephonenumber # на 555-111-1212 replace: telephonenumber telephonenumber: 555-111-1212 # заменить одно значение у атрибута с несколькими значениями # удаляем, затем добавляем # в примере заменяется 555-111-1212 на 555 dn: cn=Robert Smith,ou=people,dc=example,dc=com changetype: modify # сначала удаляем требуемый атрибут delete: telephonenumber telephonenumber: 555-111-1212 # строка-РАЗДЕЛИТЕЛЬ (необходимо) - # добавляем новое значение add: telephonenumber telephonenumber: 555
Формат:
version: number
Директива version определяет версию формата директив файла LDIF. Эта директива не является обязательной и, из-за несоответствия реализаций, мы подразумеваем, что она не используется.
Данная директива, если она присутствует, должна быть первой директивой в файле (некоторые особо бестолковые реализации воспринимают это буквально и отклоняют файл, если строке version предшествует строка комментария). В настоящее время принимается номер версии, равный только 1.
# должно быть первой записью в LDIF-файле version: 1
Проблемы, комментарии, предположения, исправления (включая битые ссылки) или есть что добавить? Пожалуйста, выкроите время в потоке занятой жизни чтобы написать нам, вебмастеру или в службу поддержки. Оставшийся день Вы проведёте с чувством удовлетворения.
Нашли ошибку в переводе? Сообщите переводчикам!
Copyright © 1994-2017 ZyTrax, Inc. Все права защищены. Последнее изменение страницы: 15 октября 2017 г.
Переведено участниками проекта Pro-LDAP.ru в 2011-2017 г.