13. Спецификация схемы данных каталога

В этом разделе описывается как расширить пользовательскую (т.е. не системную, жёстко скомпилированную в slapd) схему данных каталога, используемую slapd(8). Предполагается, что читатель знаком с информационной моделью LDAP/X.500.

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

В данном разделе не обсуждается расширение системной схемы данных, используемой slapd(8), поскольку это требует модификации исходного кода. Системная схема включает в себя все операционные типы атрибутов, а также объектные классы, в которых могут или должны использоваться данные атрибуты (прямо или косвенно).


13.1. Файлы наборов схемы данных, распространяемые с дистрибутивом

Программное обеспечение OpenLDAP распространяется с наборами спецификаций схемы данных для Ваших нужд. Каждый набор описан в файле, который можно подключить (с помощью директивы include) в Вашем файле slapd.conf(5). Эти файлы наборов схемы данных по умолчанию установлены в директорию /usr/local/etc/openldap/schema.

Таблица 8.1: Спецификации схемы, распространяемые с дистрибутивом
ФайлОписание
core.schemaOpenLDAP core (обязательная)
cosine.schemaCosine and Internet X.500 (полезная)
inetorgperson.schemaInetOrgPerson (полезная)
misc.schemaРазное (экспериментальная)
nis.schemaNetwork Information Services (FYI)
openldap.schemaOpenLDAP Project (экспериментальная)

Чтобы использовать любой из этих файлов наборов схемы данных, Вам нужно только подключить нужный файл в разделе глобальных определений Вашего файла slapd.conf(5). Например:

        # Подключаем наборы схемы данных
        include /usr/local/etc/openldap/schema/core.schema
        include /usr/local/etc/openldap/schema/cosine.schema
        include /usr/local/etc/openldap/schema/inetorgperson.schema

