Перевод выполнен участниками проекта Pro-LDAP.ru. Предложения по улучшению перевода и сообщения об ошибках принимаются на форуме проекта.
Network Working Group
Request for Comments: 4511
Категория: Standards Track
Под редакцией J. Sermersheim, Novell, Inc.
Июнь 2006 года
Отменяет: RFC 2251, RFC 2830, RFC 3771

Lightweight Directory Access Protocol (LDAP): Определение протокола

Статус документа

Этот документ определяет проект стандарта протокола Internet для сообщества Internet, а также приглашает к обсуждению и подаче предложений по его усовершенствованию. Пожалуйста, сверяйтесь с текущей редакцией "Официальных стандартов протоколов Internet" (STD 1), чтобы узнать состояние стандартизации и статус этого протокола. Ограничений на распространение данного документа не накладывается.

Уведомление об авторских правах

Copyright (C) Internet Society (2006).

Тезисы

В этом документе описываются элементы Облегчённого протокола доступа к службам каталогов (Lightweight Directory Access Protocol, LDAP) вместе с их семантиками и способами кодирования. LDAP обеспечивает доступ к распределенным службам каталогов, функционирующим в соответствии с моделями данных и сервисов X.500. Эти элементы протокола основываются на элементах Протокола доступа к службам каталогов (Directory Access Protocol, DAP) X.500.

Содержание

1. Введение
1.1. Взаимосвязь с другими спецификациями LDAP
2. Соглашения
3. Модель протокола
3.1. Взаимосвязь между операциями и уровнем сообщений LDAP
4. Элементы протокола
4.1. Общие элементы
4.1.1. Конверт сообщения
4.1.2. Строковые типы
4.1.3. Уникальное имя (Distinguished Name) и относительное уникальное имя (Relative Distinguished Name)
4.1.4. Описание атрибута
4.1.5. Значение атрибута
4.1.6. Утверждение значения атрибута (Attribute Value Assertion)
4.1.7. Атрибут (Attribute) и частичный атрибут (PartialAttribute)
4.1.8. Идентификатор правила соответствия
4.1.9. Результирующее сообщение
4.1.10. Отсылка (Referral)
4.1.11. Элементы управления (Controls)
4.2. Операция подсоединения Bind
4.2.1. Обработка запроса Bind
4.2.2. Ответ Bind
4.3. Операция отсоединения Unbind
4.4. Произвольное уведомление (Unsolicited Notification)
4.4.1. Уведомление об отключении (Notice of Disconnection)
4.5. Операция поиска Search
4.5.1. Запрос Search
4.5.2. Результат операции Search
4.5.3. Ссылки-продолжения (Continuation References) в результатах операции Search
4.6. Операция модификации Modify
4.7. Операциия добавления Add
4.8. Операция удаления Delete
4.9. Операция модификации уникального имени Modify DN
4.10. Операция сравнения Compare
4.11. Операция отказа Abandon
4.12. Расширенная операция Extended
4.13. Промежуточное ответное сообщение IntermediateResponse
4.13.1. Использование с LDAP ExtendedRequest и ExtendedResponse
4.13.2. Использование с элементами управления запросов LDAP
4.14. Операция StartTLS
4.14.1. Запрос StartTLS
4.14.2. Результат операции StartTLS
4.14.3. Снятие уровня TLS
5. Кодирование протокола, соединения и передача данных
5.1. Кодирование протокола
5.2. Transmission Control Protocol (TCP)
5.3. Прекращение сессии LDAP
6. О безопасности
7. Благодарности
8. Нормативные документы
9. Информативные документы
10. Регистрация в IANA
Приложение A. Результирующие коды LDAP
A.1. Неошибочные результирующие коды
A.2. Результирующие коды
Приложение B. Полное определение ASN.1
Приложение C. Изменения
C.1. Изменения, внесённые в RFC 2251
C.2. Изменения, внесённые в RFC 2830
C.3. Изменения, внесённые в RFC 3771

1. Введение

Каталог — это "ряд открытых систем, взаимодействующих друг с другом для предоставления сервисов каталога" [X.500]. Пользователь каталога, человек или другая сущность, получает доступ к каталогу посредством клиента (или пользовательского агента каталога (Directory User Agent, DUA)). Этот клиент от имени пользователя каталога взаимодействует с одним или несколькими серверами (или системными агентами каталога (Directory System Agent, DSA)). Клиенты взаимодействуют с серверами с помощью протокола доступа к службам каталогов.

В этом документе детализируются элементы протокола Lightweight Directory Access Protocol (LDAP) вместе с их семантиками. Вслед за описанием элементов протокола приводится способ их кодирования и передачи.

1.1. Взаимосвязь с другими спецификациями LDAP

Данный документ является неотъемлемой частью технической спецификации LDAP [RFC4510], полностью отменяющей ранее определённую техническую спецификацию LDAP, RFC 3377.

Этот документ, совместно с [RFC4510], [RFC4513] и [RFC4512] полностью отменяет RFC 2251. Раздел 3.3 отменён [RFC4510]. Разделы 4.2.1 (частично) и 4.2.2 отменены [RFC4513]. Разделы 3.2, 3.4, 4.1.3 (последний параграф), 4.1.4, 4.1.5, 4.1.5.1, 4.1.9 (последний параграф), 5.1, 6.1 и 6.2 (последний параграф) отменены [RFC4512]. Оставшаяся часть RFC 2251 отменена этим документом. Существенные изменения в этой оставшейся части обобщены в приложении C.1.

Этот документ отменяет разделы 2 и 4 RFC 2830. Оставшаяся часть RFC 2830 отменена [RFC4513]. Существенные изменения в остальных разделах обобщены в приложении C.2.

Этот документ полностью отменяет RFC 3771.

2. Соглашения

Ключевые слова "MUST" (необходимо), "MUST NOT" (недопустимо), "REQUIRED" (требуется), "SHALL" (нужно), "SHALL NOT" (не нужно), "SHOULD" (следует), "SHOULD NOT" (не следует), "RECOMMENDED" (рекомендуется) и "MAY" (возможно) в данном документе должны интерпретироваться так, как описано в [RFC2119].

Обозначения символов в этом документе используют нотацию кодирования и именования из стандарта Unicode [Unicode]. Например, буква "a" может быть представлена либо как <U+0061>, либо как <LATIN SMALL LETTER A>.

Примечание: термины, используемые в Unicode, можно найти в соответствующем [глоссарии]. Информацию о модели кодирования символов Unicode можно найти в [техническом отчёте Unicode].

Термин ("транспортное соединение") ("transport connection") обозначает базовые транспортные сервисы, используемые для проведения обмена сообщениями протокола, а также соединения, установленные этими сервисами.

Термин "уровень TLS" ("TLS layer") обозначает сервисы Transport Layer Security (TLS), используемые для обеспечения безопасности при передаче информации, а также соединения, установленные этими сервисами.

Термин "уровень SASL" ("SASL layer") обозначает сервисы Simply Authentication and Security Layer (SASL), используемые для обеспечения безопасности при передаче информации, а также соединения, установленные этими сервисами.

Термин "уровень сообщений LDAP" ("LDAP message layer") обозначает сервисы LDAP Message Protocol Data Unit (PDU), используемые для предоставления услуг служб каталогов, а также соединения, установленные этими сервисами.

Термин "сессия LDAP" ("LDAP session") обозначает комбинированные сервисы (транспортное соединение, уровень TLS, уровень SASL, уровень сообщений LDAP) и их соединения.

Иллюстрацию этих четырёх терминов смотрите в таблице в разделе 5.

3. Модель протокола

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

Как правило, операции протокола не зависят одна от другой. Каждая операция обрабатывается как атомарное действие, оставляющее каталог в целостном состоянии.

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

Основные операции протокола, определённые в этом документе, могут быть отображены в подмножество абстрактной службы каталогов (Directory Abstract Service) X.500 (1993) [X.511]. Тем не менее, не существует взаимно-однозначного соответствия между операциями LDAP и операциями Directory Access Protocol (DAP) X.500. Реализации сервера, выступающей в роли шлюза к каталогам X.500, может потребоваться выполнить несколько запросов DAP для обработки одного запроса LDAP.

3.1. Взаимосвязь между операциями и уровнем сообщений LDAP

Обмен операциями протокола происходит на уровне сообщений LDAP. При закрытии транспортного соединения любые незавершённые операции на уровне сообщений LDAP отбрасываются (если это возможно), либо завершаются без передачи ответа (когда отказаться от их выполнения невозможно). Также, при закрытии транспортного соединения, клиент не должен (MUST NOT) подразумевать, что любые незавершившиеся операции обновления были выполнены успешно или неуспешно.

4. Элементы протокола

Протокол описан с использованием Abstract Syntax Notation One ([ASN.1]) и передаётся с использованием подмножества ASN.1 Basic Encoding Rules ([BER]). В разделе 5 определяется, каким образом кодируются и передаются элементы протокола.

В целях поддержки будущих расширений данного протокола, расширяемость подразумевается там, где это разрешено в ASN.1 (то есть, расширяемыми являются типы sequence, set, choice и enumerated). Кроме того, типы ASN.1, которые являются явно расширяемыми, о чём говорится в [RFC4520], были снабжены многоточием (...). Из-за такой подразумеваемой расширяемости клиенты и серверы должны (MUST) (если не указано иное) игнорировать компоненты SEQUENCE, теги которых они не могут распознать.

Для изменений протокола, кроме тех, которые являются расширениями описанных здесь механизмов, требуется другой номер версии. Клиент указывает используемый им номер версии в составе запроса BindRequest, описанного в разделе 4.2. Если клиент не посылает Bind, сервер должен (MUST) подразумевать, что клиент использует версию 3 или выше.

Клиент может попытаться определить поддерживаемую сервером версию протокола путём прочтения атрибута 'supportedLDAPVersion' записи root DSE (DSA-Specific Entry) [RFC4512].

4.1. Общие элементы

В этом разделе описывается формат блока данных протокола "Конверт сообщения LDAP" (LDAPMessage envelope Protocol Data Unit (PDU)), а также определения типов данных, которые используются в операциях протокола.

4.1.1. Конверт сообщения

В целях обмена сообщениями протокола, все операции протокола инкапсулируются в общий конверт LDAPMessage, который определяется так:

        LDAPMessage ::= SEQUENCE {
             messageID       MessageID,
             protocolOp      CHOICE {
                  bindRequest           BindRequest,
                  bindResponse          BindResponse,
                  unbindRequest         UnbindRequest,
                  searchRequest         SearchRequest,
                  searchResEntry        SearchResultEntry,
                  searchResDone         SearchResultDone,
                  searchResRef          SearchResultReference,
                  modifyRequest         ModifyRequest,
                  modifyResponse        ModifyResponse,
                  addRequest            AddRequest,
                  addResponse           AddResponse,
                  delRequest            DelRequest,
                  delResponse           DelResponse,
                  modDNRequest          ModifyDNRequest,
                  modDNResponse         ModifyDNResponse,
                  compareRequest        CompareRequest,
                  compareResponse       CompareResponse,
                  abandonRequest        AbandonRequest,
                  extendedReq           ExtendedRequest,
                  extendedResp          ExtendedResponse,
                  ...,
                  intermediateResponse  IntermediateResponse },
             controls       [0] Controls OPTIONAL }

        MessageID ::= INTEGER (0 .. maxInt)

        maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) --

Тип ASN.1 Controls (элементы управления) определён в разделе 4.1.11.

Назначение LDAPMessage — предоставить конверт, содержащий общие поля, требуемые во всех обменах сообщениями протокола. В настоящий момент общими полями являются только messageID и controls.

Если сервер получает от клиента LDAPMessage, в котором конструкция LDAPMessage SEQUENCE не может быть распознана, либо messageID не может быть разобран, либо значение в поле protocolOp не распознаётся как запрос, либо обнаружено, что закодированная структура или длина полей данных некорректны, то серверу следует (SHOULD) вернуть Notice of Disconnection (Уведомление об отключении), описанное в разделе 4.4.1, с результирующим кодом resultCode, установленным в protocolError, после чего он должен (MUST) немедленно завершить сессию LDAP как описано в разделе 5.3.

В остальных случаях, когда клиент или сервер не могут разобрать LDAP PDU, им следует (SHOULD) немедленно завершить сессию LDAP (раздел 5.3), если дальнейшее взаимодействие (в том числе предоставление уведомления) было бы пагубным. В противном случае реализации сервера должны (MUST) возвращать соответствующий ответ на запрос, с кодом resultCode, установленным в protocolError.

4.1.1.1. MessageID

Все конверты LDAPMessage, инкапсулирующие ответы, содержат значение messageID соответствующего запросного LDAPMessage.

MessageID запроса должно (MUST) иметь ненулевое значение, отличное от messageID любого другого запроса в течение одной и той же сессии LDAP. Нулевое значение зарезервировано для сообщений незапрошенных уведомлений (unsolicited notification message).

Обычно клиенты при каждом запросе увеличивают счётчик на единицу.

Клиенту недопустимо (MUST NOT) посылать запрос с тем же messageID, что и в предыдущих запросах, в рамках одной и той же сессии LDAP, за исключением тех случаев, когда есть возможность определить, что эти предыдущие запросы больше не обслуживаются сервером (например, после получения финального ответа, либо при выполнении очередного Bind). В противном случае поведение не определено. Также имейте ввиду, что операция Abandon и успешно сброшенные операции не посылают ответов.

4.1.2. Строковые типы