Доступны также дополнительные файлы, смотрите OpenLDAP FAQ (http://www.openldap.org/faq/).


Замечание: Не следует изменять какие-либо элементы схемы данных, определённые в распространяемых файлах наборов схемы.


13.2. Расширение схемы данных каталога

Используемая slapd(8) схема данных может быть расширена для поддержки дополнительных синтаксисов, правил соответствия, типов атрибутов и объектных классов. В этом подразделе детально описано как добавить новые типы атрибутов и объектные классы, требуемые в пользовательских приложениях, с использованием уже поддерживаемых slapd синтаксисов и правил соответствия. Для slapd также можно определить дополнительные синтаксисы, правила соответствия и элементы системной схемы данных, но это требует написания программного кода и в данном подразделе не рассматривается.

Пять шагов к определению нового набора схемы данных:

  1. Получить идентификатор объекта (Object Identifier);
  2. Выбрать префикс имени;
  3. Создать локальный файл набора схемы;
  4. Определить пользовательские типы атрибутов (если необходимо);
  5. Определить пользовательские объектные классы.

13.2.1. Идентификаторы объектов

Каждый элемент схемы данных идентифицируется глобально-уникальным идентификатором объекта (Object Identifier, OID). Такие идентификаторы также используются для идентификации других объектов. Обычно их можно найти в протоколах, описанных конструкциями ASN.1. В частности, они активно используются в Simple Network Management Protocol (SNMP). Поскольку OID иерархичны, Ваша организация может получить один OID и делать от него ответвления по мере необходимости. Например, если Вашей организации был присвоен OID 1.1, Вы можете сделать такие ответвления:

Таблица 8.2: Примерная иерархия OID
OIDAssignment
1.1OID организации
1.1.1Элементы SNMP
1.1.2Элементы LDAP
1.1.2.1Типы атрибутов
1.1.2.1.1x-my-Attribute (один из атрибутов)
1.1.2.2Объектные классы
1.1.2.2.1x-my-ObjectClass (один из объектных классов)

Вы, конечно же, можете выстраивать иерархию в пределах своего OID, ориентируясь на потребности Вашей организации. Независимо от того, какую иерархию Вы избрали, нужно вести реестр выделенных Вами идентификаторов и присвоения их объектам. Это может быть простой текстовый файл или что-то более продвинутое, типа OID-реестра OpenLDAP (http://www.openldap.org/faq/index.cgi?file=197).

Дополнительную информацию о идентификаторах объектов (и сервисе регистрации) можно посмотреть здесь: http://www.alvestrand.no/objectid/.

Для бесплатного получения зарегистрированного OID можно запросить OID из пространства Private Enterprise (частное предприятие), которое поддерживается организацией Internet Assigned Numbers Authority (ORG:IANA). Любое частное предприятие (организация) может запросить выделение ему в пределах этого пространства Private Enterprise Number (PEN, номер частного предприятия). Просто заполните форму IANA на странице http://pen.iana.org/pen/PenApplication.page и в течение нескольких дней Вам вышлют Ваш официальный PEN. Ваш основной OID будет примерно такой: 1.3.6.1.4.1.X, где X — целое число.


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

Кроме того, можно получить подпространство OID от национального органа (например, ANSI, BSI).

13.2.2. Именование элементов

В дополнение к присвоению каждому элементу схемы уникального идентификатора, Вы должны предоставить ему как минимум одно текстовое имя. Имена должны быть зарегистрированы в IANA или иметь префикс "x-" для помещения элемента в пространство имён "private use" ("для частного использования").

Имена должны быть одновременно и описательными, и не пересекаться с именами других элементов схемы. В частности, любое имя, которое Вы выберите, не должно пересекаться с действующими и зарезервированными именами из Standard Track (Стандартного Ряда) (это гарантировано, если Ваши имена зарегистрированы или начинаются с "x-").

Следует отметить, что Вы можете получить свой собственный зарегистрированный префикс имен, чтобы не нужно было регистрировать каждое имя отдельно. За деталями обращайтесь к RFC4520.

В приведённых ниже примерах мы использовали короткий префикс 'x-my-'. Подобные короткие префиксы могут применяться только в очень больших глобальных организациях. В общем случае мы рекомендуем что-то вроде 'x-ru-Firm-' (российская компания) или 'x-com-Example' (элементы, ассоциированные с организацией example.com).

13.2.3. Файл локального набора схемы данных

Чтобы определить элементы схемы данных для создания записей в каталоге, можно использовать директивы конфигурационного файла objectclass и attributetype. Однако более типичной практикой является создание файла, содержащего определения Ваших пользовательских элементов схемы. Мы рекомендуем Вам создать файл local.schema в /usr/local/etc/openldap/schema/local.schema, а затем подключать его в Ваш файл slapd.conf(5) сразу после других директив подключения наборов схемы данных include.

        # Подключаем наборы схемы данных
        include /usr/local/etc/openldap/schema/core.schema
        include /usr/local/etc/openldap/schema/cosine.schema
        include /usr/local/etc/openldap/schema/inetorgperson.schema
        # Подключаем локальный набор схемы данных
        include /usr/local/etc/openldap/schema/local.schema

13.2.4. Спецификация типа атрибута

Для определения нового типа атрибута применяется директива attributetype. В ней используется такое же описание типа атрибута, определённое в RFC4512рус., как и в атрибуте attributeTypes подзаписи подсхемы (subschema subentry, RFC4512рус.):

        attributetype <RFC4512 Attribute Type Description>

где Attribute Type Description определяется следующей ABNF (Расширенная спецификация синтаксиса Бэкуса-Наура):

      AttributeTypeDescription = "(" whsp
            numericoid whsp              ; идентификатор типа атрибута
          [ "NAME" qdescrs ]             ; имя используемое в типе атрибута
          [ "DESC" qdstring ]            ; описание
          [ "OBSOLETE" whsp ]
          [ "SUP" woid ]                 ; унаследован от этого AttributeType
          [ "EQUALITY" woid              ; имя правила соответствия
          [ "ORDERING" woid              ; имя правила соответствия
          [ "SUBSTR" woid ]              ; имя правила соответствия
          [ "SYNTAX" whsp noidlen whsp ] ; OID синтаксиса
          [ "SINGLE-VALUE" whsp ]        ; по умолчанию может иметь несколько значений
          [ "COLLECTIVE" whsp ]          ; по умолчанию не коллективный
          [ "NO-USER-MODIFICATION" whsp ]; по умолчанию изменяемый пользователем
          [ "USAGE" whsp AttributeUsage ]; по умолчанию userApplications
          whsp ")"

      AttributeUsage =
          "userApplications"     /
          "directoryOperation"   /
          "distributedOperation" / ; операционный атрибут, коллективно используемый агентами DSA
          "dSAOperation"           ; операционный атрибут, специфичный для DSA; значение атрибута зависит от конкретного сервера

где whsp — это пробельный символ (' '), numericoid — глобально-уникальный OID в точечно-цифровой форме (например, 1.1.0), qdescrs — одно или более имён, woid — это или имя, или OID, за которым может следовать необязательный указатель длины (например, {10}).

Например, типы атрибутов name и cn определены в core.schema так:

        attributeType ( 2.5.4.41 NAME 'name'
                DESC 'name(s) associated with the object'
                EQUALITY caseIgnoreMatch
                SUBSTR caseIgnoreSubstringsMatch
                SYNTAX 1.3.6.1.4.1.1466.115.121.1.15{32768} )
        attributeType ( 2.5.4.3 NAME ( 'cn' 'commonName' )
                DESC 'common name(s) assciated with the object'
                SUP name )

Обратите внимание, что в каждом из них определены OID атрибута, короткое имя и краткое описание. Каждое имя — это псевдоним для OID. В ответ на запрос slapd(8) возвращает первое из перечисленных имён.

Первый атрибут, name, может содержать значения с синтаксисом directoryString (в кодировке Unicode UTF-8). Синтаксис указан с помощью его OID (1.3.6.1.4.1.1466.115.121.1.15 идентифицирует синтаксис directoryString). Также указана рекомендуемая длина значения в 32768 символов. Серверы должны поддерживать хранение значений с этой длиной, однако могут поддерживать и более длинные значения. Данное поле НЕ ограничивает длину значения, поэтому оно игнорируется серверами (в том числе и slapd), которые не накладывают таких ограничений размера. Кроме того, при сопоставлении полного значения атрибута и его подстроки (equality и substring) используются правила соответствия case ignore (без учёта регистра символов). Ниже приведены таблицы с часто используемыми синтаксисами и правилами соответствия (slapd(8) поддерживает все из перечисленных и гораздо больше).

Таблица 8.3: Часто используемые синтаксисы
НазваниеOIDОписание
boolean1.3.6.1.4.1.1466.115.121.1.7логическое значение
directoryString1.3.6.1.4.1.1466.115.121.1.15строка Unicode (UTF-8)
distinguishedName1.3.6.1.4.1.1466.115.121.1.12LDAP DN
integer1.3.6.1.4.1.1466.115.121.1.27целое число
numericString1.3.6.1.4.1.1466.115.121.1.36числовая строка
OID1.3.6.1.4.1.1466.115.121.1.38идентификатор объекта
octetString1.3.6.1.4.1.1466.115.121.1.40произвольная последовательность октетов (байт)

Таблица 8.4: Часто используемые правила соответствия
НазваниеТипОписание
booleanMatchequalityсоответствие логических значений
caseIgnoreMatchequalityсоответствие строковых значений без учёта регистра символов и количества пробельных символов
caseIgnoreOrderingMatchorderingсортировка строковых значений без учёта регистра символов и количества пробельных символов
caseIgnoreSubstringsMatchsubstringsсоответствие подстрок строковых значений без учёта регистра символов и количества пробельных символов
caseExactMatchequalityсоответствие строковых значений с учётом регистра символов и количества пробельных символов
caseExactOrderingMatchorderingсортировка строковых значений с учётом регистра символов и количества пробельных символов
caseExactSubstringsMatchsubstringsсоответствие подстрок строковых значений с учётом регистра символов и количества пробельных символов
distinguishedNameMatchequalityсоответствие уникальных имён (DN)
integerMatchequalityсоответствие целых чисел
integerOrderingMatchorderingсортировка целочисленных значений
numericStringMatchequalityсоответствие числовых значений
numericStringOrderingMatchorderingсортировка числовых значений
numericStringSubstringsMatchsubstringsсоответствие подстрок числовых значений
octetStringMatchequalityсоответствие строк байт
octetStringOrderingMatchorderingсортировка строк байт
octetStringSubstringsMatchorderingсоответствие подстрок строк байт
objectIdentiferMatchequalityсоответствие идентификаторов объектов

Второй атрибут, cn, — это подтип name, и потому он наследует синтаксис, правила соответствия и сферу применения типа атрибута name. commonName — это его альтернативное имя.

Оба атрибута могут иметь несколько значений (не накладывается ограничение о единственном значении). Сфера применения обоих — пользовательские (то есть предназначенные для использования в пользовательских приложениях). Ни один из них не устарел и не является коллективным.

В следующих подразделах даётся ещё несколько примеров.

13.2.4.1. Тип атрибута x-my-UniqueName

Во многих организациях стремятся сопоставить каждому пользователю одно уникальное имя. Хотя для этого можно было бы использовать атрибут displayName (RFC2798), в действительности значение этого атрибута должно управляться пользователем, а не организацией. Мы можем просто скопировать определение displayName из набора inetorgperson.schema и исправить OID, имя, описание, и т.д.:

        attributetype ( 1.1.2.1.1 NAME 'x-my-UniqueName'
                DESC 'unique name with my organization'
                EQUALITY caseIgnoreMatch
                SUBSTR caseIgnoreSubstringsMatch
                SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
                SINGLE-VALUE )

Однако, если мы хотим, чтобы это имя использовалось в операциях с обращением к атрибуту name, таких как (name=*Jane*), мы можем поступить иначе и определить его как подтип от типа атрибута name, например:

        attributetype ( 1.1.2.1.1 NAME 'x-my-UniqueName'
                DESC 'unique name with my organization'
                SUP name )

13.2.4.2. Тип атрибута x-my-Photo

Во многих организациях собираются фотографии всех сотрудников. Для хранения фотографий можно определить тип атрибута x-my-Photo. Конечно, для этой задачи можно просто использовать тип jpegPhoto (RFC2798) (или его подтип), но в этом случае все фотографии должны быть в формате JPEG File Interchange Format. А мы можем определить универсальный тип атрибута для хранения изображений с использованием синтаксиса octetString:

        attributetype ( 1.1.2.1.2 NAME 'x-my-Photo'
                DESC 'a photo (application defined format)'
                SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
                SINGLE-VALUE )

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

Если Вы хотите поддерживать разные форматы фотографий, это можно сделать несколькими способами: определить разные типы атрибутов для каждого формата; добавить перед фотографией некоторую порцию информации о её типе; наконец, описать значение атрибута с помощью конструкций ASN.1 и использовать опцию передачи ;binary.

Альтернативный путь — хранить в атрибуте URI, указывающий на фотографию. Вы можете смоделировать подобный атрибут по аналогии с labeledURI (RFC2079) или просто унаследовать от него подтип:

        attributetype ( 1.1.2.1.3 NAME 'x-my-PhotoURI'
                DESC 'URI and optional label referring to a photo'
                SUP labeledURI )

13.2.5. Спецификация объектного класса

Для определения нового объектного класса используется директива objectclass. В ней используется такое же описание объектного класса, определённое в RFC4512рус., как и в атрибуте objectClasses подзаписи подсхемы (subschema subentry, RFC4512):

        objectclass <RFC4512 Object Class Description>

где Object Class Description определяется следующей ABNF:

        ObjectClassDescription = "(" whsp
                numericoid whsp      ; идентификатор объектного класса
                [ "NAME" qdescrs ]
                [ "DESC" qdstring ]
                [ "OBSOLETE" whsp ]
                [ "SUP" oids ]       ; родительский объектный класс
                [ ( "ABSTRACT" / "STRUCTURAL" / "AUXILIARY" ) whsp ]
                        ; по умолчанию STRUCTURAL
                [ "MUST" oids ]      ; типы атрибутов
                [ "MAY" oids ]       ; типы атрибутов
                whsp ")"

где whsp — это пробельный символ (' '), numericoid — глобально-уникальный OID в точечно-цифровой форме (например, 1.1.0), qdescrs — одно или более имён, oids — одно или более имён и/или OID.

13.2.5.1. Объектный класс x-my-PhotoObject

Определим вспомогательный (auxiliary) объектный класс, который позволит добавить атрибут x-my-Photo к любой существующей записи.

        objectclass ( 1.1.2.2.1 NAME 'x-my-PhotoObject'
                DESC 'mixin x-my-Photo'
                AUXILIARY
                MAY x-my-Photo )

13.2.5.2. Объектный класс x-my-Person

Если Вашей организации нужен собственный внутренний структурный (structural) объектный класс для представления пользователей, Вы можете сделать подкласс одного из существующих классов для описания людей, таких как inetOrgPerson (RFC2798), и добавить к нему любые дополнительные атрибуты, которые Вы разработали.

        objectclass ( 1.1.2.2.2 NAME 'x-my-Person'
                DESC 'my person'
                SUP inetOrgPerson
                MUST ( x-my-UniqueName $ givenName )
                MAY x-my-Photo )

Данный объектный класс наследует требуемые/разрешённые типы атрибутов от inetOrgPerson, но также требует наличия типов атрибутов x-my-UniqueName и givenName и разрешает наличие x-my-Photo.

13.2.6. Макросы OID

Чтобы облегчить управление и использование OID, slapd(8) поддерживает макросы идентификаторов объектов. Директива objectIdentifier используется для сопоставления макроса (имени) с OID. OID также может быть производным от ранее определенного макроса OID. Синтаксис файла slapd.conf(5) для задания макроса:

        objectIdentifier <имя> { <oid> | <имя>[:<суффикс>] }

Следующий пример демонстрирует задание набора макросов OID и их использование в определении элементов схемы:

        objectIdentifier myOID  1.1
        objectIdentifier mySNMP myOID:1
        objectIdentifier myLDAP myOID:2
        objectIdentifier myAttributeType        myLDAP:1
        objectIdentifier myObjectClass  myLDAP:2
        attributetype ( myAttributeType:3 NAME 'x-my-PhotoURI'
                DESC 'URI and optional label referring to a photo'
                SUP labeledURI )
        objectclass ( myObjectClass:1 NAME 'x-my-PhotoObject'
                DESC 'mixin x-my-Photo'
                AUXILIARY
                MAY x-my-Photo )