LDAPString — это введённое для удобства обозначение, указывающее на то, что, хотя строки типа LDAPString кодируются как тип ASN.1 OCTET STRING, используется набор символов [ISO10646] (расширенный набор [Unicode]), закодированный по алгоритму UTF-8 [RFC3629]. Обратите внимание, что символы Unicode от U+0000 до U+007F совпадают с символами ASCII от 0 до 127 соответственно, и имеют одну и ту же кодировку UTF-8 в один октет. Другие символы Unicode имеют кодировку UTF-8 в несколько октетов.

        LDAPString ::= OCTET STRING -- закодирована в UTF-8,
                                    -- символы [ISO10646]

LDAPOID — это введённое для удобства обозначение, указывающее на то, что разрешённым значением такой строки является точечно-цифровое представление идентификатора объекта OBJECT IDENTIFIER (закодированное в UTF-8). Хотя LDAPOID кодируется как OCTET STRING, значения такой строки ограничены определением <numericoid>, данным в разделе 1.4 [RFC4512].

        LDAPOID ::= OCTET STRING -- ограничена до <numericoid>
                                 -- [RFC4512]

Например,

        1.3.6.1.4.1.1466.1.2.3

4.1.3. Уникальное имя (Distinguished Name) и относительное уникальное имя (Relative Distinguished Name)

LDAPDN определено как представление уникального имени Distinguished Name (DN) после кодирования согласно спецификации, данной в [RFC4514].

        LDAPDN ::= LDAPString
                   -- ограничена до <distinguishedName> [RFC4514]

RelativeLDAPDN определено как представление относительного уникального имени Relative Distinguished Name (RDN) после кодирования согласно спецификации, данной в [RFC4514].

        RelativeLDAPDN ::= LDAPString
                           -- ограничена до <name-component> [RFC4514]

4.1.4. Описание атрибута

Спецификация и правила кодирования для описания атрибутов определены в разделе 2.5 [RFC4512]. Если коротко, описание атрибута — это тип атрибута и ноль или более опций.

        AttributeDescription ::= LDAPString
                                -- ограничена до <attributedescription>
                                -- [RFC4512]

4.1.5. Значение атрибута

Поле типа AttributeValue — это строка OCTET STRING, содержащая закодированное значение атрибута. Значение атрибута кодируется согласно LDAP-специфичному определению кодирования соответствующего этому атрибуту синтаксиса. LDAP-специфичные определения кодирования для различных синтаксисов и типов атрибутов можно найти в других документах, в частности в [RFC4517].

        AttributeValue ::= OCTET STRING

Имейте ввиду, что ограничений на размер данного кодирования не определено; таким образом, значения протокола могут включать значения атрибутов в несколько мегабайт (например, фотографии).

Значения атрибута могут быть определены так, чтобы у них был произвольный или непечатный синтаксис. В реализациях недопустимо (MUST NOT) отображать или пытаться декодировать значение атрибута, если его синтаксис неизвестен. Реализация может попытаться найти поднабор схемы данных исходной записи и получить из него описание этого типа атрибута 'attributeTypes' [RFC4512].

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

4.1.6. Утверждение значения атрибута (Attribute Value Assertion)

Определение типа AttributeValueAssertion (AVA) аналогично приведённому с стандартах каталога X.500. Он содержит описание атрибута и правило соответствия ([RFC4512], раздел 4.1.3) утверждаемого значения, подходящего для данного типа атрибута. Элементы данного типа обычно используются для утверждения того, что значение в assertionValue соответствует значению атрибута.

        AttributeValueAssertion ::= SEQUENCE {
             attributeDesc   AttributeDescription,
             assertionValue  AssertionValue }

        AssertionValue ::= OCTET STRING

Синтаксис AssertionValue зависит от контекста выполняемой операции LDAP. Например, синтаксис правила соответствия EQUALITY для атрибута используется при выполнении операции Compare. Часто это тот же самый синтаксис, что используется для значений этого типа атрибута, но в некоторых случаях синтаксис утверждения отличается от синтаксиса значения. Например, смотрите objectIdentiferFirstComponentMatch в [RFC4517].

4.1.7. Атрибут (Attribute) и частичный атрибут (PartialAttribute)

Атрибуты и частичные атрибуты состоят из описания атрибута и значений атрибута. PartialAttribute позволяет не иметь значений (ноль значений), а Attribute требует наличия хотя бы одного значения.

        PartialAttribute ::= SEQUENCE {
             type       AttributeDescription,
             vals       SET OF value AttributeValue }

        Attribute ::= PartialAttribute(WITH COMPONENTS {
             ...,
             vals (SIZE(1..MAX))})

Как описано в разделе 2.2 [RFC4512], никакие два значения атрибута не могут быть эквивалентны. Набор значений атрибутов не отсортирован. Реализации не должны (MUST NOT) полагаться на то, что порядок значений атрибутов от запроса к запросу будет повторяться.

4.1.8. Идентификатор правила соответствия

Правила соответствия определяются в разделе 4.1.3 [RFC4512]. Правило соответствия идентифицируется в протоколе состоящим из печатных символов представлением либо его числового идентификатора объекта <numericoid>, либо одного из его коротких имён-дескрипторов [RFC4512], например, 'caseIgnoreMatch' или '2.5.13.2'.

        MatchingRuleId ::= LDAPString

4.1.9. Результирующее сообщение

LDAPResult — это конструкция, используемая в данном протоколе для возврата индикации успешного или неудачного завершения операции от сервера клиенту. На различные запросы сервер будет возвращать ответы, содержащие элементы из конструкции LDAPResult, для индикации финального статуса запроса операции протокола.

        LDAPResult ::= SEQUENCE {
             resultCode         ENUMERATED {
                  success                      (0),
                  operationsError              (1),
                  protocolError                (2),
                  timeLimitExceeded            (3),
                  sizeLimitExceeded            (4),
                  compareFalse                 (5),
                  compareTrue                  (6),
                  authMethodNotSupported       (7),
                  strongerAuthRequired         (8),
                       -- 9 зарезервирован --
                  referral                     (10),
                  adminLimitExceeded           (11),
                  unavailableCriticalExtension (12),
                  confidentialityRequired      (13),
                  saslBindInProgress           (14),
                  noSuchAttribute              (16),
                  undefinedAttributeType       (17),
                  inappropriateMatching        (18),
                  constraintViolation          (19),
                  attributeOrValueExists       (20),
                  invalidAttributeSyntax       (21),
                       -- 22-31 не используются --
                  noSuchObject                 (32),
                  aliasProblem                 (33),
                  invalidDNSyntax              (34),
                       -- 35 зарезервирован для неопределённого isLeaf --
                  aliasDereferencingProblem    (36),
                       -- 37-47 не используются --
                  inappropriateAuthentication  (48),
                  invalidCredentials           (49),
                  insufficientAccessRights     (50),
                  busy                         (51),
                  unavailable                  (52),
                  unwillingToPerform           (53),
                  loopDetect                   (54),
                       -- 55-63 не используются --
                  namingViolation              (64),
                  objectClassViolation         (65),
                  notAllowedOnNonLeaf          (66),
                  notAllowedOnRDN              (67),
                  entryAlreadyExists           (68),
                  objectClassModsProhibited    (69),
                       -- 70 зарезервирован для CLDAP --
                  affectsMultipleDSAs          (71),
                       -- 72-79 не используются --
                  other                        (80),
                  ... },
             matchedDN          LDAPDN,
             diagnosticMessage  LDAPString,
             referral           [3] Referral OPTIONAL }

Нумерация кодов resultCode является расширяемой, как определено в разделе 3.8 [RFC4520]. Значение перечисленных результирующих кодов дано в приложении A. Если сервер обнаруживает при выполнении операции несколько ошибок, возвращается только один результирующий код. Сервер должен вернуть результирующий код, который наилучшим образом отражает характер возникшей ошибки. Серверы могут возвращать подмененные результирующие коды для предотвращения несанкционированного сбора сведений злоумышленниками.

Поле данной конструкции diagnosticMessage может, по усмотрению сервера, быть использовано для возврата строки, содержащей читабельное текстовое диагностическое сообщение (в нём следует избегать символов управления терминалом и форматирования страницы). Поскольку данное диагностическое сообщение не стандартизировано, реализации не должны (MUST NOT) полагаться на возвращаемые в этом поле значения. Обычно диагностические сообщения дополняют коды resultCode дополнительной информацией. Если сервер решает не возвращать текстовой диагностики, поле diagnosticMessage должно (MUST) быть пустым.

Для некоторых результирующих кодов (как правило, noSuchObject, aliasProblem, invalidDNSyntax и aliasDereferencingProblem, но не ограничиваясь только ими), в поле matchedDN помещается (по результатам контроля доступа) имя последней записи (объекта или псевдонима), которое используется для нахождения целевого (или базового) объекта. Это будет усечённая форма предоставленного имени, либо, если при попытке нахождения записи был разыменован псевдоним, то результирующего имени. В противном случае поле matchedDN остаётся пустым.

4.1.10. Отсылка (Referral)

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

Поле referral присутствует в конструкции LDAPResult, если поле resultCode установлено в referral, при всех остальных результирующих кодах оно отсутствует. Оно содержит одну или несколько отсылок на один или несколько серверов или сервисов, которые могут быть доступны посредством LDAP или других протоколов. Отсылки могут быть возвращены в ответ на запрос какой-либо операции (за исключением Unbind и Abandon, которые не возвращают ответов). В поле referral должен (MUST) присутствовать по меньшей мере один URI.

Во время операции поиска Search, после нахождения базового объекта baseObject и оценки записей, отсылка referral не возвращается. Вместо этого, если для завершения операции требуется обратиться к другим серверам, возвращаются ссылки-продолжения (continuation references), описанные в разделе 4.5.3.

        Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI

        URI ::= LDAPString     -- ограничена набором символов,
                               -- разрешённых в URI

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

Клиенты, следующие по отсылкам, должны (MUST) принимать меры по предотвращению зацикливания между серверами. Они не должны (MUST NOT) повторно обращаться к одному и тому же серверу с одними и теми же запросами с указанием в них одинаковых параметров. Некоторые клиенты используют счётчик, увеличивающийся на единицу каждый раз, когда во время операции происходит обработка отсылки. Клиенты такого типа должны (MUST) быть способны обрабатывать по крайней мере десять вложенных отсылок во время выполнения операции.

URI для сервера, реализующего LDAP и доступного по TCP/IP (v4 или v6) [RFC793][RFC791], записывается в виде LDAP URL в соответствии с [RFC4516].

Значения Referral, которые являются LDAP URL, подчиняются следующим правилам:

Могут быть возвращены и другие типы URI. Синтаксис и семантика таких URI оставлены как предмет будущих спецификаций. Клиенты могут игнорировать неподдерживаемые ими URI.

Закодированные в UTF-8 символы, добавляемые в строковое представление DN, поискового фильтра или других полей в значении поля referral, могут быть неразрешёнными для использования в URI (например, пробелы) и должны (MUST) быть экранированы с помощью % по методу, описанному в [RFC3986].

4.1.11. Элементы управления (Controls)

Элементы управления предоставляют механизм, с помощью которого семантика и аргументы существующих операций LDAP могут быть расширены. К одному сообщению LDAP могут быть присоединены один или несколько элементов управления. Действие элемента управления распространяется только на семантику того сообщения, к которому он присоединён.

Элементы управления, посылаемые клиентом, называются "элементами управления запроса" ("request controls"), а посылаемые сервером — "элементами управления ответа" ("response controls").

        Controls ::= SEQUENCE OF control Control

        Control ::= SEQUENCE {
             controlType             LDAPOID,
             criticality             BOOLEAN DEFAULT FALSE,
             controlValue            OCTET STRING OPTIONAL }

Поле controlType представляет собой точечно-цифровое представление идентификатора объекта OBJECT IDENTIFIER, уникально идентифицирующего данный элемент управления. Таким образом обеспечивается однозначность именования элементов управления. Часто элемент (элементы) управления ответа, предоставляемые в ответ на элемент управления запроса, разделяют с этим элементом управления запроса значения controlType.

Поле criticality имеет смысл только в элементах управления, присоединяемых к сообщениям запроса (за исключением UnbindRequest). Для элементов управления, присоединяемых к сообщениям ответа и UnbindRequest, поле criticality должно (SHOULD) быть установлено в FALSE, и должно (MUST) быть проигнорировано принимающей стороной протокола. Значение TRUE указывает на то, что выполнение операции без применения семантики элемента управления является неприемлемым. Конкретнее, обработка поля criticality выполняется следующим образом:

Поле controlValue может содержать информацию, связанную с типом controlType. Формат этого поля определяется спецификацией элемента управления. Реализации протокола должны (MUST) быть готовы обрабатывать строку октетов controlValue произвольного содержимого, в том числе нулевой длины. Это поле отсутствует только в случае, когда с элементом управления определённого типа не связано никакой информации в виде значения. Когда значение controlValue определено в терминах ASN.1 и закодировано BER в соответствии с разделом 5.1, оно также следует правилам расширяемости, приведённым в разделе 4.

Серверы перечисляют поддерживаемые ими типы controlType элементов управления запроса в атрибуте "supportedControl" записи root DSE (раздел 5.1 [RFC4512]).

Не следует (SHOULD NOT) объединять элементы управления, кроме случаев, когда семантика такого объединения была определена. Семантики объединения элементов управления, если таковые определены, как правило можно найти в спецификации элемента управления, опубликованной позднее остальных. Если встречается объединение элементов управления, семантика которого неверна, не определена (или неизвестна), сообщение считается плохо сформированным; таким образом, операция завершается неудачей с результирующим кодом protocolError. Элементы управления с полем criticality, установленным в FALSE, могут быть проигнорированы с целью получения допустимого сочетания. Кроме того, если в спецификации не указаны семантики, зависящие от порядка следования элементов управления, порядок комбинации элементов управления в последовательности SEQUENCE игнорируется. Там, где порядок следования элементов управления должен быть проигнорирован, но сервер не может его проигнорировать, сообщение считается плохо сформированным и операция завершается неудачей с результирующим кодом protocolError. Опять же, элементы управления с полем criticality, установленным в FALSE, могут быть проигнорированы с целью получения допустимого сочетания.

В этом документе не приводится спецификация никаких элементов управления. Элементы управления могут быть определены в других документах. Документы, описывающие расширения в виде элементов управления, должны предоставлять следующую информацию для каждого элемента управления:

4.2. Операция подсоединения Bind

Функция операции Bind — разрешить обмен аутентификационной информацией между клиентом и сервером. Операция Bind должна рассматриваться как операция "аутентификации". Операционные, аутентификационные и связанные с безопасностью семантики данной операции даны в [RFC4513].

Запрос Bind определяется следующим образом:

        BindRequest ::= [APPLICATION 0] SEQUENCE {
             version                 INTEGER (1 .. 127),
             name                    LDAPDN,
             authentication          AuthenticationChoice }

        AuthenticationChoice ::= CHOICE {
             simple                  [0] OCTET STRING,
                                     -- 1 и 2 зарезервированы
             sasl                    [3] SaslCredentials,
             ... }

        SaslCredentials ::= SEQUENCE {
             mechanism               LDAPString,
             credentials             OCTET STRING OPTIONAL }

Поля BindRequest:

Текстовые пароли (состоящие из последовательности символов с известным набором символов и кодировкой), передаваемые на сервер с использованием варианта simple конструкции AuthenticationChoice, должны (SHALL) передаваться как [Unicode], закодированный UTF-8 [RFC3629]. Перед передачей клиенту следует (SHOULD) подготовить текстовые пароли как строки запроса "query" путём применения к ним профиля SASLprep [RFC4013] алгоритма stringprep [RFC3454]. Пароли, состоящие из других данных (такие, как случайный набор октетов), не должны (MUST NOT) изменяться. Определение того, является ли пароль текстовым, возлагается на клиента.

4.2.1. Обработка запроса Bind

Перед обработкой запроса BindRequest все незавершённые операции должны (MUST) быть либо завершены, либо отброшены. Сервер может либо дождаться выполнения незавершённых операций, либо отбросить их. Затем сервер переходит к аутентификации клиента путём выполнения процесса подсоединения Bind в один или несколько шагов. На каждом шаге требуется, чтобы сервер возвращал ответ BindResponse для отображения статуса аутентификации.

После посылки запроса BindRequest клиенты не должны (MUST NOT) посылать дальнейших сообщений (PDU) LDAP до получения ответа BindResponse. Аналогичным образом, серверам не следует (SHOULD NOT) обрабатывать или отвечать на получаемые запросы во время обработки запроса BindRequest.

Если клиент не выполнял подсоединения перед отправкой запроса и получил в ответ на этот запрос сообщение с результирующим кодом operationsError, то после этого он может послать запрос BindRequest. Если этот запрос также завершился неудачей или клиент решил не выполнять подсоединения в рамках существующей сессии LDAP, он может завершить эту сессию LDAP, установить её заново и снова начать с посылки запроса BindRequest. Это может помочь при взаимодействии с серверами, на которых функционирует реализация других версий LDAP.

Клиенты могут посылать несколько запросов Bind для изменения аутентификации и/или ассоциаций безопасности, или для выполнения многоэтапного процесса Bind. Аутентификационные данные от предыдущих подсоединений при последующем подсоединении игнорируются.

Для некоторых механизмов аутентификации SASL клиенту может быть необходимо выполнить запрос BindRequest несколько раз (раздел 5.2 [RFC4513]). Клиенты не должны (MUST NOT) вызывать операции между двумя запросами Bind, выполняемыми как часть многоэтапного процесса Bind.

Клиент может прервать переговоры подсоединения SASL путём посылки запроса BindRequest с отличным от предыдущего значением в поле mechanism конструкции SaslCredentials, либо отличным от sasl значением поля AuthenticationChoice.

Если клиент посылает запрос BindRequest, в поле sasl mechanism которого пустая строка, сервер должен (MUST) вернуть ответ BindResponse с результирующим кодом resultCode, установленным в authMethodNotSupported. Это позволит клиенту прервать переговоры, если он хочет выполнить повторную попытку подсоединения с тем же самым механизмом SASL.

4.2.2. Ответ Bind

Ответ Bind определяется следующим образом:

        BindResponse ::= [APPLICATION 1] SEQUENCE {
             COMPONENTS OF LDAPResult,
             serverSaslCreds    [7] OCTET STRING OPTIONAL }

BindResponse представляет собой просто отчёт сервера о статусе клиентского запроса аутентификации.

Об удачном завершении операции Bind свидетельствует BindResponse с результирующим кодом resultCode, установленным в success. При ином исходе в BindResponse устанавливается соответствующий результирующий код. Результирующий код protocolError в BindResponse может использоваться для указания на то, что предоставленный клиентом номер версии не поддерживается.

Если клиент получает сообщение BindResponse, в котором resultCode установлено в protocolError, он должен считать, что сервер не поддерживает эту версию LDAP. Клиент может быть способен продолжить сессию с другой версией данного протокола (при этом может потребоваться или не потребоваться закрывать и вновь устанавливать транспортное соединения), однако описание того, как можно продолжить сессию с другой версией данного протокола, выходит за рамки этого документа. Клиентам, которые не в состоянии или не желают продолжать сессию, следует (SHOULD) завершить эту сессию LDAP.

Поле serverSaslCreds используется как часть определённого в SASL механизма подсоединения, чтобы позволить клиенту аутентифицировать сервер, с которым он взаимодействует, либо выполнить аутентификацию типа "вызов-ответ" ("challenge-response"). Если клиент выполнял подсоединение с механизмом simple, либо механизм SASL не требует, чтобы сервер возвращал информацию клиенту, то включать это поле в BindResponse не нужно (SHALL NOT).

4.3. Операция отсоединения Unbind

Назначение операции Unbind — завершение сессии LDAP. Операция Unbind не является противоположностью операции Bind, как можно предположить из названия. Наименования этих операций являются историческими. Операция Unbind должна рассматриваться как операция выхода "quit".

Операция Unbind определяется следующим образом:

       UnbindRequest ::= [APPLICATION 2] NULL

Клиент при передаче UnbindRequest и сервер при получении UnbindRequest должны корректно завершить сессию LDAP, как описано в разделе 5.3. Обработка незавершённых операций производится как описано в разделе 3.1.

4.4. Произвольное уведомление (Unsolicited Notification)

Произвольное уведомление — это сообщение LDAPMessage, посылаемое от сервера клиенту, которое не является ответом на какое-либо сообщение LDAPMessage, полученное этим сервером. Оно используется для сигнализации об экстраординарных условиях, возникших на сервере или в сессии LDAP между клиентом и сервером. Такое уведомление носит рекомендательный характер, и серверу не следует ожидать, что клиент вернёт на него какой-либо ответ.

Произвольное уведомление структурируется как сообщение LDAPMessage, в котором идентификатор messageID установлен в ноль и поле protocolOp установлено в extendedResp, в котором используется тип ExtendedResponse (смотрите раздел 4.12). Поле responseName конструкции ExtendedResponse всегда содержит уникальный для данного уведомления идентификатор объекта LDAPOID.

Одно из произвольных уведомлений, — уведомление об отключении (Notice of Disconnection), — определяется в данном документе. Спецификация произвольного уведомления состоит из:

4.4.1. Уведомление об отключении (Notice of Disconnection)

Это уведомление может быть использовано сервером, чтобы сообщить клиенту, что сервер собирается завершить сессию LDAP по своей инициативе. Назначение этого уведомления — помочь клиенту отличить возникшее на сервере состояние исключения от временной ошибки в сети. Имейте ввиду, что данное уведомление не является ответом на запрос Unbind клиента. Обработка незавершённых операций производится как описано в разделе 3.1.

Идентификатор Объекта в поле responseName — 1.3.6.1.4.1.1466.20036, поле responseValue отсутствует, а результирующий код resultCode используется для указания причины рассоединения. Если результирующий код resultCode, возвращаемый с этим сообщением, установлен в strongerAuthRequired, это указывает на то, что сервер определил, что в установленном защищённом соединении между клиентом и сервером возникла непредвиденная ошибка, или оно было скомпрометировано.

После отправки уведомления об отключении сервер корректно завершает сессию LDAP как описано в разделе 5.3.

4.5. Операция поиска Search

Операция Search используется для того, чтобы запросить сервер вернуть (после проверки контроля доступа и других ограничений) набор записей, соответствующих комплексному критерию поиска. Она может быть использована для получения атрибутов единственной записи, записей, непосредственно подчинённых какой-либо конкретной записи, либо всего поддерева записей.

4.5.1. Запрос Search

Запрос Search определяется следующим образом:

        SearchRequest ::= [APPLICATION 3] SEQUENCE {
             baseObject      LDAPDN,
             scope           ENUMERATED {
                  baseObject              (0),
                  singleLevel             (1),
                  wholeSubtree            (2),
                  ... },
             derefAliases    ENUMERATED {
                  neverDerefAliases       (0),
                  derefInSearching        (1),
                  derefFindingBaseObj     (2),
                  derefAlways             (3) },
             sizeLimit       INTEGER (0 .. maxInt),
             timeLimit       INTEGER (0 .. maxInt),
             typesOnly       BOOLEAN,
             filter          Filter,
             attributes      AttributeSelection }

        AttributeSelection ::= SEQUENCE OF selector LDAPString
                        -- строка LDAPString, ограниченная конструкцией
                        -- <attributeSelector> из раздела 4.5.1.8

        Filter ::= CHOICE {
             and             [0] SET SIZE (1..MAX) OF filter Filter,
             or              [1] SET SIZE (1..MAX) OF filter Filter,
             not             [2] Filter,
             equalityMatch   [3] AttributeValueAssertion,
             substrings      [4] SubstringFilter,
             greaterOrEqual  [5] AttributeValueAssertion,
             lessOrEqual     [6] AttributeValueAssertion,
             present         [7] AttributeDescription,
             approxMatch     [8] AttributeValueAssertion,
             extensibleMatch [9] MatchingRuleAssertion,
             ... }

        SubstringFilter ::= SEQUENCE {
             type           AttributeDescription,
             substrings     SEQUENCE SIZE (1..MAX) OF substring CHOICE {
                  initial [0] AssertionValue,  -- может вкючаться только один раз
                  any     [1] AssertionValue,
                  final   [2] AssertionValue } -- может вкючаться только один раз
             }

        MatchingRuleAssertion ::= SEQUENCE {
             matchingRule    [1] MatchingRuleId OPTIONAL,
             type            [2] AttributeDescription OPTIONAL,
             matchValue      [3] AssertionValue,
             dnAttributes    [4] BOOLEAN DEFAULT FALSE }

Имейте ввиду, что клиент может эмулировать операцию "list" X.500 путём запроса операции Search с диапазоном singleLevel и фильтром, проверяющим наличие атрибута objectClass, а операцию "read" X.500 — операцией Search с диапазоном baseObject и тем же самым фильтром. От сервера, работающего как шлюз к X.500, не требуется использовать операции Read или List; с другой стороны, он может сделать это, тогда он должен обеспечить те же семантики, что и в операции Search X.500.

4.5.1.1. SearchRequest.baseObject

Имя записи базового объекта (или, возможно, корневой записи), относительно которой должна быть выполнена операция поиска Search.

4.5.1.2. SearchRequest.scope

Указывает диапазон выполняемой операции Search. Семантика определённых для данного поля значений (как описано в [X.511]):

baseObject: диапазон ограничен записью, указанной в baseObject.

singleLevel: диапазон ограничен записями, непосредственно подчинёнными записи, указанной в baseObject.

wholeSubtree: диапазон ограничен записью, указанной в baseObject, и всеми подчинёнными ей записями.

4.5.1.3. SearchRequest.derefAliases

Индикатор того, должны или нет записи-псевдонимы (определённые в [RFC4512]) разыменовываться на этапах операции поиска Search.

Процедура разыменования псевдонимов включает в себя рекурсивное разыменование псевдонимов, которые ссылаются на другие псевдонимы.

Серверы должны (MUST) определять зацикливание в процессе разыменования псевдонимов в целях предотвращения атак типа "отказ от обслуживания" подобного рода.

Семантика определённых для данного поля значений:

neverDerefAliases: не разыменовывать псевдонимы при поиске или при определении местонахождения базового объекта поиска.

derefInSearching: при поиске среди подчинённых записей базового объекта, разыменовывать любые псевдонимы в рамках поискового диапазона. Разыменованные объекты становятся вершинами дальнейших диапазонов поиска, на которые также распространяется эта операция поиска Search. Если диапазон поиска — wholeSubtree, операция поиска Search продолжается по поддереву (поддеревьям) любого разыменованного объекта. Если диапазон поиска — singleLevel, операция поиска применяется к любым разыменованным объектам и не применяется к подчинённым им записям. Серверам следует (SHOULD) исключить дублирующиеся записи, появляющиеся в процессе разыменования псевдонимов при поиске.

derefFindingBaseObj: разыменовывать псевдонимы при определении местонахождения базового объекта поиска, но не при поиске подчинённых записей этого объекта.

derefAlways: разыменовывать псевдонимы и при поиске, и при определении местонахождения базового объекта поиска.

4.5.1.4. SearchRequest.sizeLimit

Ограничение по размеру, устанавливающее максимальное количество записей, которое будет возвращено в качестве результата операции Search. Значение ноль в этом поле означает, что никакие запрашиваемые клиентом ограничения по размеру не распространяются на данную операцию Search. Сервер также может принудительно установить максимальное количество записей, которое он будет возвращать.

4.5.1.5. SearchRequest.timeLimit

Ограничение по времени, устанавливающее максимальное время (в секундах), которое отводится на выполнение операции Search. Значение ноль в этом поле означает, что никакие запрашиваемые клиентом ограничения по времени не распространяются на данную операцию Search. Сервер также может принудительно установить максимальное время выполнения операции Search.

4.5.1.6. SearchRequest.typesOnly

Индикатор того, должны ли результаты операции Search содержать и описания атрибутов, и значения, либо только описания атрибутов. Установка этого поля в TRUE приведёт к возврату только описаний атрибутов (без значений). Установка этого поля в FALSE приведёт к возврату и описаний атрибутов, и значений.

4.5.1.7. SearchRequest.filter

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

Для формирования комбинаций фильтров могут быть использованы пункты "and", "or" и "not". Как минимум один элемент фильтра должен (MUST) присутствовать при использовании пунктов "and" или "or". Элементы фильтра предназначены для нахождения совпадений значений индивидуальных атрибутов записей в диапазоне поиска. (Примечание для тех, кто занимается реализацией: фильтр "not" является примером поименованного пункта в модуле с неявным именованием. В BER это интерпретируется как явное именование.)

Сервер должен (MUST) оценить фильтры в соответствии с трехзначной логикой согласно пункта 7.8.1 стандарта [X.511] (1993). Если коротко, фильтр оценивается как "TRUE", "FALSE" или "Undefined". Если фильтр оценивается как TRUE для конкретной записи, то атрибуты такой записи возвращаются как часть результата операции Search (после проверки на соответствие любым применимым к записи ограничениям контроля доступа). Если фильтр оценивается как FALSE или Undefined, то для этой операции Search запись игнорируется.

Фильтр с пунктом "and" оценивается как TRUE, если все фильтры в наборе SET OF оцениваются как TRUE, и как FALSE, если хотя бы один фильтр оценивается как FALSE; в противном случае такой фильтр оценивается как Undefined. Фильтр с пунктом "or" оценивается как FALSE, если все фильтры в наборе SET OF оцениваются как FALSE, и как TRUE, если хотя бы один фильтр оценивается как TRUE; в противном случае такой фильтр оценивается как Undefined. Фильтр с пунктом "not" оценивается как TRUE, если подвергаемый отрицанию фильтр оценивается как FALSE; как FALSE, если подвергаемый отрицанию фильтр оценивается как TRUE, и как Undefined, если подвергаемый отрицанию фильтр оценивается как Undefined.

Фильтр оценивается как Undefined, когда сервер не в состоянии определить, соответствует ли значение утверждения записи. Возможные примеры:

Например, если сервер не распознаёт тип атрибута shoeSize, то каждый из фильтров (shoeSize=*), (shoeSize=12), (shoeSize>=12) и (shoeSize<=12) будет оцениваться как Undefined.

Серверы не должны (MUST NOT) возвращать ошибок, если они не могут распознать описания атрибутов или идентификаторы правил соответствия, определяют неверное значение утверждения или не поддерживают синтаксис утверждения. Дополнительные подробности обработки фильтров приведены в пункте 7.8 стандарта [X.511].

4.5.1.7.1. SearchRequest.filter.equalityMatch

Правило соответствия для фильтра equalityMatch определяется правилом соответствия EQUALITY для типа или подтипа атрибута. Фильтр оценивается как TRUE, когда правило EQUALITY, при применении его к типу или подтипу атрибута и заявленному значению, возвращает TRUE.

4.5.1.7.2. SearchRequest.filter.substrings

Должно (SHALL) быть не более одного пункта "initial" и не более одного пункта "final" в последовательности "substrings" конструкции SubstringFilter. Если присутствует пункт "initial", он должен (SHALL) быть первым элементом последовательности "substrings". Если присутствует пункт "final", он должен (SHALL) быть последним элементом последовательности "substrings".

Правило соответствия для AssertionValue в пункте фильтра substrings определяется правилом соответствия SUBSTR для типа или подтипа атрибута. Фильтр оценивается как TRUE, когда правило SUBSTR, при применении его к типу или подтипу атрибута и заявленному значению, возвращает TRUE.

Обратите внимание, что AssertionValue в пункте фильтра substrings соответствует синтаксису утверждения правила соответствия EQUALITY для типа атрибута, а не синтаксису утверждения правила соответствия SUBSTR для типа атрибута. Концептуально, перед применением правила вся конструкция SubstringFilter преобразуется в значение утверждения согласно правилу соответствия substrings.

4.5.1.7.3. SearchRequest.filter.greaterOrEqual

Правило соответствия для фильтра greaterOrEqual определяется правилом соответствия ORDERING для типа или подтипа атрибута. Фильтр оценивается как TRUE, когда правило ORDERING, при применении его к типу или подтипу атрибута и заявленному значению, возвращает FALSE.

4.5.1.7.4. SearchRequest.filter.lessOrEqual

Правило соответствия для фильтра lessOrEqual определяется правилами соответствия ORDERING и EQUALITY для типа или подтипа атрибута. Фильтр оценивается как TRUE, когда либо правило ORDERING, либо правило EQUALITY, при применении их к типу или подтипу атрибута и заявленному значению, возвращают TRUE.

4.5.1.7.5. SearchRequest.filter.present

Фильтр present оценивается как TRUE, когда в записи присутствует тип или подтип атрибута, соответствующий указанному описанию типа атрибута AttributeDescription; и как FALSE, когда в записи не присутствует тип или подтип атрибута, соответствующий указанному описанию типа атрибута, в противном случае такой фильтр оценивается как Undefined.

4.5.1.7.6. SearchRequest.filter.approxMatch

Фильтр approxMatch оценивается как TRUE, когда присутствует значение типа или подтипа атрибута, для которого некоторый локально определённый алгоритм нахождения приблизительного соответствия (например, по вариантам написания, по фонетическому соответствию, и т.п.) возвращает TRUE. Если значение соответствует фильтру equality, оно также удовлетворяет соответствию approximate. Если для атрибута не поддерживается нахождение соответствия approximate, этот пункт фильтра должен интерпретироваться как equalityMatch.

4.5.1.7.7. SearchRequest.filter.extensibleMatch

Поля пункта фильтра extensibleMatch оцениваются следующим образом:

Используемое для оценки правило соответствия matchingRule определяет синтаксис для значения утверждения. После того, как были определены matchingRule и атрибут (атрибуты), пункт фильтра оценивается как TRUE, если найдено соответствие хотя бы с одним типом или подтипом атрибута в записи; как FALSE, если не найдено соответствие ни с одним типом или подтипом атрибута в записи; и как Undefined, если правило соответствия matchingRule не распознано, не может быть использовано с указанным типом type, либо значение assertionValue не верно.

4.5.1.8. SearchRequest.attributes

Список атрибутов, которые должны быть возвращены для каждой записи, соответствующей поисковому фильтру. Атрибуты, которые являются подтипами перечисленных атрибутов, также неявно включаются в этот список. На строковые значения LDAPString этого поля накладываются ограничения по следующей расширенной форме Бэкуса-Наура (ABNF) [RFC4234]:

      attributeSelector = attributedescription / selectorspecial

      selectorspecial = noattrs / alluserattrs

      noattrs = %x31.2E.31 ; "1.1"

      alluserattrs = %x2A ; asterisk ("*")

Конструкция <attributedescription> определена в разделе 2.5 of [RFC4512].

В списке атрибутов могут фигурировать три особых случая:

  1. Запросы с пустым списком (без атрибутов) возвращают все пользовательские атрибуты.
  2. Запросы со списком, содержащим "*" (с нулём или более описаний атрибутов), возвращают все пользовательские атрибуты в дополнение к другим перечисленным (операционным) атрибутам.
  3. Список, содержащий только OID "1.1", указывает на то, что никаких атрибутов возвращено не будет. Если кроме "1.1" предоставляются другие значения attributeSelector, значение attributeSelector "1.1" игнорируется. Данный OID был выбран потому, что он не соответствует (и не может соответствовать) никакому используемому атрибуту.

Те, кто занимается реализацией клиентов, должны иметь ввиду, что даже если были запрошены все атрибуты, в результат операции Search могут быть не включены некоторые атрибуты и/или значения атрибутов записи из-за контроля доступа или иных ограничений. Кроме того, серверы не будут возвращать операционных атрибутов, таких как objectClasses или attributeTypes, кроме тех из них, которые были явно указаны по имени. Операционные атрибуты описаны в [RFC4512].

Атрибуты в записи возвращаются не более одного раза. Если описание атрибута указывается в списке более одного раза, повторно встретившиеся имена игнорируются. Если описание атрибута в списке не распознаётся, оно игнорируется сервером.

4.5.2. Результат операции Search

Результаты операции Search возвращаются в виде нуля или более сообщений SearchResultEntry и/или сообщений SearchResultReference, за которыми следует единственное сообщение SearchResultDone.

        SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
             objectName      LDAPDN,
             attributes      PartialAttributeList }

        PartialAttributeList ::= SEQUENCE OF
                             partialAttribute PartialAttribute

        SearchResultReference ::= [APPLICATION 19] SEQUENCE
                                  SIZE (1..MAX) OF uri URI

        SearchResultDone ::= [APPLICATION 5] LDAPResult

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

Каждая запись, возвращаемая в сообщении SearchResultEntry, будет содержать все соответствующие атрибуты, указанные в поле attributes запроса Search, по результатам применения к ним контроля доступа и другой административной политики. Имейте ввиду, что последовательность PartialAttributeList может содержать ноль элементов. Такое может произойти, когда ни один из атрибутов записи не был запрошен или не может быть возвращён. Также имейте ввиду, что набор значений partialAttribute может содержать ноль элементов. Такое может произойти при запросе с выставленным полем typesOnly, если контроль доступа не допускает возврата значений или по другим причинам.

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

Если в схеме данных сервера определены сокращённые имена типов атрибутов [RFC4512], то серверу следует (SHOULD) использовать одно из таких имён в описаниях атрибутов для такого типа атрибута (это предпочтительнее использования формата идентификатора объекта <numericoid> [RFC4512] типа атрибута). Серверу не следует (SHOULD NOT) использовать сокращённое имя, если ему известно, что это имя неоднозначно или может каким-либо иным способом привести к проблемам совместимости.

4.5.3. Ссылки-продолжения (Continuation References) в результатах операции Search

Если сервер смог определить расположение записи, на которую указывает поле baseObject запроса, но не может или не желает осуществлять поиск одной или нескольких нелокальных записей, он может вернуть одно или несколько сообщений SearchResultReference, каждое из которых содержит ссылку на другой набор серверов для продолжения операции. Сервер не должен (MUST NOT) возвращать какие-либо сообщения SearchResultReference, если он не определил расположение объекта baseObject, и, следовательно, не нашёл ни одной записи. В этом случае он должен вернуть сообщение SearchResultDone, содержащее либо отсылку, либо результирующий код noSuchObject (в зависимости от того, обладает ли сервер знаниями относительно записи, указанной в baseObject).

Если сервер хранит копию или частичную копию нижестоящего (подчинённого) контекста именования (раздел 5 of [RFC4512]), он может использовать поисковый фильтр для определения того, возвращать или нет ответ SearchResultReference. В противном случае ответы SearchResultReference возвращаются всегда, если область, на которую указывает ссылка, находится в диапазоне поиска.

Тип данных SearchResultReference тот же, что и у отсылок Referral.

Если клиент желает продолжить поиск, он запрашивает новую операцию Search для каждого из возвращённых сообщений SearchResultReference. Если в сообщении присутствуют несколько URI, клиент подразумевает, что любой из поддерживаемых URI может быть использован для продолжения операции.

Клиенты, которые следуют по поисковым ссылкам-продолжениям, должны (MUST) принимать меры по предотвращению зацикливания между серверами. Они не должны (MUST NOT) повторно обращаться к одному и тому же серверу с одними и теми же запросами с указанием в них одинаковых параметров. Некоторые клиенты используют счётчик, увеличивающийся на единицу каждый раз, когда во время операции происходит обработка поисковой ссылки-продолжения. Клиенты такого типа должны (MUST) быть способны обрабатывать по крайней мере десять вложенных отсылок во время выполнения операции.

Имейте ввиду, что операция Abandon, описанная в разделе 4.11, применяется только к конкретной операции, отправляемой между клиентом и сервером на уровне сообщений LDAP. Клиент должен отдельно отменять последующие операции Search, от которых он хочет отказаться.

URI для сервера, реализующего LDAP и доступного по TCP/IP (v4 или v6) [RFC793][RFC791], записывается в виде LDAP URL в соответствии с [RFC4516].

Значения SearchResultReference, которые являются LDAP URL, подчиняются следующим правилам:

Могут быть возвращены и другие типы URI. Синтаксис и семантика таких URI оставлены как предмет будущих спецификаций. Клиенты могут игнорировать неподдерживаемые ими URI.

Закодированные в UTF-8 символы, добавляемые в строковое представление DN, поискового фильтра или других полей в значении ссылки, могут быть неразрешёнными для использования в URI (например, пробелы) и должны (MUST) быть экранированы с помощью % по методу, описанному в [RFC3986].

4.5.3.1. Примеры

Для примера, предположим, что на сервере, к которому происходит обращение (hosta), хранятся записи <DC=Example,DC=NET> и <CN=Manager,DC=Example,DC=NET>. Этот сервер знает, что на двух других LDAP-серверах (hostb) и (hostc) (один из них главный (master), а второй — теневая копия) хранится <OU=People,DC=Example,DC=NET>, а на LDAP-совместимом сервере (hostd) хранится поддерево <OU=Roles,DC=Example,DC=NET>. Если на сервере, к которому происходит обращение, был запрошен поиск Search по <DC=Example,DC=NET> с диапазоном wholeSubtree, он может вернуть следующее:

     SearchResultEntry for DC=Example,DC=NET
     SearchResultEntry for CN=Manager,DC=Example,DC=NET
     SearchResultReference {
       ldap://hostb/OU=People,DC=Example,DC=NET??sub
       ldap://hostc/OU=People,DC=Example,DC=NET??sub }
     SearchResultReference {
       ldap://hostd/OU=Roles,DC=Example,DC=NET??sub }
     SearchResultDone (success)

Тем, кто занимается реализацией клиентов, следует иметь ввиду, что при следовании по ссылкам из сообщения SearchResultReference могут быть сгенерированы дополнительные сообщения SearchResultReference. В продолжение нашего примера, если клиент обращается к серверу (hostb) и выполняет запрос Search по поддереву <OU=People,DC=Example,DC=NET>, этот сервер может ответить следующим образом:

     SearchResultEntry for OU=People,DC=Example,DC=NET
     SearchResultReference {
       ldap://hoste/OU=Managers,OU=People,DC=Example,DC=NET??sub }
     SearchResultReference {
       ldap://hostf/OU=Consultants,OU=People,DC=Example,DC=NET??sub }
     SearchResultDone (success)

Другой вариант, если на сервере, к которому происходит обращение, был запрошен поиск Search по <DC=Example,DC=NET> с диапазоном singleLevel, он может вернуть следующее:

     SearchResultEntry for CN=Manager,DC=Example,DC=NET
     SearchResultReference {
       ldap://hostb/OU=People,DC=Example,DC=NET??base
       ldap://hostc/OU=People,DC=Example,DC=NET??base }
     SearchResultReference {
       ldap://hostd/OU=Roles,DC=Example,DC=NET??base }
     SearchResultDone (success)

Если на сервере, к которому происходит обращение, не содержится базовый объект поиска Search, но у него есть информация о его возможном местонахождении, то он может вернуть клиенту отсылку referral. В этом случае, если клиент запрашивает у сервера hosta поиск Search по поддереву <DC=Example,DC=ORG>, сервер возвращает сообщение SearchResultDone, содержащее отсылку:

     SearchResultDone (referral) {
       ldap://hostg/DC=Example,DC=ORG??sub }

4.6. Операция модификации Modify

Операция модификации Modify позволяет клиенту запросить, чтобы сервер выполнил модификацию записи от его имени. Запрос Modify определяется следующим образом:

        ModifyRequest ::= [APPLICATION 6] SEQUENCE {
             object          LDAPDN,
             changes         SEQUENCE OF change SEQUENCE {
                  operation       ENUMERATED {
                       add     (0),
                       delete  (1),
                       replace (2),
                       ... },
                  modification    PartialAttribute } }

Поля запроса Modify:

После получения запроса Modify сервер пытается выполнить необходимые модификации в DIT и возвращает результат в ответе Modify Response, который определяется следующим образом:

        ModifyResponse ::= [APPLICATION 7] LDAPResult

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

Серверы должны (MUST) обеспечить, чтобы записи удовлетворяли правилам пользовательской и системной схемы данных, а также другим ограничениям модели данных. Операция Modify не может быть использована для удаления из записи каких-либо её уникальных (отличительных) значений, то есть тех значений, которые формируют относительное уникальное имя записи. Попытка сделать это приведёт к тому, что сервер вернёт результирующий код notAllowedOnRDN. Для переименования записи используется операция модификации уникального имени (Modify DN), описанная в разделе 4.9.

Типы атрибутов, для которых не определено соответствие equality, подчиняются правилам из раздела 2.5.1 [RFC4512].

Обратите внимание, что в связи со сделанными в LDAP упрощениями, нет прямого отображения изменений посредством запроса LDAP ModifyRequest в изменения посредством операции DAP ModifyEntry, и различные реализации шлюзов LDAP-DAP могут использовать различные средства представления этих изменений. В случае успешного завершения изменений, окончательный эффект от выполнения этих операций над записью должен (MUST) быть идентичен.

4.7. Операция добавления Add

Операция Add позволяет клиенту запросить добавление записи в каталог. Запрос Add определяется следующим образом:

        AddRequest ::= [APPLICATION 8] SEQUENCE {
             entry           LDAPDN,
             attributes      AttributeList }

        AttributeList ::= SEQUENCE OF attribute Attribute

Поля запроса Add:

Серверы должны (MUST) обеспечить, чтобы записи удовлетворяли правилам пользовательской и системной схемы данных, а также другим ограничениям модели данных. Типы атрибутов, для которых не определено соответствие equality, подчиняются правилам из раздела 2.5.1 [RFC4512] (это относится к атрибуту именования и, кроме того, к любым добавляемым многозначным атрибутам).

Для успешного выполнения запроса AddRequest запись, имя которой указано в поле entry этого запроса, не должна (MUST NOT) существовать. Непосредственно вышестоящая (родительская) запись добавляемой записи объекта или псевдонима должна (MUST) существовать. Например, если клиент пытается добавить <CN=JS,DC=Example,DC=NET>, запись <DC=Example,DC=NET> не существует, а запись <DC=NET> существует, то сервер вернёт результирующий код noSuchObject, а поле matchedDN конструкции LDAPResult будет содержать <DC=NET>.

При получении запроса Add сервер попытается добавить указанную запись. Результат попытки добавления будет возвращён клиенту в ответе Add Response, который определяется следующим образом:

        AddResponse ::= [APPLICATION 9] LDAPResult

Ответ с кодом success указывает на то, что новая запись была добавлена в каталог.

4.8. Операция удаления Delete

Операция Delete позволяет клиенту запросить удаление записи из каталога. Запрос Delete определяется следующим образом:

        DelRequest ::= [APPLICATION 10] LDAPDN

Запрос Delete состоит из имени записи, которую требуется удалить. Серверу не нужно (SHALL NOT) выполнять разыменования псевдонимов при определении имени целевой записи для удаления.

С помощью этой операции могут быть удалены только листовые записи (у которых нет нижестоящих (подчинённых) записей).

При получении запроса Delete сервер попытается выполнить удаление указанной записи и результат будет возвращён клиенту в ответе Delete Response, который определяется следующим образом:

        DelResponse ::= [APPLICATION 11] LDAPResult

4.9. Операция модификации уникального имени Modify DN

Операция Modify DN позволяет клиенту изменить относительное уникальное имя (Relative Distinguished Name, RDN) записи в каталоге и/или переместить поддерево записей в новое местоположение в каталоге. Запрос Modify DN определяется следующим образом:

        ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
             entry           LDAPDN,
             newrdn          RelativeLDAPDN,
             deleteoldrdn    BOOLEAN,
             newSuperior     [0] LDAPDN OPTIONAL }

Поля запроса Modify DN:

Серверу не нужно (SHALL NOT) выполнять какие-либо разыменования псевдонимов для определения местоположения объектов, имена которых указаны в полях entry или newSuperior.

При получении запроса ModifyDNRequest сервер попытается выполнить изменение имени и вернуть результат в ответе Modify DN Response, который определяется следующим образом:

        ModifyDNResponse ::= [APPLICATION 13] LDAPResult

Например, если имя записи, указанное в поле entry, было <cn=John Smith,c=US>, в поле newrdn было <cn=John Cougar Smith>, а поле newSuperior отсутствовало, то данная операция выполнила бы попытку переименовать запись в <cn=John Cougar Smith,c=US>. Если запись с таким именем уже существовала, операция бы закончилась неудачей с результирующим кодом entryAlreadyExists.

Серверы должны (MUST) обеспечить, чтобы записи удовлетворяли правилам пользовательской и системной схемы данных, а также другим ограничениям модели данных. Типы атрибутов, для которых не определено соответствие equality, подчиняются правилам из раздела 2.5.1 [RFC4512] (это относится к полям newrdn и deleteoldrdn).

Объект, имя которого указано в newSuperior должен (MUST) существовать. Например, если клиент пытается добавить <CN=JS,DC=Example,DC=NET>, а запись <DC=Example,DC=NET> не существует, но существует запись <DC=NET>, то сервер вернёт результирующий код noSuchObject, а поле matchedDN конструкции LDAPResult будет содержать <DC=NET>.

Если поле deleteoldrdn установлено в TRUE, значения атрибутов, формировавшие старое RDN (но не входящие в новое RDN), удаляются из записи. Если поле deleteoldrdn установлено в FALSE, значения атрибутов, формировавшие старое RDN, будут сохранены как неотличительные значения атрибутов записи.

Имейте ввиду, что стандарт X.500 накладывает ограничение: операция ModifyDN может влиять только на перемещение записей в пределах одного сервера. Если сервер LDAP отображается на DAP, то будет применяться это ограничение, и при возникновении ошибки вследствие его нарушения будет возвращаться результирующий код affectsMultipleDSAs. В общем случае, клиенты не должны (MUST NOT) рассчитывать на то, что они смогут выполнить произвольное перемещение записей и поддеревьев между серверами или контекстами именования.

4.10. Операция сравнения Compare

Операция Compare позволяет клиенту сравнить значение утверждения со значениями конкретного атрибута конкретной записи в каталоге. Запрос Compare определяется следующим образом:

        CompareRequest ::= [APPLICATION 14] SEQUENCE {
             entry           LDAPDN,
             ava             AttributeValueAssertion }

Поля запроса Compare:

При получении запроса Compare сервер попытается выполнить заданное сравнение и вернуть результат в ответе Compare Response, который определяется следующим образом:

        CompareResponse ::= [APPLICATION 15] LDAPResult

Результирующий код resultCode может быть устновлен в compareTrue, compareFalse или в значение, соответствующее возникшей ошибке. Код compareTrue указывает на то, что значение утверждения в поле ava совпадает со значением типа или подтипа атрибута согласно правилу соответствия EQUALITY этого атрибута. Код compareFalse указывает на то, что значение утверждения в поле ava и значение типа или подтипа атрибута не совпадают. Другие результирующие коды указывают либо на то, что результат сравнения был Undefined (раздел 4.5.1.7), либо на возникновение какой-либо ошибки.

Имейте ввиду, что некоторые системы каталогов могут устанавливать контроль доступа, разрешающий сравнения со значениями некоторых атрибутов (таких как userPassword), при этом другие действия с этими атрибутами могут быть запрещены.

4.11. Операция отказа Abandon

Назначение операции Abandon — позволить клиенту запросить сервер отказаться от выполнения незавершённой операции. Запрос Abandon определяется следующим образом:

        AbandonRequest ::= [APPLICATION 16] MessageID

MessageID — это идентификатор сообщения той операции, которая была запрошена ранее на данном уровне сообщений LDAP. У самого запроса Abandon есть свой собственный идентификатор сообщения MessageID. Он отличается от идентификатора MessageID ранее запрошенной операции, от выполнения которой требуется отказаться.

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

Невозможно отказаться от операций Abandon, Bind, Unbind и StartTLS.

В случае получения сервером запроса Abandon для отказа от операции Search, когда он уже производит передачу ответов на запрос Search, этот сервер должен (MUST) немедленно прекратить передачу ответов-записей того запроса, который был отменён, и он не должен (MUST NOT) отправлять ответ SearchResultDone. Естественно, сервер должен (MUST) обеспечить передачу только должным образом закодированных PDU сообщений LDAPMessage.

Решение о возможности отказа от других операций (в частности, операций обновления каталога) оставляется на усмотрение сервера.

Клиентам не следует несколько раз посылать запросы Abandon для одной и той же операции, и они также должны (MUST) быть готовы получить результаты от операций, от которых они отказывались (поскольку те могли уже передаваться, когда была запрошена операция Abandon, либо невозможно было выполнить отказ).

Серверы должны (MUST) отбрасывать запросы Abandon для тех MessageID, которые они не могут распознать, для операций, от которых нельзя отказаться, и для операций, отказ от которых уже произошёл.

4.12. Расширенная операция Extended

Операция Extended позволяет определить дополнительные операции помимо тех, которые уже определены в протоколе; например, добавить операции для установки Transport Layer Security (смотрите раздел 4.14).

Операция Extended позволяет клиентам выполнять запросы и получать ответы с предопределёнными синтаксисами и семантиками. Эти синтаксисы и семантики могут быть определены в RFC, либо определяться в частном порядке для конкретных реализаций.

Каждая операция Extended состоит из запроса Extended и ответа Extended.

        ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
             requestName      [0] LDAPOID,
             requestValue     [1] OCTET STRING OPTIONAL }

В поле requestName содержится точечно-цифровое представление соответствующего запросу уникального идентификатора объекта OBJECT IDENTIFIER. В поле requestValue — информация, форма которой определяется этим запросом, инкапсулированная в строку октетов OCTET STRING.

На этот запрос сервер ответит сообщением LDAPMessage, содержащим ответ ExtendedResponse.

        ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
             COMPONENTS OF LDAPResult,
             responseName     [10] LDAPOID OPTIONAL,
             responseValue    [11] OCTET STRING OPTIONAL }

Поле responseName, при его наличии, содержит идентификатор LDAPOID, уникальный для данной расширенной операции или её ответа. Это поле является опциональным (даже когда в спецификации расширения определён LDAPOID для использования в этом поле). Это поле будет отсутствовать, когда сервер не может или не желает определить, какой именно LDAPOID вернуть, например, если невозможно разобрать requestName, либо его значение не распознано.

Если не распознан идентификатор в requestName, сервер возвращает protocolError. (Сервер может вернуть protocolError и в других случаях.)

Поля requestValue и responseValue содержат связанную с операцией информацию. Формат этих полей определяется спецификацией операции-расширения Extended. Реализации должны (MUST) быть готовы обработать произвольное содержимое этих полей, в том числе и нулевой длины. Значения, которые определяются в терминах ASN.1 и закодированы BER в соответствии с разделом 5.1, также следуют правилам расширяемости, приведённым в разделе 4.

Серверы перечисляют идентификаторы requestName тех запросов Extended Request, которые они могут распознать, в атрибуте 'supportedExtension' записи root DSE (раздел 5.1 [RFC4512]).

Операции-расширения Extended могут быть определены в других документах. Спецификация операции-расширения Extended включает в себя:

4.13. Промежуточное ответное сообщение IntermediateResponse

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

Сообщение IntermediateResponse предоставляет общий механизм для определения операций типа "один запрос/несколько ответов" в LDAP. Данное сообщение предназначено для использования в сочетании с расширенной операцией Extended для определения новых операций типа "один запрос/несколько ответов", либо в сочетании с элементом управления, когда расширение существующих операций LDAP осуществляется таким образом, что от них требуется возвращать промежуточную ответную информацию.

Предполагается, что в определениях и описаниях операций-расширений Extended и элементов управления, в которых будут использоваться промежуточные сообщения IntermediateResponse, будут определены условия, при которых сервером могут посылаться сообщения IntermediateResponse, а также разъяснение того, что означает посылка сообщения IntermediateResponse при наступлении конкретного условия.

        IntermediateResponse ::= [APPLICATION 25] SEQUENCE {
                responseName     [0] LDAPOID OPTIONAL,
                responseValue    [1] OCTET STRING OPTIONAL }

Не нужно (SHALL NOT) возвращать клиенту сообщений IntermediateResponse, если клиент не посылает запрос, в котором специально требуется их возвращение. В этом документе определяются две формы таких затребований: в расширенной операции Extended и в элементе управления запроса. При определении сообщений IntermediateResponse в каких-либо документах, оговаривается манера, в которой будет затребоваться возвращение этих сообщений (то есть, в спецификации операции-расширения Extended или элемента управления запроса, которые их используют). Такие спецификации включают в себя:

Расширениям, позволяющим возвращать несколько типов сообщений IntermediateResponse, нужно (SHALL) идентифицировать эти типы с помощью уникальных значений в поле responseName (причём в одном из этих сообщений, по спецификации, значение в поле responseName может отсутствовать).

В разделах 4.13.1 и 4.13.2 описаны дополнительные требования к включению полей responseName и responseValue в сообщения IntermediateResponse.

4.13.1. Использование с LDAP ExtendedRequest и ExtendedResponse

Операция типа "один запрос/несколько ответов" может быть определена так, чтобы в ней использовалось одно сообщение ExtendedRequest, в котором затребуется ноль или более однотипных или разнотипных сообщений IntermediateResponse, за которыми следует сообщение ExtendedResponse.

4.13.2. Использование с элементами управления запросов LDAP

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

Во все сообщения IntermediateResponse, ассоциированные с элементами управления запросов, нужно (SHALL) включать поле responseName. Выполнение этого требования гарантирует, что клиент сможет корректно идентифицировать источник сообщений IntermediateResponse, когда:

4.14. Операция StartTLS

Предназначение операции Start Transport Layer Security (StartTLS) — инициировать установление уровня TLS. Операция StartTLS определена с использованием механизма расширенной операции Extended, описанной в разделе 4.12.

4.14.1. Запрос StartTLS

Клиент запрашивает установление TLS путём отправки серверу сообщения с запросом StartTLS. Запрос StartTLS определяется в терминах запроса операции-расширения ExtendedRequest. Идентификатор requestName — "1.3.6.1.4.1.1466.20037", а поле requestValue всегда отсутствует.

Клиент не должен (MUST NOT) посылать вслед за этим запросом каких-либо LDAP PDU на данном уровне сообщений LDAP до получения ответа операции-расширения StartTLS, и, в случае ответа с успешным статусом, до завершения переговоров TLS.

При обнаружении проблем с последовательностью выполнения операций (в частности тех, которые описаны в разделе 3.1.1 [RFC4513]) результирующий код resultCode ответа должен быть установлен в operationsError.

Если сервер не поддерживает TLS (в силу конструктивных особенностей или текущих настроек), он возвращает ответ с результирующим кодом resultCode, установленным в protocolError, как описано в разделе 4.12.

4.14.2. Результат операции StartTLS

При получении запроса StartTLS, сервер, поддерживающий данную операцию, должен (MUST) вернуть запрашивающему клиенту ответное сообщение StartTLS. Идентификатор responseName, если таковой предоставляется (смотрите раздел 4.12), — "1.3.6.1.4.1.1466.20037". Поле responseValue всегда отсутствует.

Если сервер желает и способен вести переговоры TLS, он возвращает ответ StartTLS, результирующий код resultCode которого установлен success. При получении клиентом ответа StartTLS с успешным статусом стороны могут начать переговоры TLS как описано в разделе 3 [RFC4513].

В противном случае, если сервер не желает или не способен выполнить данную операцию, он должен вернуть соответствующий результирующий код, указывающий на характер проблемы. Например, если подсистема TLS в настоящее время не доступна, сервер может указать на это путём возврата сообщения с результирующим кодом resultCode, установленным в unavailable. В тех случаях, когда возвращён ответ с неуспешным результирующим кодом, сессия LDAP продолжается без уровня TLS.

4.14.3. Снятие уровня TLS

Как клиент, так и сервер может (MAY) снять уровень TLS (прекратить его использование) и продолжить работу с "чистым" уровнем сообщений LDAP путём отправки и получения оповещения о закрытии TLS (TLS closure alert).

Сторона-инициатор посылает оповещение о закрытии TLS и должна (MUST) ожидать, пока не получит оповещение о закрытии TLS от другой стороны, прежде чем посылать дальнейшие LDAP PDU.

Когда одна из сторон получает начальное оповещение о закрытии TLS, она может избрать вариант продолжения работы с "чистым" уровнем сообщений LDAP. В этом случае она должна (MUST) немедленно передать оповещение о закрытии TLS. Вслед за этим она может (MAY) посылать и принимать LDAP PDU.

Стороны могут (MAY) завершить данную сессию LDAP после отправки и получения оповещения о закрытии TLS.

5. Кодирование протокола, соединения и передача данных

Этот протокол предназначен для работы поверх ориентированных на соединение, надежных транспортов, где поток данных делится на октеты (блоки по 8 бит), и значимым является каждый октет и каждый бит.

Один из таких сервисов, LDAP поверх TCP, определён в разделе 5.2.

Данный сервис, как правило, применим к приложениям, которые являются поставщиками или потребителями основанных на X.500 служб каталогов в Интернет. Данная спецификация в основном создавалась с расчётом на отображение в TCP.

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

Реализации LDAP поверх TCP должны (MUST) осуществлять это отображение так, как описано в разделе 5.2.

Данная схема показывает взаимосвязь между разными уровнями, участвующими в обмене между сторонами протокола:

               +--------------------------+
               |  уровень сообщений LDAP  |
               +--------------------------+ > LDAP PDU
               +--------------------------+ < данные
               |       уровень SASL       |
               +--------------------------+ > данные, защищённые SASL
               +--------------------------+ < данные
               |       уровень TLS        |
    Приложение +--------------------------+ > данные, защищённые TLS
   ------------+--------------------------+ < данные
     Транспорт | транспортное  соединение |
               +--------------------------+

5.1. Кодирование протокола

Для обмена элементами протокола LDAP их нужно (SHALL) кодировать с использованием основных правил кодирования Basic Encoding Rules [BER] [ASN.1] со следующими ограничениями:

Эти ограничения предназначены для снижения накладных расходов на кодирование и декодирование определенных элементов в BER.

Эти ограничения не применяются к типам ASN.1, инкапсулированным в значения строк OCTET STRING, таким как значения атрибутов, если не указано иное.

5.2. Transmission Control Protocol (TCP)

Закодированные PDU LDAPMessage напрямую отображаются на поток TCP [RFC793] с использованием основанного на BER кодирования, описанного в разделе 5.1. Рекомендуется, чтобы реализации сервера, работающие поверх TCP, ожидали соединения по протоколу на порту LDAP 389, назначенному Internet Assigned Numbers Authority (IANA) [PortReg]. Вместо этого серверы могут ожидать соединения на порту с другим номером. Клиенты должны (MUST) поддерживать возможность связываться с серверами на любом действительном порту TCP.

5.3. Прекращение сессии LDAP

Обычно прекращение сессии LDAP инициируется клиентом, посылающим запрос UnbindRequest (раздел 4.3), либо сервером, посылающим уведомление об отключении (раздел 4.4.1). В этих случаях каждая сторона протокола корректно завершает сессию LDAP путём прекращения обменов на уровне сообщений LDAP, разрыва (если он установлен) уровня SASL, разрыва (если он установлен) уровня TLS и закрытия транспортного соединения.

Стороны протокола могут определить, что продолжение какого-либо взаимодействия может привести к пагубным последствиям, в таком случае они могут сразу завершить сессию путём прекращения обменов и закрытия транспортного соединения.

В любом случае, если сессия LDAP прекращена, незавершённые операции обрабатываются как указано в разделе 3.1.

6. О безопасности

Данная версия протокола предоставляет возможности простой аутентификации с использованием паролей в открытом виде, а также аутентификации с использованием любого механизма SASL [RFC4422]. Установление уровней SASL и/или TLS может обеспечить целостность и другие сервисы безопасности информации.

Также разрешается возврат сервером клиенту своих учётных данных для аутентификации, если он захочет это сделать.

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

Считается правильным, когда серверы предотвращают изменения каталога клиентами, осуществляющими доступ анонимно [RFC4513].

Соображения безопасности для методов аутентификации, механизмов SASL и TLS описаны в [RFC4513].

Обратите внимание, что обмен аутентификационной информацией SASL не обеспечивает конфиденциальности информации и защиты целостности для полей version или name запроса BindRequest, полей resultCode, diagnosticMessage или referral ответа BindResponse, а также для какой-либо информации, содержащейся в элементах управления, вложенных в запросы и ответы Bind. Таким образом, не следует (SHOULD NOT) помещать в эти поля важную информацию, если она не защищена другим способом (таким, как установка защиты на транспортном уровне).

Тем, кто занимается реализацией, следует иметь ввиду, что различные факторы безопасности (в том числе аутентификационная и авторизационная информация и сервисы безопасности данных) могут меняться в ходе сессии LDAP или даже во время выполнения конкретной операции. Например, может закончиться срок действия учётных данных, могут измениться авторизационные сущности или правила контроля доступа, либо уровень (уровни) обеспечения безопасности, поверх которых работает сессия LDAP, могут быть заменены или их работа завершена. Реализации должны обеспечить достаточную надёжность при обработке изменений факторов безопасности.

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

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

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

Содержимое полей matchedDN и diagnosticMessage, а также некоторые значения результирующих кодов resultCode (например, attributeOrValueExists и entryAlreadyExists) могут раскрывать наличие или отсутствие конкретных данных в каталоге, защищаемых средствами контроля доступа и других административных ограничений. Реализациям сервера следует ограничивать доступ к защищаемой информации в равной степени как в нормальных условиях, так и при возникновении ошибок.

Стороны протокола должны (MUST) быть готовы обрабатывать неверные кодировки протокола и кодировки произвольной длины. Неверные кодировки протокола включают в себя: исключения кодировки BER, исключения формата строки и кодировки UTF-8, исключения переполнения, исключения целочисленных значений, а также исключения флага on/off бинарного режима. Набор тестов LDAPv3 PROTOS [PROTOS-LDAP] предоставляет прекрасные примеры таких исключений и варианты тестов для обнаружения недостатков в реализациях.

В случае обнаружения сторонами протокола какой-либо атаки, которая может привести к плохим последствиям при продолжении взаимодействия на любом уровне в рамках сессии LDAP, им следует немедленно прекратить эту сессию LDAP как описано в разделе 5.3.

7. Благодарности

Этот документ основан на RFC 2251, авторы Mark Wahl, Tim Howes и Steve Kille. RFC 2251 — продукт рабочей группы IETF ASID.

Он также основан на RFC 2830, авторы Jeff Hodges, RL "Bob" Morgan и Mark Wahl. RFC 2830 — продукт рабочей группы IETF LDAPEXT.

Он также основан на RFC 3771, авторы Roger Harrison и Kurt Zeilenga. RFC 3771 — индивидуальный вклад в IETF.

Этот документ — продукт рабочей группы IETF LDAPBIS. Существенный вклад в составление документа и его техническую ревизию внесли Kurt Zeilenga, Steven Legg и Hallvard Furuseth.

8. Нормативные документы

[ASN.1] ITU-T Recommendation X.680 (07/2002) | ISO/IEC 8824-1:2002 "Information Technology - Abstract Syntax Notation One (ASN.1): Specification of basic notation".

[BER] ITU-T Rec. X.690 (07/2002) | ISO/IEC 8825-1:2002, "Information technology - ASN.1 encoding rules: Specification of Basic Encoding Rules (BER), Canonical Encoding Rules (CER) and Distinguished Encoding Rules (DER)", 2002.

[ISO10646] Universal Multiple-Octet Coded Character Set (UCS) - Architecture and Basic Multilingual Plane, ISO/IEC 10646-1 : 1993.

[RFC791] Postel, J., "Internet Protocol", STD 5, RFC 791, сентябрь 1981.

[RFC793] Postel, J., "Transmission Control Protocol", STD 7, RFC 793, сентябрь 1981.

[RFC2119] Bradner, S., "Ключевые слова для обозначения уровня требований в RFC", BCP 14, RFC 2119, март 1997.

[RFC3454] Hoffman P. и M. Blanchet, "Preparation of Internationalized Strings ('stringprep')", RFC 3454, декабрь 2002.

[RFC3629] Yergeau, F., "UTF-8, a transformation format of ISO 10646", STD 63, RFC 3629, ноябрь 2003.

[RFC3986] Berners-Lee, T., Fielding, R. и L. Masinter, "Uniform Resource Identifier (URI): Generic Syntax", STD 66, RFC 3986, январь 2005.

[RFC4013] Zeilenga, K., "SASLprep: Stringprep Profile for User Names and Passwords", RFC 4013, февраль 2005.

[RFC4234] Crocker, D. и P. Overell, "Augmented BNF for Syntax Specifications: ABNF", RFC 4234, октябрь 2005.

[RFC4346] Dierks, T. и E. Rescorla, "The TLS Protocol Version 1.1", RFC 4346, март 2006.

[RFC4422] Под редакцией Melnikov, A., и K. Zeilenga, "Простой уровень аутентификации и защиты (Simple Authentication and Security Layer, SASL)", RFC 4422, июнь 2006.

[RFC4510] Под редакцией Zeilenga, K., "Lightweight Directory Access Protocol (LDAP): Technical Specification Road Map", RFC 4510, июнь 2006.

[RFC4512] Zeilenga, K., Lightweight Directory Access Protocol (LDAP): Directory Information Models", RFC 4512, июнь 2006.

[RFC4513] Под редакцией Harrison, R., "Lightweight Directory Access Protocol (LDAP): Authentication Methods and Security Mechanisms", RFC 4513, июнь 2006.

[RFC4514] Под редакцией Zeilenga, K., "Lightweight Directory Access Protocol (LDAP): String Representation of Distinguished Names", RFC 4514, июнь 2006.

[RFC4516] Под редакцией Smith, M. и T. Howes, "Lightweight Directory Access Protocol (LDAP): Uniform Resource Locator", RFC 4516, июнь 2006.

[RFC4517] Под редакцией Legg, S., "Lightweight Directory Access Protocol (LDAP): Syntaxes and Matching Rules", RFC 4517, июнь 2006.

[RFC4520] Zeilenga, K., "Internet Assigned Numbers Authority (IANA) Considerations for the Lightweight Directory Access Protocol (LDAP)", BCP 64, RFC 4520, июнь 2006.

[Unicode] The Unicode Consortium, "The Unicode Standard, Version 3.2.0", определён в "The Unicode Standard, Version 3.0" (Reading, MA, Addison-Wesley, 2000. ISBN 0-201-61633-5), с поправками, внесенными в "Unicode Standard Annex #27: Unicode 3.1" (http://www.unicode.org/reports/tr27/) и в "Unicode Standard Annex #28: Unicode 3.2" (http://www.unicode.org/reports/tr28/).

[X.500] ITU-T Rec. X.500, "The Directory: Overview of Concepts, Models and Service", 1993.

[X.511] ITU-T Rec. X.511, "The Directory: Abstract Service Definition", 1993.

9. Информативные документы

[CharModel] Whistler, K. and M. Davis, "Unicode Technical Report #17, Character Encoding Model", UTR17, <http://www.unicode.org/unicode/reports/tr17/>, август 2000.

[Glossary] The Unicode Consortium, "Unicode Glossary", <http://www.unicode.org/glossary/>.

[PortReg] IANA, "Port Numbers", <http://www.iana.org/assignments/port-numbers>.

[PROTOS-LDAP] University of Oulu, "PROTOS Test-Suite: c06-ldapv3" <http://www.ee.oulu.fi/research/ouspg/protos/testing/c06/ldapv3/>.

10. Регистрация в IANA

Администрация адресного пространства Интернет (Internet Assigned Numbers Authority, IANA) обновила регистрацию результирующих кодов LDAP, указав тем самым, что в данном документе предоставлена окончательная техническая спецификация для результирующих кодов 0-36, 48-54, 64-70, 80-90. Также отмечается, что значение одного результирующего кода (strongAuthRequired) было переименовано (в strongerAuthRequired).

Также IANA обновила регистрацию механизма протокола LDAP, указав тем самым, что в данном документе и в [RFC4513] предоставлена окончательная техническая спецификация для расширенной операции StartTLS (1.3.6.1.4.1.1466.20037).

IANA назначила идентификатор объекта LDAP 18 [RFC4520] для идентификации определённого в этом документа модуля ASN.1.

        Subject: Request for LDAP Object Identifier Registration
        Person & email address to contact for further information:
             Jim Sermersheim <jimse@novell.com>
        Specification: RFC 4511
        Author/Change Controller: IESG
        Comments:
             Identifies the LDAP ASN.1 module

Приложение A. Результирующие коды LDAP

Это нормативное приложение раскрывает дополнительные соображения о результирующих кодах LDAP и содержит краткое общее описание каждого из перечисленных в разделе 4.1.9 результирующих кодов LDAP.

Для использования с расширениями [RFC4520] могут (MAY) быть определены дополнительные результирующие коды. Реализациям клиента нужно (SHALL) интерпретировать любой нераспознанный ими результирующий код как неизвестное ошибочное состояние.

Предоставленные здесь описания не в полной мере отражают суть ошибки в случаях замены результирующего кода, которая используется для предотвращения раскрытия неавторизованного доступа (например, замена на noSuchObject для insufficientAccessRights, или на invalidCredentials для insufficientAccessRights).

A.1. Неошибочные результирующие коды

Эти результирующие коды (так называемые "неошибочные" результирующие коды) не указывают на возникновение ошибки:

success (0),
compareFalse (5),
compareTrue (6),
referral (10) и
saslBindInProgress (14).

Результирующие коды success, compareTrue и compareFalse указывают на успешное выполнение (и, соответственно, называются "успешными" результирующими кодами).

Результирующие коды referral и saslBindInProgress указывают клиенту, что для выполнения операции ему необходимо предпринять дополнительные действия.

A.2. Результирующие коды

Описание существующих результирующих кодов LDAP:

success (0)

Указывает на успешное выполнение операции. Примечание: этот код не используется с операцией Compare. Смотрите compareFalse (5) и compareTrue (6).

operationsError (1)

Указывает на то, что операция нарушает последовательность выполнения по отношению к другим операциям (того же или другого типа).
Например, данный код возвращается, когда клиент пытается выполнить StartTLS [RFC4346], в то время как другие незавершенные операции ещё выполняются или уровень TLS уже был установлен.

protocolError (2)

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

timeLimitExceeded (3)

Указывает на то, что определённое клиентом ограничение по времени было превышено до завершения операции.

sizeLimitExceeded (4)

Указывает на то, что определённое клиентом ограничение по размеру было превышено до завершения операции.

compareFalse (5)

Указывает на то, что операция Compare успешно выполнена и утверждение оценено как FALSE или Undefined.

compareTrue (6)

Указывает на то, что операция Compare успешно выполнена и утверждение оценено как TRUE.

authMethodNotSupported (7)

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

strongerAuthRequired (8)

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

referral (10)

Указывает на то, что для выполнения операции необходимо проследовать по отсылке (смотрите раздел 4.1.10).

adminLimitExceeded (11)

Указывает на то, что были превышены административные ограничения.

unavailableCriticalExtension (12)

Указывает, что критичный элемент управления не распознан (смотрите раздел 4.1.11).

confidentialityRequired (13)

Указывает на то, что требуется защита конфиденциальности данных.

saslBindInProgress (14)

Указывает, что для продолжения процесса аутентификации сервер требует от клиента нового запроса на подсоединение с тем же самым механизмом SASL (смотрите раздел 4.2).

noSuchAttribute (16)

Указывает на то, что запись с заданным именем не содержит указанного атрибута или значения атрибута.

undefinedAttributeType (17)

Указывает на то, что описание атрибута в поле запроса не распознано.

inappropriateMatching (18)

Указывает на то, что была предпринята попытка использовать (например, в утверждении) правило соответствия, не определённое для того типа атрибута, который участвует в операции.

constraintViolation (19)

Указывает на то, что клиент предоставил значение атрибута, не удовлетворяющее ограничениям, налагаемым на него моделью данных.
Например, данный код возвращается, когда для атрибута с ограничением SINGLE-VALUE было предоставлено несколько значений.

attributeOrValueExists (20)

Указывает на то, что клиент предоставил для добавления в запись атрибут или значение, но эти атрибут или значение уже существуют.

invalidAttributeSyntax (21)

Указывает на то, что предполагаемое значение атрибута не соответствует синтаксису атрибута.

noSuchObject (32)

Указывает на то, что такого объекта в DIT не существует.

aliasProblem (33)

Указывает на то, что возникла проблема с псевдонимом. Например, данный код может использоваться для индикации того, что полученное в результате разыменования псевдонима имя не указывает на объект.

invalidDNSyntax (34)

Указывает на то, что значения поля типа LDAPDN или RelativeLDAPDN запроса (например, search base, target entry, ModifyDN newrdn, и т.п.) не удовлетворяют требуемому синтаксису или содержат значения атрибутов, не удовлетворяющие синтаксису этих типов атрибутов.

aliasDereferencingProblem (36)

Указывает на то, что при разыменовании псевдонима возникла проблема. Как правило, псевдоним встретился в ситуации, когда это не позволяется, либо доступ к нему запрещён.

inappropriateAuthentication (48)

Указывает, что сервер требует от клиента, который попытался подсоединиться анонимно или без предоставления данных аутентификации, предоставить эти данные в той или иной форме.

invalidCredentials (49)

Указывает на то, что предоставленные данные аутентификации (например, имя пользователя и пароль) неверны.

insufficientAccessRights (50)

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

busy (51)

Указывает на то, что сервер слишком занят для обслуживания данной операции.

unavailable (52)

Указывает на то, что сервер находится в стадии выключения или необходимая для выполнения операции подсистема недоступна.

unwillingToPerform (53)

Указывает на то, что сервер не желает исполнять данную операцию.

loopDetect (54)

Указывает на то, что сервер обнаружил зацикливание (например, в процессе разыменования псевдонимов или при выполнении сцепления).

namingViolation (64)

Указывает на то, что имя записи нарушает ограничения именования.

objectClassViolation (65)

Указывает на то, что запись нарушает ограничения объектного класса.

notAllowedOnNonLeaf (66)

Указывает на то, что операция выполняет ненадлежащее действие над нелистовой записью.

notAllowedOnRDN (67)

Указывает на то, что операция производит неуместную попытку удалить значение, формирующее относительное уникальное имя записи.

entryAlreadyExists (68)

Указывает на то, что запрос (на добавление, перемещение или переименование) не может быть исполнен, поскольку целевая запись уже существует.

objectClassModsProhibited (69)

Указывает на то, что попытка модификации объектного класса (классов) в атрибуте "objectClass" записи не разрешается.

Например, данный код возвращается при попытке клиента модифицировать структурный объектный класс записи.

affectsMultipleDSAs (71)

Указывает на то, что операция не может быть выполнена, поскольку она затрагивает несколько серверов (DSA).

other (80)

Указывает, что на сервере произошла внутренняя ошибка.

Приложение B. Полное определение ASN.1

Это приложение является нормативным.

        Lightweight-Directory-Access-Protocol-V3 {1 3 6 1 1 18}
        -- Copyright (C) The Internet Society (2006). Эта версия
        -- данного модуля ASN.1 является частью RFC 4511; 
        -- полное заявление авторских прав смотрите в самом RFC.
        DEFINITIONS
        IMPLICIT TAGS
        EXTENSIBILITY IMPLIED ::=

        BEGIN

        LDAPMessage ::= SEQUENCE {
             messageID       MessageID,
             protocolOp      CHOICE {
                  bindRequest           BindRequest,
                  bindResponse          BindResponse,
                  unbindRequest         UnbindRequest,
                  searchRequest         SearchRequest,
                  searchResEntry        SearchResultEntry,
                  searchResDone         SearchResultDone,
                  searchResRef          SearchResultReference,
                  modifyRequest         ModifyRequest,
                  modifyResponse        ModifyResponse,
                  addRequest            AddRequest,
                  addResponse           AddResponse,
                  delRequest            DelRequest,
                  delResponse           DelResponse,
                  modDNRequest          ModifyDNRequest,
                  modDNResponse         ModifyDNResponse,
                  compareRequest        CompareRequest,
                  compareResponse       CompareResponse,
                  abandonRequest        AbandonRequest,
                  extendedReq           ExtendedRequest,
                  extendedResp          ExtendedResponse,
                  ...,
                  intermediateResponse  IntermediateResponse },
             controls       [0] Controls OPTIONAL }

        MessageID ::= INTEGER (0 .. maxInt)

        maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) --

        LDAPString ::= OCTET STRING -- закодирована в UTF-8,
                                    -- символы [ISO10646]

        LDAPOID ::= OCTET STRING -- ограничена до <numericoid>
                                 -- [RFC4512]

        LDAPDN ::= LDAPString -- ограничена до <distinguishedName>
                              -- [RFC4514]

        RelativeLDAPDN ::= LDAPString -- ограничена до <name-component>
                                      -- [RFC4514]

        AttributeDescription ::= LDAPString
                                -- ограничена до <attributedescription>
                                -- [RFC4512]

        AttributeValue ::= OCTET STRING

        AttributeValueAssertion ::= SEQUENCE {
             attributeDesc   AttributeDescription,
             assertionValue  AssertionValue }

        AssertionValue ::= OCTET STRING

        PartialAttribute ::= SEQUENCE {
             type       AttributeDescription,
             vals       SET OF value AttributeValue }

        Attribute ::= PartialAttribute(WITH COMPONENTS {
             ...,
             vals (SIZE(1..MAX))})

        MatchingRuleId ::= LDAPString

        LDAPResult ::= SEQUENCE {
             resultCode         ENUMERATED {
                  success                      (0),
                  operationsError              (1),
                  protocolError                (2),
                  timeLimitExceeded            (3),
                  sizeLimitExceeded            (4),
                  compareFalse                 (5),
                  compareTrue                  (6),
                  authMethodNotSupported       (7),
                  strongerAuthRequired         (8),
                       -- 9 зарезервирован --
                  referral                     (10),
                  adminLimitExceeded           (11),
                  unavailableCriticalExtension (12),
                  confidentialityRequired      (13),
                  saslBindInProgress           (14),
                  noSuchAttribute              (16),
                  undefinedAttributeType       (17),
                  inappropriateMatching        (18),
                  constraintViolation          (19),
                  attributeOrValueExists       (20),
                  invalidAttributeSyntax       (21),
                       -- 22-31 не используются --
                  noSuchObject                 (32),
                  aliasProblem                 (33),
                  invalidDNSyntax              (34),
                       -- 35 зарезервирован для неопределённого isLeaf --
                  aliasDereferencingProblem    (36),
                       -- 37-47 не используются --
                  inappropriateAuthentication  (48),
                  invalidCredentials           (49),
                  insufficientAccessRights     (50),
                  busy                         (51),
                  unavailable                  (52),
                  unwillingToPerform           (53),
                  loopDetect                   (54),
                       -- 55-63 не используются --
                  namingViolation              (64),
                  objectClassViolation         (65),
                  notAllowedOnNonLeaf          (66),
                  notAllowedOnRDN              (67),
                  entryAlreadyExists           (68),
                  objectClassModsProhibited    (69),
                       -- 70 зарезервирован для CLDAP --
                  affectsMultipleDSAs          (71),
                       -- 72-79 не используются --
                  other                        (80),
                  ... },
             matchedDN          LDAPDN,
             diagnosticMessage  LDAPString,
             referral           [3] Referral OPTIONAL }

        Referral ::= SEQUENCE SIZE (1..MAX) OF uri URI

        URI ::= LDAPString     -- ограничена набором символов,
                               -- разрешённых в URI

        Controls ::= SEQUENCE OF control Control

        Control ::= SEQUENCE {
             controlType             LDAPOID,
             criticality             BOOLEAN DEFAULT FALSE,
             controlValue            OCTET STRING OPTIONAL }

        BindRequest ::= [APPLICATION 0] SEQUENCE {
             version                 INTEGER (1 .. 127),
             name                    LDAPDN,
             authentication          AuthenticationChoice }

        AuthenticationChoice ::= CHOICE {
             simple                  [0] OCTET STRING,
                                     -- 1 и 2 зарезервированы
             sasl                    [3] SaslCredentials,
             ... }

        SaslCredentials ::= SEQUENCE {
             mechanism               LDAPString,
             credentials             OCTET STRING OPTIONAL }

        BindResponse ::= [APPLICATION 1] SEQUENCE {
             COMPONENTS OF LDAPResult,
             serverSaslCreds    [7] OCTET STRING OPTIONAL }

        UnbindRequest ::= [APPLICATION 2] NULL

        SearchRequest ::= [APPLICATION 3] SEQUENCE {
             baseObject      LDAPDN,
             scope           ENUMERATED {
                  baseObject              (0),
                  singleLevel             (1),
                  wholeSubtree            (2),
                  ... },
             derefAliases    ENUMERATED {
                  neverDerefAliases       (0),
                  derefInSearching        (1),
                  derefFindingBaseObj     (2),
                  derefAlways             (3) },
             sizeLimit       INTEGER (0 .. maxInt),
             timeLimit       INTEGER (0 .. maxInt),
             typesOnly       BOOLEAN,
             filter          Filter,
             attributes      AttributeSelection }

        AttributeSelection ::= SEQUENCE OF selector LDAPString
                       -- строка LDAPString, ограниченная конструкцией
                       -- <attributeSelector> из раздела 4.5.1.8

        Filter ::= CHOICE {
             and             [0] SET SIZE (1..MAX) OF filter Filter,
             or              [1] SET SIZE (1..MAX) OF filter Filter,
             not             [2] Filter,
             equalityMatch   [3] AttributeValueAssertion,
             substrings      [4] SubstringFilter,
             greaterOrEqual  [5] AttributeValueAssertion,
             lessOrEqual     [6] AttributeValueAssertion,
             present         [7] AttributeDescription,
             approxMatch     [8] AttributeValueAssertion,
             extensibleMatch [9] MatchingRuleAssertion,
             ... }

        SubstringFilter ::= SEQUENCE {
             type           AttributeDescription,
             substrings     SEQUENCE SIZE (1..MAX) OF substring CHOICE {
                  initial [0] AssertionValue,  -- может вкючаться только один раз
                  any     [1] AssertionValue,
                  final   [2] AssertionValue } -- может вкючаться только один раз
             }

        MatchingRuleAssertion ::= SEQUENCE {
             matchingRule    [1] MatchingRuleId OPTIONAL,
             type            [2] AttributeDescription OPTIONAL,
             matchValue      [3] AssertionValue,
             dnAttributes    [4] BOOLEAN DEFAULT FALSE }

        SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
             objectName      LDAPDN,
             attributes      PartialAttributeList }

        PartialAttributeList ::= SEQUENCE OF
                             partialAttribute PartialAttribute

        SearchResultReference ::= [APPLICATION 19] SEQUENCE
                                  SIZE (1..MAX) OF uri URI

        SearchResultDone ::= [APPLICATION 5] LDAPResult

        ModifyRequest ::= [APPLICATION 6] SEQUENCE {
             object          LDAPDN,
             changes         SEQUENCE OF change SEQUENCE {
                  operation       ENUMERATED {
                       add     (0),
                       delete  (1),
                       replace (2),
                       ... },
                  modification    PartialAttribute } }

        ModifyResponse ::= [APPLICATION 7] LDAPResult

        AddRequest ::= [APPLICATION 8] SEQUENCE {
             entry           LDAPDN,
             attributes      AttributeList }

        AttributeList ::= SEQUENCE OF attribute Attribute

        AddResponse ::= [APPLICATION 9] LDAPResult

        DelRequest ::= [APPLICATION 10] LDAPDN

        DelResponse ::= [APPLICATION 11] LDAPResult

        ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
             entry           LDAPDN,
             newrdn          RelativeLDAPDN,
             deleteoldrdn    BOOLEAN,
             newSuperior     [0] LDAPDN OPTIONAL }

        ModifyDNResponse ::= [APPLICATION 13] LDAPResult

        CompareRequest ::= [APPLICATION 14] SEQUENCE {
             entry           LDAPDN,
             ava             AttributeValueAssertion }

        CompareResponse ::= [APPLICATION 15] LDAPResult

        AbandonRequest ::= [APPLICATION 16] MessageID

        ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
             requestName      [0] LDAPOID,
             requestValue     [1] OCTET STRING OPTIONAL }

        ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
             COMPONENTS OF LDAPResult,
             responseName     [10] LDAPOID OPTIONAL,
             responseValue    [11] OCTET STRING OPTIONAL }

        IntermediateResponse ::= [APPLICATION 25] SEQUENCE {
             responseName     [0] LDAPOID OPTIONAL,
             responseValue    [1] OCTET STRING OPTIONAL }

        END

Приложение C. Изменения

Это приложение не является нормативным.

В данном приложении собраны основные изменения, внесенные в RFC 2251, RFC 2830 и RFC 3771.

C.1. Изменения, внесённые в RFC 2251

В данном разделе приводятся основные изменения, внесённые в разделы 1, 2, 3.1, 4 и в оставшуюся часть RFC 2251. За перечнем изменений, внесённых в другие разделы этого RFC, читателям следует обратиться к [RFC4512] и [RFC4513].

C.1.1. Раздел 1 (Статус документа)

C.1.2. Раздел 3.1 (Модель протокола) и другое

C.1.3. Раздел 4 (Элементы протокола)

C.1.4. Раздел 4.1.1 (Конверт сообщения)

C.1.5. Раздел 4.1.1.1 (Message ID)

C.1.6. Раздел 4.1.2 (Строковые типы)

C.1.7. Раздел 4.1.5.1 (Опция binary) и другое

C.1.8. Раздел 4.1.8 (Атрибут)

C.1.9. Раздел 4.1.10 (Результирующее сообщение)

C.1.10. Раздел 4.1.11 (Отсылка)

C.1.11. Раздел 4.1.12 (Элементы управления)

C.1.12. Раздел 4.2 (Операция Bind)

C.1.13. Раздел 4.2.1 (Последовательность запросов Bind)

C.1.14. Раздел 4.2.3 (Ответ Bind)

C.1.15. Раздел 4.3 (Операция Unbind)

C.1.16. Раздел 4.4 (Произвольное уведомление)

C.1.17. Раздел 4.5.1 (Запрос Search)

C.1.18. Раздел 4.5.2 (Результат операции Search)

C.1.19. Раздел 4.5.3 (Ссылки-продолжения в результатах операции Search)

C.1.20. Раздел 4.5.3.1 (Примеры)

C.1.21. Раздел 4.6 (Операция Modify)

C.1.22. Раздел 4.7 (Операция Add)

C.1.23. Раздел 4.9 (Операция Modify DN)

C.1.24. Раздел 4.10 (Операция Compare)

C.1.25. Раздел 4.11 (Операция Abandon)

C.1.26. Раздел 4.12 (Операция Extended)

C.1.27. Раздел 5.2 (Протоколы передачи)

C.1.28. Раздел 7 (О безопасности)

C.1.29. Приложение A (Полное определение ASN.1)

C.2. Изменения, внесённые в RFC 2830

В данном разделе приводятся основные изменения, внесённые в разделы RFC 2830. За перечнем изменений, внесённых в другие разделы этого RFC, читателям следует обратиться к [RFC4513].

C.2.1. Раздел 2.3 (Ответ, отличный от "success")

C.2.1. Раздел 4 (Закрытие соединения TLS)

C.3. Изменения, внесённые в RFC 3771

Адрес редактора

Jim Sermersheim

Novell, Inc., 1800 South Novell Place, Provo, Utah 84606, USA

Телефон: +1 801 861-3088

EMail: jimse@novell.com

Полное заявление авторских прав

Copyright (C) Internet Society (2006).

На этот документ распространяются права, лицензии и ограничения, содержащиеся в BCP 78, и, за исключением случаев, изложенных в нем, авторы сохраняют все свои права.

Это документ и содержащаяся в нём информация распространяются "КАК ЕСТЬ" и АВТОР ДОКУМЕНТА, ОРГАНИЗАЦИЯ, КОТОРУЮ ОН/ОНА ПРЕДСТАВЛЯЕТ, ИЛИ КОТОРОЙ ОН/ОНА СПОНСИРУЕТСЯ (ЕСЛИ ТАКОВЫЕ ИМЕЮТСЯ), INTERNET SOCIETY И INTERNET ENGINEERING TASK FORCE ОТКАЗЫВАЮТСЯ ОТ ВСЕХ ГАРАНТИЙ, ЯВНЫХ ИЛИ ПОДРАЗУМЕВАЕМЫХ, ВКЛЮЧАЯ, ПОМИМО ПРОЧЕГО, ЛЮБЫЕ ГАРАНТИИ ТОГО, ЧТО ИСПОЛЬЗОВАНИЕ ПРИВЕДЁННОЙ ЗДЕСЬ ИНФОРМАЦИИ НЕ НАРУШАЕТ КАКИХ-ЛИБО ПРАВ ИЛИ ЛЮБЫЕ ПОДРАЗУМЕВАЕМЫЕ ГАРАНТИИ ПРИГОДНОСТИ ДЛЯ КОНКРЕТНЫХ ЦЕЛЕЙ.

Интеллектуальная собственность

IETF не занимает никакой позиции относительно действительности или области действия каких-либо прав на интеллектуальную собственность или других прав, которые могут заявляться как относящиеся к реализации или использованию технологий, описанных в данном документе, либо в подтверждении которых могут или не могут быть доступны какие-либо лицензии; кроме того, IETF не заявляет о том, что она будет предпринимать какие-либо независимые усилия по выявлению подобных прав. Информацию по процедурам в отношении прав в документах RFC можно найти в BCP 78 и BCP 79.

Копии поданных в секретариат IETF заявлений о правах на интеллектуальную собственность (Intellectual Property Rights, IPR), а также какие-либо документы, подтверждающие лицензию и предназначенные для предоставления доступа к ним, либо результаты попыток получения генеральных лицензий или разрешений на пользование подобными правами собственности могут быть получены теми, кто занимается реализацией, или пользователями данной спецификации из он-лайн репозитория IPR IETF по адресу http://www.ietf.org/ipr.

IETF просит всех заинтересованных лиц довести до её сведения любые авторские права, патенты или патентные заявки, либо другие права собственности, которые могут касаться технологий данного стандарта и могут потребоваться для его реализации. Пожалуйста, направляйте информацию в IETF по адресу ietf-ipr@ietf.org.

Признание заслуг

Финансирование функций RFC Editor обеспечивается IETF Administrative Support Activity (IASA).

Перевод выполнен участниками проекта Pro-LDAP.ru. Предложения по улучшению перевода и сообщения об ошибках принимаются на форуме проекта.