RFC 2251
Lightweight Directory Access Protocol (v3)
RFC 2251 ๐ Title Block
Okay bestie, here's the vibe check on the paper itself ๐
- Network Working Group ๐ธ
- RFC 2251: "Lightweight Directory Access Protocol (v3)" ๐ฆ
- Authors: M. Wahl (Critical Angle Inc.), T. Howes (Netscape Communications Corp.), S. Kille (Isode Limited) ๐
- Category: Standards Track โญ
- Date: December 1997 ๐
- Obsoletes / Updates: the title block doesn't list anything under either one ๐
1. Status of this Memo โจ
This document specifies an Internet standards track protocol for the Internet community, and requests discussion and suggestions for improvements. Please refer to the current edition of the "Internet Official Protocol Standards" (STD 1) for the standardization state and status of this protocol. Distribution of this memo is unlimited. ๐
Copyright Notice
Copyright (C) The Internet Society (1997). All Rights Reserved. ๐
IESG Note ๐ซถ
This document describes a directory access protocol that provides both read and update access. Update access requires secure authentication, but this document does not mandate implementation of any satisfactory authentication mechanisms. ๐ฅ
In accordance with RFC 2026, section 4.4.1, this specification is being approved by IESG as a Proposed Standard despite this limitation, for the following reasons:
- a. to encourage implementation and interoperability testing of these protocols (with or without update access) before they are deployed, and
- b. to encourage deployment and use of these protocols in read-only applications. (e.g. applications where LDAPv3 is used as a query language for directories which are updated by some secure mechanism other than LDAP), and
- c. to avoid delaying the advancement and deployment of other Internet standards-track protocols which require the ability to query, but not update, LDAPv3 directory servers.
Readers are hereby warned that until mandatory authentication mechanisms are standardized, clients and servers written according to this specification which make use of update functionality are "UNLIKELY TO INTEROPERATE, or MAY INTEROPERATE ONLY IF AUTHENTICATION IS REDUCED TO AN UNACCEPTABLY WEAK LEVEL." ๐ญ
Implementors are hereby discouraged from deploying LDAPv3 clients or servers which implement the update functionality, until a Proposed Standard for mandatory authentication in LDAPv3 has been approved and published as an RFC. ๐
Table of Contents ๐๏ธ
1. Status of this Memo .................................... 1
Copyright Notice ....................................... 1
IESG Note .............................................. 1
2. Abstract ............................................... 3
3. Models ................................................. 4
3.1. Protocol Model ........................................ 4
3.2. Data Model ............................................ 5
3.2.1. Attributes of Entries ............................... 5
3.2.2. Subschema Entries and Subentries .................... 7
3.3. Relationship to X.500 ................................. 8
3.4. Server-specific Data Requirements ..................... 8
4. Elements of Protocol ................................... 9
4.1. Common Elements ....................................... 9
4.1.1. Message Envelope .................................... 9
4.1.1.1. Message ID ........................................ 11
4.1.2. String Types ........................................ 11
4.1.3. Distinguished Name and Relative Distinguished Name .. 11
4.1.4. Attribute Type ...................................... 12
4.1.5. Attribute Description ............................... 13
4.1.5.1. Binary Option ..................................... 14
4.1.6. Attribute Value ..................................... 14
4.1.7. Attribute Value Assertion ........................... 15
4.1.8. Attribute ........................................... 15
4.1.9. Matching Rule Identifier ............................ 15
4.1.10. Result Message ..................................... 16
4.1.11. Referral ........................................... 18
4.1.12. Controls ........................................... 19
4.2. Bind Operation ........................................ 20
4.2.1. Sequencing of the Bind Request ...................... 21
4.2.2. Authentication and Other Security Services .......... 22
4.2.3. Bind Response ....................................... 23
4.3. Unbind Operation ...................................... 24
4.4. Unsolicited Notification .............................. 24
4.4.1. Notice of Disconnection ............................. 24
4.5. Search Operation ...................................... 25
4.5.1. Search Request ...................................... 25
4.5.2. Search Result ....................................... 29
4.5.3. Continuation References in the Search Result ........ 31
4.5.3.1. Example ........................................... 31
4.6. Modify Operation ...................................... 32
4.7. Add Operation ......................................... 34
4.8. Delete Operation ...................................... 35
4.9. Modify DN Operation ................................... 36
4.10. Compare Operation .................................... 37
4.11. Abandon Operation .................................... 38
4.12. Extended Operation ................................... 38
5. Protocol Element Encodings and Transfer ................ 39
5.1. Mapping Onto BER-based Transport Services ............. 39
5.2. Transfer Protocols .................................... 40
5.2.1. Transmission Control Protocol (TCP) ................. 40
6. Implementation Guidelines .............................. 40
6.1. Server Implementations ................................ 40
6.2. Client Implementations ................................ 40
7. Security Considerations ................................ 41
8. Acknowledgements ....................................... 41
9. Bibliography ........................................... 41
10. Authors' Addresses ..................................... 42
Appendix A - Complete ASN.1 Definition ..................... 44
Full Copyright Statement ................................... 50
2. Abstract ๐
The protocol described in this document is designed to provide access to directories supporting the X.500 models, while not incurring the resource requirements of the X.500 Directory Access Protocol (DAP). This protocol is specifically targeted at management applications and browser applications that provide read/write interactive access to directories. When used with a directory supporting the X.500 protocols, it is intended to be a complement to the X.500 DAP. ๐
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", and "MAY" in this document are to be interpreted as described in RFC 2119 [10]. ๐
Key aspects of this version of LDAP are: โจ
- All protocol elements of LDAPv2 (RFC 1777) are supported. The protocol is carried directly over TCP or other transport, bypassing much of the session/presentation overhead of X.500 DAP.
- Most protocol data elements can be encoded as ordinary strings (e.g., Distinguished Names).
- Referrals to other servers may be returned.
- SASL mechanisms may be used with LDAP to provide association security services.
- Attribute values and Distinguished Names have been internationalized through the use of the ISO 10646 character set.
- The protocol can be extended to support new operations, and controls may be used to extend existing operations.
- Schema is published in the directory for use by clients.
3. Models ๐ง
Interest in X.500 [1] directory technologies in the Internet has led to efforts to reduce the high cost of entry associated with use of these technologies. This document continues the efforts to define directory protocol alternatives, updating the LDAP [2] protocol specification. ๐ฆ
3.1. Protocol Model
The general model adopted by this protocol is one of clients performing protocol operations against servers. In this model, a client transmits a protocol request describing the operation to be performed to a server. The server is then responsible for performing the necessary operation(s) in the directory. Upon completion of the operation(s), the server returns a response containing any results or errors to the requesting client. ๐
In keeping with the goal of easing the costs associated with use of the directory, it is an objective of this protocol to minimize the complexity of clients so as to facilitate widespread deployment of applications capable of using the directory. ๐ธ
Note that although servers are required to return responses whenever such responses are defined in the protocol, there is no requirement for synchronous behavior on the part of either clients or servers. Requests and responses for multiple operations may be exchanged between a client and server in any order, provided the client eventually receives a response for every request that requires one. ๐
In LDAP versions 1 and 2, no provision was made for protocol servers returning referrals to clients. However, for improved performance and distribution this version of the protocol permits servers to return to clients referrals to other servers. This allows servers to offload the work of contacting other servers to progress operations. ๐ฅ
Note that the core protocol operations defined in this document can be mapped to a strict subset of the X.500(1997) directory abstract service, so it can be cleanly provided by the DAP. However there is not a one-to-one mapping between LDAP protocol operations and DAP operations: server implementations acting as a gateway to X.500 directories may need to make multiple DAP requests. ๐ซถ
3.2. Data Model
This section provides a brief introduction to the X.500 data model, as used by LDAP. ๐
The LDAP protocol assumes there are one or more servers which jointly provide access to a Directory Information Tree (DIT). The tree is made up of entries. Entries have names: one or more attribute values from the entry form its relative distinguished name (RDN), which "MUST" be unique among all its siblings. The concatenation of the relative distinguished names of the sequence of entries from a particular entry to an immediate subordinate of the root of the tree forms that entry's Distinguished Name (DN), which is unique in the tree. An example of a Distinguished Name is: ๐ณ
CN=Steve Kille, O=Isode Limited, C=GB
Some servers may hold cache or shadow copies of entries, which can be used to answer search and comparison queries, but will return referrals or contact other servers if modification operations are requested. ๐
Servers which perform caching or shadowing "MUST" ensure that they do not violate any access control constraints placed on the data by the originating server. ๐จ
The largest collection of entries, starting at an entry that is mastered by a particular server, and including all its subordinates and their subordinates, down to the entries which are mastered by different servers, is termed a naming context. The root of the DIT is a DSA-specific Entry (DSE) and not part of any naming context: each server has different attribute values in the root DSE. (DSA is an X.500 term for the directory server.) ๐
That's part 1 of 11 done bestie ๐ฆ more parts coming, so stay tuned ๐
3.2.1. Attributes of Entries โจ
Okay so entries are basically a bunch of attributes ๐ An attribute is a type with one or more values attached to it. The attribute type gets a short descriptive name AND an OID (object identifier) ๐ The type decides whether an entry can hold more than one value of that attribute, what syntax those values have to follow, what kinds of matching you can do on them, and some other stuff too ๐ฆ
Here's an example: "mail" ๐ง It can have one or more values, they must be IA5 (ASCII) strings, and it's case insensitive. So foo@bar.com will match FOO@BAR.COM. Iconic ๐
Schema is the whole collection of attribute type definitions, object class definitions, and other info a server uses to figure out how to match a filter or an attribute value assertion (in a compare operation) against an entry's attributes. It also helps the server decide whether to allow add and modify operations ๐ง The schema for LDAP is defined in [5] and [6], and other documents can add more schema elements too ๐
Each entry MUST have an objectClass attribute ๐ The objectClass attribute lists the object classes of an entry. Together with the system and user schema, those decide which attributes the entry is allowed to have. Clients can change the values of this attribute, but the objectClass attribute itself can't be removed ๐ญ Servers may restrict changes to this attribute so the entry's basic structural class can't be swapped out (so no turning a person into a country, bestie ๐). When you create an entry or add an objectClass value, all the superclasses of the named classes get added automatically if they aren't already there. The client has to supply values for any mandatory attributes of those new superclasses ๐ซถ
Some attributes are called operational attributes, and servers use them to run the directory system itself ๐ธ They don't come back in search results unless you ask for them by name. Non-operational attributes, like "mail", still get their schema and syntax rules enforced by servers, but servers generally don't do anything with their values ๐
Servers MUST NOT permit clients to add attributes to an entry unless those attributes are allowed by the object class definitions, by the schema controlling that entry (listed in the subschema, see below), or are operational attributes the server knows about and uses for administration. Also, there's a special objectClass called extensibleObject defined in [5] that lets all user attributes be present in an entry, so it's giving wide open ๐ฅ
Entries MAY contain, among others, the following operational attributes, defined in [5]. The server maintains these automatically, and clients can't modify them ๐
creatorsName: the Distinguished Name of the user who added this entry to the directory.createTimestamp: the time this entry was added to the directory.modifiersName: the Distinguished Name of the user who last modified this entry.modifyTimestamp: the time this entry was last modified.subschemaSubentry: the Distinguished Name of the subschema entry (or subentry) that controls the schema for this entry.
3.2.2. Subschema Entries and Subentries ๐ฆ
Subschema entries are where info about the directory schema lives, especially the object classes and attribute types that directory servers support ๐ One subschema entry holds all the schema definitions used by entries in a particular part of the directory tree.
Servers that follow the X.500(93) models SHOULD implement subschema using the X.500 subschema mechanisms, which means these subschemas aren't ordinary entries ๐ LDAP clients SHOULD NOT assume that servers implement any other parts of X.500 subschema ๐ A server that masters entries and lets clients modify them MUST implement and provide access to these subschema entries, so its clients can find out which attributes and object classes are allowed to be present. It is strongly recommended that all other servers implement this as well ๐ซถ
The following four attributes MUST be present in all subschema entries โจ
cn: this attribute MUST be used to form the RDN of the subschema entry.objectClass: the attribute MUST have at least the valuestopandsubschema.objectClasses: each value of this attribute specifies an object class known to the server.attributeTypes: each value of this attribute specifies an attribute type known to the server.
These are defined in [5]. Other attributes MAY be present in subschema entries to show extra supported capabilities ๐ Those include matchingRules, matchingRuleUse, dITStructureRules, dITContentRules, nameForms and ldapSyntaxes.
Servers SHOULD provide the attributes createTimestamp and modifyTimestamp in subschema entries, so clients can keep their schema caches up to date ๐
Clients MUST only retrieve attributes from a subschema entry by doing a base object search of the entry, where the search filter is (objectClass=subschema). (This lets LDAPv3 servers that gateway to X.500(93) notice that subentry info is being requested. Smart, right? ๐ง)
3.3. Relationship to X.500 ๐
This document defines LDAP in terms of X.500, as an X.500 access mechanism ๐ An LDAP server MUST act in accordance with the X.500(1993) series of ITU recommendations when it provides the service. BUT it's not required for an LDAP server to use any X.500 protocols to do that ๐ฆ LDAP can be mapped onto any other directory system, as long as the X.500 data and service model used in LDAP isn't violated in the LDAP interface ๐ซถ
3.4. Server-specific Data Requirements ๐ธ
An LDAP server MUST provide info about itself and other info that's specific to each server ๐ช This is stored as a group of attributes in the root DSE (DSA-Specific Entry), which is named with the zero-length LDAPDN. Clients can read these attributes with a base object search of the root using the filter (objectClass=*), but access control restrictions still apply ๐ The root DSE MUST NOT be included if the client does a subtree search starting from the root.
Servers may allow clients to modify these attributes ๐
The following root DSE attributes are defined in section 5 of [5]. Other documents may define more attributes too โจ
namingContexts: naming contexts held in the server. Naming contexts are defined in section 17 of X.501 [6].subschemaSubentry: subschema entries (or subentries) known by this server.altServer: alternative servers in case this one becomes unavailable later.supportedExtension: list of supported extended operations.supportedControl: list of supported controls.supportedSASLMechanisms: list of supported SASL security features.supportedLDAPVersion: LDAP versions implemented by the server.
If the server doesn't master entries and doesn't know where the schema info is, the subschemaSubentry attribute won't be present in the root DSE ๐ If the server masters directory entries under one or more schema rules, there may be any number of values of the subschemaSubentry attribute in the root DSE ๐
4. Elements of Protocol โจ
The LDAP protocol is described using Abstract Syntax Notation 1 (ASN.1) [3], and it's usually transferred using a subset of ASN.1 Basic Encoding Rules [11] ๐ง To support future extensions to this protocol, clients and servers MUST ignore elements of SEQUENCE encodings whose tags they don't recognize. Bestie, that's how the protocol stays flexible ๐
Note that, unlike X.500, each change to the LDAP protocol other than through the extension mechanisms gets a different version number ๐ข A client indicates the version it supports as part of the bind request, which is described in section 4.2. If a client hasn't sent a bind, the server MUST assume that version 3 is supported by the client (since version 2 required the client to bind first) ๐
Clients can work out which protocol version a server supports by reading the supportedLDAPVersion attribute from the root DSE ๐ Servers which implement version 3 or later versions MUST provide this attribute. Servers which only implement version 2 may not provide this attribute ๐ฆ
4.1. Common Elements ๐ธ
This section describes the LDAPMessage envelope PDU (Protocol Data Unit) format, plus the data type definitions used in the protocol operations ๐
4.1.1. Message Envelope ๐
For protocol exchanges, all protocol operations are wrapped in a common envelope called the LDAPMessage, which is defined like this ๐
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 },
controls [0] Controls OPTIONAL }
MessageID ::= INTEGER (0 .. maxInt)
maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) --
The job of the LDAPMessage is to be an envelope with the common fields every protocol exchange needs ๐จ Right now, the only common fields are the message ID and the controls ๐ซถ
If the server gets a PDU from the client where the LDAPMessage SEQUENCE tag can't be recognized, the messageID can't be parsed, the tag of the protocolOp isn't recognized as a request, or the encoding structures or lengths of data fields are found to be incorrect, then the server MUST return the notice of disconnection described in section 4.4.1, with a resultCode of protocolError, and immediately close the connection ๐ฑ In other cases where the server can't parse the request it received from the client, the server MUST return an appropriate response to the request, with the resultCode set to protocolError ๐
If the client gets a PDU from the server that can't be parsed, the client may discard the PDU, or it may abruptly close the connection ๐
The ASN.1 type Controls is defined in section 4.1.12 โจ
4.1.1.1. Message ID โจ
okay so every LDAPMessage envelope that carries a response has the messageID of the request it's answering ๐ that's how everyone knows which question a reply belongs to, bestie.
The message ID of a request MUST have a value different from the values of any other requests outstanding in the LDAP session of which this message is a part. ๐ no two open requests can share an ID, period.
A client MUST NOT send a second request with the same message ID as an earlier request on the same connection if the client has not received the final response from the earlier request. Otherwise the behavior is undefined. ๐ undefined is not the vibe, so don't. Typical clients increment a counter for each request ๐ข
A client MUST NOT reuse the message id of an abandonRequest or of the abandoned operation until it has received a response from the server for another request invoked subsequent to the abandonRequest, as the abandonRequest itself does not have a response. ๐ the abandonRequest never gets a reply of its own, so you wait for a response to some later request first.
4.1.2. String Types ๐งต
okay so the LDAPString is basically a notational shortcut ๐ง it means that even though these strings encode as OCTET STRING, the character set is ISO 10646 [13] (a superset of Unicode), encoded with the UTF-8 algorithm [14]. ngl the cute part is that characters matching ASCII (0x0000 through 0x007F) are stored as that same ASCII character in a single byte. The other byte values are used to build a variable-length encoding for any character at all ๐
LDAPString ::= OCTET STRING
The LDAPOID is also a notational shortcut ๐ฆ it means the permitted value is a (UTF-8 encoded) dotted-decimal representation of an OBJECT IDENTIFIER.
LDAPOID ::= OCTET STRING
For example,
1.3.6.1.4.1.1466.1.2.3
4.1.3. Distinguished Name and Relative Distinguished Name ๐ธ
LDAPDN and RelativeLDAPDN are the representations of a Distinguished Name and a Relative Distinguished Name after encoding them according to the spec in [4] ๐ so that:
<distinguished-name> ::= <name>
<relative-distinguished-name> ::= <name-component>
where <name> and <name-component> are as defined in [4].
LDAPDN ::= LDAPString
RelativeLDAPDN ::= LDAPString
Only Attribute Types can be present in a relative distinguished name component ๐ โโ๏ธ the options of Attribute Descriptions (next section) MUST NOT be used in specifying distinguished names. no options in DNs, main character energy only.
4.1.4. Attribute Type ๐ฆ
An AttributeType takes on as its value the textual string associated with that AttributeType in its specification.
AttributeType ::= LDAPString
Each attribute type has a unique OBJECT IDENTIFIER assigned to it ๐ this identifier may be written as decimal digits with components separated by periods, e.g. "2.5.4.10".
A specification may also assign one or more textual names for an attribute type. These names MUST begin with a letter, and only contain ASCII letters, digit characters and hyphens. They are case insensitive. (These ASCII characters are identical to ISO 10646 characters whose UTF-8 encoding is a single byte between 0x00 and 0x7F.) ๐ค
If the server has a textual name for an attribute type, it MUST use a textual name for attributes returned in search results. The dotted-decimal OBJECT IDENTIFIER is only used if there is no textual name for an attribute type. ๐งพ names win when they exist, iykyk.
Attribute type textual names are non-unique, as two different specifications (neither in standards track RFCs) may choose the same name. ๐ญ yes, names can collide, it's giving chaos.
A server which masters or shadows entries SHOULD list all the attribute types it supports in the subschema entries, using the attributeTypes attribute. Servers which support an open-ended set of attributes SHOULD include at least the attributeTypes value for the 'objectClass' attribute. Clients MAY retrieve the attributeTypes value from subschema entries in order to obtain the OBJECT IDENTIFIER and other information associated with attribute types. ๐
Some attribute type names which are used in this version of LDAP are described in [5]. Servers may implement additional attribute types. โจ
4.1.5. Attribute Description ๐
An AttributeDescription is a superset of the definition of the AttributeType. It has the same ASN.1 definition, but allows additional options to be specified. They are also case insensitive. ๐
AttributeDescription ::= LDAPString
A value of AttributeDescription is based on the following BNF:
<AttributeDescription> ::= <AttributeType> [ ";" <options> ]
<options> ::= <option> | <option> ";" <options>
<option> ::= <opt-char> <opt-char>*
<opt-char> ::= ASCII-equivalent letters, numbers and hyphen
Examples of valid AttributeDescription:
cn
userCertificate;binary
One option, "binary", is defined in this document. Additional options may be defined in IETF standards-track and experimental RFCs. Options beginning with "x-" are reserved for private experiments. Any option could be associated with any AttributeType, although not all combinations may be supported by a server. ๐งช
An AttributeDescription with one or more options is treated as a subtype of the attribute type without any options. Options present in an AttributeDescription are never mutually exclusive. Implementations MUST generate the <options> list sorted in ascending order, and servers MUST treat any two AttributeDescription with the same AttributeType and options as equivalent. A server will treat an AttributeDescription with any options it does not implement as an unrecognized attribute type. ๐ sorted order is a must, and the same type plus options means the same thing.
The data type "AttributeDescriptionList" describes a list of 0 or more attribute types. (A list of zero elements has special significance in the Search request.) ๐ง
AttributeDescriptionList ::= SEQUENCE OF
AttributeDescription
4.1.5.1. Binary Option ๐ซถ
If the "binary" option is present in an AttributeDescription, it overrides any string-based encoding representation defined for that attribute in [5]. Instead the attribute is to be transferred as a binary value encoded using the Basic Encoding Rules [11]. The syntax of the binary value is an ASN.1 data type definition which is referenced by the "SYNTAX" part of the attribute type definition.
The presence or absence of the "binary" option only affects the transfer of attribute values in protocol; servers store any particular attribute in a single format. If a client requests that a server return an attribute in the binary format, but the server cannot generate that format, the server MUST treat this attribute type as an unrecognized attribute type. Similarly, clients MUST NOT expect servers to return an attribute in binary format if the client requested that attribute by name without the binary option. ๐ซ no sneaky binary surprises.
This option is intended to be used with attributes whose syntax is a complex ASN.1 data type, and the structure of values of that type is needed by clients. Examples of this kind of syntax are "Certificate" and "CertificateList". ๐
4.1.6. Attribute Value ๐
A field of type AttributeValue takes on as its value either a string encoding of a AttributeValue data type, or an OCTET STRING containing an encoded binary value, depending on whether the "binary" option is present in the companion AttributeDescription to this AttributeValue.
The definition of string encodings for different syntaxes and types may be found in other documents, and in particular [5].
AttributeValue ::= OCTET STRING
Note that there is no defined limit on the size of this encoding; thus protocol values may include multi-megabyte attributes (e.g. photographs). ๐ธ big files are allowed, bestie.
Attributes may be defined which have arbitrary and non-printable syntax. Implementations MUST NEITHER simply display nor attempt to decode as ASN.1 a value if its syntax is not known. The implementation may attempt to discover the subschema of the source entry, and retrieve the values of attributeTypes from it. ๐ don't just print it or try to decode it blindly.
Clients MUST NOT send attribute values in a request which are not valid according to the syntax defined for the attributes. โ no junk values in requests, ever.
4.1.7. Attribute Value Assertion ๐ง
The AttributeValueAssertion type definition is similar to the one in the X.500 directory standards. It contains an attribute description and a matching rule assertion value suitable for that type.
AttributeValueAssertion ::= SEQUENCE {
attributeDesc AttributeDescription,
assertionValue AssertionValue }
AssertionValue ::= OCTET STRING
If the "binary" option is present in attributeDesc, this signals to the server that the assertionValue is a binary encoding of the assertion value. ๐
For all the string-valued user attributes described in [5], the assertion value syntax is the same as the value syntax. Clients may use attribute values as assertion values in compare requests and search filters. ๐
Note however that the assertion syntax may be different from the value syntax for other attributes or for non-equality matching rules. These may have an assertion syntax which contains only part of the value. See section 20.2.1.8 of X.501 [6] for examples. ๐ plot twist, sometimes it's only part of the value.
4.1.8. Attribute ๐ท
An attribute consists of a type and one or more values of that type. (Though attributes MUST have at least one value when stored, due to access control restrictions the set may be empty when transferred in protocol. This is described in section 4.5.2, concerning the PartialAttributeList type.) ๐ stored attributes always have a value, but the wire can be empty because of access control.
Attribute ::= SEQUENCE {
type AttributeDescription,
vals SET OF AttributeValue }
Each attribute value is distinct in the set (no duplicates). The order of attribute values within the vals set is undefined and implementation-dependent, and MUST NOT be relied upon. ๐ซ don't count on the order, it's not promised.
4.1.9. Matching Rule Identifier ๐
A matching rule is a means of expressing how a server should compare an AssertionValue received in a search filter with an abstract data value. The matching rule defines the syntax of the assertion value and the process to be performed in the server. ๐ง
An X.501(1993) Matching Rule is identified in the LDAP protocol by the printable representation of its OBJECT IDENTIFIER, either as one of the strings given in [5], or as decimal digits with components separated by periods, e.g. "caseIgnoreIA5Match" or "1.3.6.1.4.1.453.33.33". ๐
MatchingRuleId ::= LDAPString
Servers which support matching rules for use in the extensibleMatch search filter MUST list the matching rules they implement in subschema entries, using the matchingRules attributes. The server SHOULD also list there, using the matchingRuleUse attribute, the attribute types with which each matching rule can be used. More information is given in section 4.4 of [5]. ๐ the matching rules go in the subschema, with the server listing which attribute types each one works with.
4.1.10. Result Message โจ
okay so the LDAPResult is the construct this protocol uses to tell clients whether things went ๐ or ๐. servers send back responses with LDAPResult fields so you can see the final status of whatever operation you asked for. main character energy for status codes ๐
LDAPResult ::= SEQUENCE {
resultCode ENUMERATED {
success (0),
operationsError (1),
protocolError (2),
timeLimitExceeded (3),
sizeLimitExceeded (4),
compareFalse (5),
compareTrue (6),
authMethodNotSupported (7),
strongAuthRequired (8),
-- 9 reserved --
referral (10), -- new
adminLimitExceeded (11), -- new
unavailableCriticalExtension (12), -- new
confidentialityRequired (13), -- new
saslBindInProgress (14), -- new
noSuchAttribute (16),
undefinedAttributeType (17),
inappropriateMatching (18),
constraintViolation (19),
attributeOrValueExists (20),
invalidAttributeSyntax (21),
-- 22-31 unused --
noSuchObject (32),
aliasProblem (33),
invalidDNSyntax (34),
-- 35 reserved for undefined isLeaf --
aliasDereferencingProblem (36),
-- 37-47 unused --
inappropriateAuthentication (48),
invalidCredentials (49),
insufficientAccessRights (50),
busy (51),
unavailable (52),
unwillingToPerform (53),
loopDetect (54),
-- 55-63 unused --
namingViolation (64),
objectClassViolation (65),
notAllowedOnNonLeaf (66),
notAllowedOnRDN (67),
entryAlreadyExists (68),
objectClassModsProhibited (69),
-- 70 reserved for CLDAP --
affectsMultipleDSAs (71), -- new
-- 72-79 unused --
other (80) },
-- 81-90 reserved for APIs --
matchedDN LDAPDN,
errorMessage LDAPString,
referral [3] Referral OPTIONAL }
so basically every result code EXCEPT success, compareFalse and compareTrue means the operation did not fully finish ๐ those three are the only ones that count as a clean vibe check โจ
most of these codes are based on problem types from X.511 ๐ธ codes 16 to 21 are AttributeProblem, 32, 33, 34 and 36 are NameProblem, 48, 49 and 50 are SecurityProblem, 51 to 54 are ServiceProblem, and 64 to 69 plus 71 are UpdateProblem ๐ง
if a client gets a result code that isn't on this list, it has to treat it as an unknown error condition ๐ no guessing allowed ๐ญ
the errorMessage field can hold a textual, human-readable error diagnostic if the server wants to send one ๐ (terminal control and page formatting characters should be avoided). this diagnostic isn't standardized, so implementations MUST NOT rely on the values returned ๐
โโ๏ธ if the server doesn't send a text diagnostic, the errorMessage field of the LDAPResult type MUST contain a zero length string.
for the result codes noSuchObject, aliasProblem, invalidDNSyntax and aliasDereferencingProblem, the matchedDN field is set to the name of the lowest entry (object or alias) that got matched in the directory ๐ if no aliases were dereferenced while looking for the entry, it's a truncated form of the name you sent, or if aliases were dereferenced, it's a truncated form of the resulting name, as defined in section 12.5 of X.511 [8]. for all other result codes, the matchedDN field is set to a zero length string.
4.1.11. Referral ๐ฆ
this is the referral error, and it basically says "wrong server bestie, this one doesn't hold the target entry" ๐งญ the referral field shows up in an LDAPResult only when resultCode is referral, and it's absent for every other result code. it contains a reference to another server (or a set of servers) that you can reach over LDAP or other protocols. referrals can come back for any operation request (except unbind and abandon, which don't have responses). at least one URL MUST be present in the Referral โจ
the referral is NOT returned for a singleLevel or wholeSubtree search where the search scope spans multiple naming contexts and you'd need to contact several different servers to finish ๐ตโ๐ซ instead, you get continuation references, which are described in section 4.5.3 ๐
Referral ::= SEQUENCE OF LDAPURL -- one or more
LDAPURL ::= LDAPString -- limited to characters permitted in URLs
if the client wants to keep the operation going, it MUST follow the referral by contacting any one of the servers ๐โโ๏ธ all the URLs MUST be equally capable of being used to progress the operation ๐ (how multiple servers pull this off is outside the scope of this document, so that's a different story ๐)
URLs for servers that implement the LDAP protocol are written according to [9]. if an alias was dereferenced, the <dn> part of the URL MUST be present, with the new target object name ๐ if the <dn> part is there, the client MUST use that name in its next request to progress the operation. if it's not there, the client uses the same name as in the original request. some servers (for example, ones taking part in distributed indexing) might give you a different filter in a referral for a search operation ๐ง if the filter part of the URL is in an LDAPURL, the client MUST use that filter in its next request to progress the search, and if it's not there, the client MUST use the same filter it used for that search. the other parts of the new request can be the same or different from the request that made the referral ๐ซถ
heads up ๐จ UTF-8 characters in a DN or search filter might not be legal in URLs (spaces, for example), so they MUST be escaped using the % method in RFC 1738 [7] ๐
other kinds of URLs can be returned too, as long as the operation could be performed using that protocol โจ
4.1.12. Controls ๐
a control is a way to pass extension information ๐ controls sent as part of a request only apply to that request and are NOT saved ๐
Controls ::= SEQUENCE OF Control
Control ::= SEQUENCE {
controlType LDAPOID,
criticality BOOLEAN DEFAULT FALSE,
controlValue OCTET STRING OPTIONAL }
the controlType field MUST be a UTF-8 encoded dotted-decimal representation of an OBJECT IDENTIFIER that uniquely identifies the control ๐ฅ this stops control names from clashing ๐
the criticality field is either TRUE or FALSE ๐
if the server recognizes the control type and it fits the operation, the server will use the control when it performs the operation ๐ธ
if the server doesn't recognize the control type and criticality is TRUE, the server MUST NOT perform the operation, and MUST instead return the resultCode unsupportedCriticalExtension ๐
if the control doesn't fit the operation and criticality is TRUE, the server MUST NOT perform the operation, and MUST instead return the resultCode unsupportedCriticalExtension ๐
if the control is unrecognized or doesn't fit but criticality is FALSE, the server MUST ignore the control ๐ซ
the controlValue contains any info tied to the control, and its format is defined for that control ๐ง the server MUST be prepared to handle arbitrary contents of the controlValue octet string, including zero bytes ๐ช it's only absent if there's no value information associated with a control of its type โจ
this document doesn't define any controls ๐ โโ๏ธ controls can be defined in other documents. a control definition consists of:
- the OBJECT IDENTIFIER assigned to the control,
- whether the control is always noncritical, always critical, or critical at the client's option,
- the format of the
controlValuecontents of the control.
servers list the controls they recognize in the supportedControl attribute in the root DSE ๐
4.2. Bind Operation โจ
okay so the Bind Operation is basically how the client and server swap authentication info ๐ it's giving handshake energy, and it's lowkey the main character of the whole session ๐
The Bind Request is defined as follows:
BindRequest ::= [APPLICATION 0] SEQUENCE {
version INTEGER (1 .. 127),
name LDAPDN,
authentication AuthenticationChoice }
AuthenticationChoice ::= CHOICE {
simple [0] OCTET STRING,
-- 1 and 2 reserved
sasl [3] SaslCredentials }
SaslCredentials ::= SEQUENCE {
mechanism LDAPString,
credentials OCTET STRING OPTIONAL }
Okay, so there are three parameters in the Bind Request ๐
- version: this is the protocol version the session is going to use. This document is about version 3 of LDAP โจ There's no version negotiation, so the client just sets this to whatever version it wants. If the client asks for protocol version 2, a server that supports the version 2 protocol described in [2] won't return any v3-specific protocol fields ๐ (Fair warning, not every LDAP server does version 2, because they might not be able to generate the attribute syntaxes that go with it.)
- name: this is the directory object the client wants to bind as ๐ It can be a null value (a zero length string) for anonymous binds, when authentication already happened at a lower layer, or when you're using SASL credentials with a mechanism that puts the LDAPDN inside the credentials.
- authentication: this is the info used to authenticate the name, if there's any in the Bind Request ๐
So when a Bind Request comes in, the protocol server authenticates the requesting client, if that's needed. Then it sends back a Bind Response that tells the client how the authentication went ๐ซถ
Authorization is using that authentication info while doing operations. Authorization MAY be affected by stuff outside the LDAP Bind request, like lower layer security services ๐
4.2.1. Sequencing of the Bind Request โจ
ngl this part is so important for not getting stuck in a loop ๐ Some SASL mechanisms need the client to send the BindRequest more than once. If the client wants to quit the bind process at any point, it MAY unbind and then drop the underlying connection ๐ฆ Also, clients MUST NOT invoke operations between two Bind requests made as part of a multi-stage bind. No sneaking operations in the middle, bestie ๐ โโ๏ธ
A client can abort a SASL bind negotiation by sending a BindRequest with a different value in the mechanism field of SaslCredentials, or an AuthenticationChoice other than sasl ๐
If the client sends a BindRequest with the sasl mechanism field as an empty string, the server MUST return a BindResponse with authMethodNotSupported as the resultCode. This lets clients bail out of a negotiation if they want to try again with the same SASL mechanism ๐ธ
Unlike LDAP v2, the client doesn't have to send a Bind Request in the first PDU of the connection ๐ง The client can ask for any operations, and the server MUST treat them as unauthenticated. If the server wants the client to bind before it browses or changes the directory, the server MAY reject any request other than binding, unbinding, or an extended request with the "operationsError" result ๐
If the client didn't bind before sending a request and gets an operationsError, it can then send a Bind Request. If that also fails, or the client decides not to bind on the existing connection, it closes the connection, reopens it, and starts over by sending a PDU with a Bind Request first ๐ This helps it play nice with servers running other versions of LDAP ๐ค
Clients MAY send multiple bind requests on a connection to change their credentials โจ A later bind process abandons every operation still outstanding on the connection. (This makes the server side simpler, which is iconic ๐) Authentication from earlier binds gets ignored, so if the bind fails, the connection gets treated as anonymous. If a SASL transfer encryption or integrity mechanism has been negotiated, and that mechanism can't switch credentials from one identity to another, then the client MUST establish a new connection instead ๐จ
4.2.2. Authentication and Other Security Services ๐
The simple authentication option is the most basic one. The authentication field only holds a cleartext password ๐ฌ Using cleartext passwords over open networks is not recommended when no lower layer is doing authentication or encryption. Check out the "Security Considerations" section for the full story ๐
If there's no authentication to do, the simple authentication option MUST be chosen, and the password has to be zero length. (LDAPv2 clients do this a lot.) The DN is usually zero length too ๐
The sasl choice works with any mechanism defined for use with SASL [12] โจ The mechanism field holds the mechanism's name. The credentials field holds the arbitrary data used for authentication, wrapped inside an OCTET STRING. LDAP isn't text-based, unlike some other internet protocols that use SASL, so no base64 transformations get done on the credentials ๐ โโ๏ธ
If any SASL-based integrity or confidentiality services are turned on, they kick in after the server sends the final BindResponse with resultCode success and the client receives it ๐ก๏ธ
The client can ask the server to use authentication info from a lower layer protocol by using the SASL EXTERNAL mechanism ๐ฆ
4.2.3. Bind Response ๐
The Bind Response is defined as follows:
BindResponse ::= [APPLICATION 1] SEQUENCE {
COMPONENTS OF LDAPResult,
serverSaslCreds [7] OCTET STRING OPTIONAL }
The Bind Response is basically the server telling the client how its authentication request went ๐ฌ
If the bind worked, the resultCode is success. Otherwise, it's one of these:
- operationsError: the server ran into an internal error, ๐ฅ
- protocolError: the version number isn't recognized, or the PDU structure is wrong, ๐
- authMethodNotSupported: the SASL mechanism name isn't recognized, ๐คทโโ๏ธ
- strongAuthRequired: the server needs authentication to happen with a SASL mechanism, ๐
- referral: this server can't accept this bind, so the client should try another one, ๐
- saslBindInProgress: the server needs the client to send a new bind request, using the same sasl mechanism, to keep the authentication going ๐
- inappropriateAuthentication: the client tried to bind anonymously or without credentials, and the server needs it to supply some kind of credentials ๐โโ๏ธ
- invalidCredentials: the password was wrong, or the SASL credentials couldn't be processed ๐ญ
- unavailable: the server is shutting down ๐
If the server doesn't support the client's requested protocol version, it MUST set the resultCode to protocolError ๐ซ
If the client gets a BindResponse where the resultCode was protocolError, it MUST close the connection, because the server won't accept more operations after that ๐ (This is for compatibility with older LDAP versions, where the bind was always the very first operation and there was no negotiation. Very throwback ๐ฐ๏ธ)
The serverSaslCreds are used as part of a SASL-defined bind mechanism. They let the client authenticate the server it's talking to, or do "challenge-response" authentication ๐ค If the client bound with the password choice, or the SASL mechanism doesn't need the server to send info back to the client, then this field isn't included in the result โจ
4.3. Unbind Operation ๐
The Unbind Operation is how you end a protocol session ๐งน It's defined as follows:
UnbindRequest ::= [APPLICATION 2] NULL
There's no response defined for the Unbind Operation. Once a protocol client sends an UnbindRequest, it can assume the session is over ๐ซถ When a protocol server gets an UnbindRequest, it can assume the client is done, throw away any outstanding requests, and close the connection ๐
4.4. Unsolicited Notification ๐ฃ
An unsolicited notification is an LDAPMessage the server sends to the client without the client asking for it ๐ The server uses it to signal something extraordinary going on in the server or on the connection between it and the client ๐จ It's advisory, so the server doesn't expect the client to reply ๐
The unsolicited notification is structured as an LDAPMessage with a messageID of 0 and a protocolOp in the extendedResp form. The responseName field of the ExtendedResponse is present. The LDAPOID value MUST be unique to this notification, and it can't be used in any other situation ๐
Only one unsolicited notification is defined in this document ๐ธ
4.4.1. Notice of Disconnection ๐ช
The server can use this notification to tell the client it's about to close the connection because of an error condition ๐ต Note that this notification is NOT a response to an unbind the client asked for. The server MUST follow the procedures of section 4.3 instead. This notification is there to help clients tell an error condition apart from a temporary network failure ๐ง Like with a connection closed by a network failure, the client MUST NOT assume that any outstanding requests which changed the directory succeeded or failed ๐ค
The responseName is 1.3.6.1.4.1.1466.20036, the response field is absent, and the resultCode tells you why the connection is dropping ๐
These resultCode values are used in this notification:
- protocolError: the server got data from the client that couldn't be parsed as an LDAPMessage structure. ๐
- strongAuthRequired: the server noticed that the security association protecting the communication between client and server has unexpectedly failed or been compromised. ๐จ๐
- unavailable: this server is going to stop accepting new connections and operations on all existing connections, and it'll be unavailable for a while. The client can use an alternative server instead. ๐
After sending this notice, the server MUST close the connection ๐ After receiving it, the client MUST NOT transmit anything else on the connection, and it may close the connection abruptly ๐ฅ
4.5. Search Operation ๐
The Search Operation lets a client ask a server to run a search for it ๐ต๏ธโโ๏ธ It can be used to read attributes from a single entry, from the entries immediately below a particular entry, or from a whole subtree of entries ๐ณ literally so useful ๐
4.5.1. Search Request โจ
Okay bestie, here's how the Search Request is laid out ๐:
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 AttributeDescriptionList }
Filter ::= CHOICE {
and [0] SET OF Filter,
or [1] SET OF 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,
-- at least one must be present
substrings SEQUENCE OF CHOICE {
initial [0] LDAPString,
any [1] LDAPString,
final [2] LDAPString } }
MatchingRuleAssertion ::= SEQUENCE {
matchingRule [1] MatchingRuleId OPTIONAL,
type [2] AttributeDescription OPTIONAL,
matchValue [3] AssertionValue,
dnAttributes [4] BOOLEAN DEFAULT FALSE }
Now the parameters of the Search Request, the fun part ๐ :
baseObject: anLDAPDN๐ธ that names the base object entry the search is performed relative to.scope: this tells the server how wide the search is ๐ฆ. The values mean exactly the same thing as the scope field in the X.511 Search Operation.derefAliases: this decides how alias objects (as defined in X.501) get handled when searching ๐. The possible values are:neverDerefAliases: aliases are not dereferenced, either while searching or while locating the base object of the search.derefInSearching: aliases are dereferenced in subordinates of the base object while searching, but not while locating the base object of the search.derefFindingBaseObj: aliases are dereferenced while locating the base object of the search, but not when searching subordinates of the base object.derefAlways: aliases are dereferenced both while searching and while locating the base object of the search.
sizelimit: a limit on the maximum number of entries returned by the search ๐ง. A value of0means no client-requested sizelimit restrictions are in effect for the search. Servers may enforce a maximum number of entries to return.timelimit: a limit on the maximum time, in seconds, allowed for a search โฐ. A value of0means no client-requested timelimit restrictions are in effect for the search.typesOnly: this one decides whether results include both attribute types and values, or just the types ๐. Setting it toTRUEmeans only attribute types come back (no values). Setting it toFALSEmeans both attribute types and values come back.filter: this is the set of conditions an entry has to fulfill for the search to match it ๐.
The and, or and not choices can be used to combine filters into combos ๐งฉ. At least one filter element MUST be present in an and or or choice. The others match against individual attribute values of entries in the scope of the search. (Implementor's note: the not filter is an example of a tagged choice in an implicitly-tagged module. In BER this is treated as if the tag was explicit.)
A server MUST evaluate filters according to the three-valued logic of X.511(93) section 7.8.1 ๐ฅ. Basically, a filter comes out as TRUE, FALSE or Undefined. If the filter comes out TRUE for a particular entry, that entry's attributes are returned as part of the search result (subject to any applicable access control restrictions) โจ. If it comes out FALSE or Undefined, the entry gets ignored for the search ๐
โโ๏ธ.
An and filter is TRUE if all the filters in the SET OF evaluate to TRUE, FALSE if at least one of them is FALSE, and otherwise Undefined. An or filter is FALSE if all of the filters in the SET OF evaluate to FALSE, TRUE if at least one of them is TRUE, and Undefined otherwise. A not filter is TRUE if the filter being negated is FALSE, FALSE if it is TRUE, and Undefined if the negated filter is Undefined ๐.
The present match evaluates to TRUE where an entry has an attribute, or a subtype of the specified attribute description, present. Otherwise it's FALSE ๐ธ. That includes a presence test using an attribute description the server doesn't recognize.
The extensibleMatch is brand new in this version of LDAP ๐. If the matchingRule field is absent, the type field MUST be present, and the equality match is performed for that type. If the type field is absent and matchingRule is present, the matchValue gets compared against all attributes in an entry that support that matchingRule, and the matchingRule decides the syntax for the assertion value. The filter item comes out TRUE if it matches at least one attribute in the entry, FALSE if it doesn't match any attribute in the entry, and Undefined if the matchingRule isn't recognized or the assertion value can't be parsed. If the type field is present and matchingRule is present, the matchingRule MUST be one permitted for use with that type, otherwise the filter item is undefined. If the dnAttributes field is set to TRUE, the match is also applied against all the attributes in an entry's distinguished name, and it evaluates to TRUE if at least one of those attributes gives TRUE for the filter item. (Editors note: The dnAttributes field is present so that there does not need to be multiple versions of generic matching rules such as for word matching, one to apply to entries and another to apply to entries and dn attributes as well).
A filter item evaluates to Undefined when the server wouldn't be able to figure out whether the assertion value matches an entry ๐ค. That happens if an attribute description in an equalityMatch, substrings, greaterOrEqual, lessOrEqual, approxMatch or extensibleMatch filter isn't recognized by the server, if a matching rule id in the extensibleMatch isn't recognized, if the assertion value can't be parsed, or if the type of filtering requested isn't implemented. For example, if a server didn't recognize the attribute type shoeSize, then (shoeSize=*) would evaluate to FALSE, while (shoeSize=12), (shoeSize>=12) and (shoeSize<=12) would all evaluate to Undefined ๐.
Servers MUST NOT return errors if attribute descriptions or matching rule ids aren't recognized, or if assertion values can't be parsed ๐ โโ๏ธ๐. More details of filter processing are given in section 7.8 of X.511 [8].
attributes: a list of the attributes to return from each entry that matches the search filter ๐. There are two special values you can use: an empty list with no attributes, and the attribute description string*. Both of these mean all user attributes get returned. (The*lets the client ask for all user attributes on top of specific operational attributes ๐ฆ.)
Attributes MUST be named at most once in the list, and they get returned at most once in an entry. If the list has attribute descriptions that aren't recognized, the server just ignores them ๐ซถ.
If the client doesn't want any attributes back, it can give a list with only the attribute with OID 1.1 ๐. That OID was picked arbitrarily and doesn't match any attribute in use.
Client implementors, listen up ๐: even if you request all user attributes, some attributes of the entry might still be left out of the search results because of access control or other restrictions. Also, servers won't return operational attributes, like objectClasses or attributeTypes, unless you list them by name, since some operational attributes can have an extremely large number of values ๐ญ. (A list of operational attributes for use in LDAP is given in [5].)
Note that an X.500 "list"-like operation can be faked by the client sending a one-level LDAP search with a filter that checks for the existence of the objectClass attribute ๐ง. Similarly, an X.500 "read"-like operation can be faked with a base object LDAP search using that same filter ๐. A server that provides a gateway to X.500 isn't required to use the Read or List operations, although it may choose to do so. If it does, it must provide the same semantics as the X.500 search operation ๐.
4.5.2. Search Result โจ
okay so the results of a search go back to the client inside Search Responses ๐ These are LDAP messages, and each one carries either a SearchResultEntry, a SearchResultReference, an ExtendedResponse, or a SearchResultDone. that's the whole cast ๐
SearchResultEntry ::= [APPLICATION 4] SEQUENCE {
objectName LDAPDN,
attributes PartialAttributeList }
PartialAttributeList ::= SEQUENCE OF SEQUENCE {
type AttributeDescription,
vals SET OF AttributeValue }
-- implementors should note that the PartialAttributeList may
-- have zero elements (if none of the attributes of that entry
-- were requested, or could be returned), and that the vals set
-- may also have zero elements (if types only was requested, or
-- all values were excluded from the result.)
SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL
-- at least one LDAPURL element must be present
SearchResultDone ::= [APPLICATION 5] LDAPResult
the moment a server gets a Search Request, it goes off and does the search of the DIT ๐
if the LDAP session is running over a connection-oriented transport like TCP, the server sends back a bunch of responses, each in its own LDAP message ๐ฌ there can be zero or more SearchResultEntry responses, one for each entry it finds. there can also be zero or more SearchResultReference responses, one for each area the server didn't explore during the search ๐บ๏ธ the SearchResultEntry and SearchResultReference PDUs can show up in any order, so don't get thrown if they're jumbled ๐ once every SearchResultReference and every SearchResultEntry is sent, the server wraps it up with a SearchResultDone response. that one says whether things went well, or spells out any errors that happened ๐
each entry in a SearchResultEntry has all the attributes you asked for in the attributes field of the Search Request, with their values included when needed ๐ง but getting attributes back is subject to access control and other administrative policy, so it's not automatically a free-for-all ๐ some attributes can come back in binary format, and you'll spot that because the AttributeDescription in the response has the binary option present ๐ธ
some attributes are constructed by the server and show up in a SearchResultEntry attribute list even though they aren't stored attributes of the entry โจ so, important bit: Clients MUST NOT assume that all attributes can be modified, even if permitted by access control. ๐ซ seeing an attribute doesn't mean you get to change it, bestie ๐
LDAPMessage responses in the ExtendedResponse form are reserved for sending back information tied to a control the client asked for ๐ these might get defined in future versions of this document ๐ฎ
4.5.3. Continuation References in the Search Result
ok this part is about when the server finds the entry called the baseObject but can't search everything in the scope at and under it ๐ in that case the server may send back one or more SearchResultReference responses. each one points to another set of servers that can continue the operation ๐ฆ A server MUST NOT return any SearchResultReference if it has not located the baseObject and thus has not searched any entries; in that situation it returns a SearchResultDone with a referral resultCode instead ๐
if the server doesn't have indexing info from the servers that hold the subordinate naming contexts, then SearchResultReference responses aren't filtered by the search filters. they're always returned when they're in scope ๐
the SearchResultReference is the same data type as the Referral. URLs for servers implementing the LDAP protocol are written according to [9]. The <dn> part MUST be present in the URL, with the new target object name. The client MUST use this name in its next request. ๐ฏ some servers (like part of a distributed index exchange system) might give a different filter in the URLs of the SearchResultReference ๐งฉ if the filter part is in the LDAP URL, then the client MUST use the new filter in its next request to progress the search. if the filter part is absent, the client just uses the same filter again ๐ other parts of the new search request can be the same or different from the search that made the continuation references ๐ซ
other kinds of URLs can come back too, as long as the operation could be done using that protocol ๐ธ
the name of an unexplored subtree in a SearchResultReference doesn't have to be subordinate to the base object ๐คทโโ๏ธ
to finish the search, the client MUST issue a new search operation for each SearchResultReference that is returned. ๐จ also, the abandon operation in section 4.11 only applies to one particular operation sent on a connection between a client and server. so if you've got multiple outstanding search operations going to different servers, it MUST abandon each operation individually. ๐ โโ๏ธ very main character energy of you to keep track of all of them ๐
4.5.3.1. Example
okay let's walk through this with some hosts ๐ง say the contacted server (hosta) holds the entry "O=MNN,C=WW" and the entry "CN=Manager,O=MNN,C=WW". it knows that either LDAP-capable servers (hostb) or (hostc) hold "OU=People,O=MNN,C=WW" (one is the master and the other server a shadow). and LDAP-capable server (hostd) holds the subtree "OU=Roles,O=MNN,C=WW". if a subtree search of "O=MNN,C=WW" is requested to the contacted server, it may return the following:
SearchResultEntry for O=MNN,C=WW
SearchResultEntry for CN=Manager,O=MNN,C=WW
SearchResultReference {
ldap://hostb/OU=People,O=MNN,C=WW
ldap://hostc/OU=People,O=MNN,C=WW
}
SearchResultReference {
ldap://hostd/OU=Roles,O=MNN,C=WW
}
SearchResultDone (success)
client implementors, pay attention here ๐ when you follow a SearchResultReference, you might get additional SearchResultReference responses generated too ๐ continuing the example, if the client contacted the server (hostb) and issued the search for the subtree "OU=People,O=MNN,C=WW", the server might respond like this:
SearchResultEntry for OU=People,O=MNN,C=WW
SearchResultReference {
ldap://hoste/OU=Managers,OU=People,O=MNN,C=WW
}
SearchResultReference {
ldap://hostf/OU=Consultants,OU=People,O=MNN,C=WW
}
SearchResultDone (success)
and if the contacted server doesn't hold the base object for the search, it sends back a referral to the client ๐ for example, if the client requests a subtree search of "O=XYZ,C=US" to hosta, the server may return only a SearchResultDone containing a referral:
SearchResultDone (referral) {
ldap://hostg/
}
4.6. Modify Operation
the Modify Operation lets a client ask a server to modify an entry for it ๐ the Modify Request is defined like this:
ModifyRequest ::= [APPLICATION 6] SEQUENCE {
object LDAPDN,
modification SEQUENCE OF SEQUENCE {
operation ENUMERATED {
add (0),
delete (1),
replace (2) },
modification AttributeTypeAndValues } }
AttributeTypeAndValues ::= SEQUENCE {
type AttributeDescription,
vals SET OF AttributeValue }
Parameters of the Modify Request are:
- object: The object to be modified. The value of this field contains the DN of the entry to be modified. The server will not perform any alias dereferencing in determining the object to be modified. ๐ฏ
- modification: A list of modifications to be performed on the entry. The entire list of entry modifications MUST be performed in the order they are listed, as a single atomic operation. While individual modifications may violate the directory schema, the resulting entry after the entire list of modifications is performed MUST conform to the requirements of the directory schema. ๐ the values that the
'operation'field can take in each modification construct have these semantics, respectively:- add: add values listed to the given attribute, creating the attribute if necessary; โ
- delete: delete values listed from the given attribute, removing the entire attribute if no values are listed, or if all current values of the attribute are listed for deletion; ๐๏ธ
- replace: replace all existing values of the given attribute with the new values listed, creating the attribute if it did not already exist. A replace with no value will delete the entire attribute if it exists, and is ignored if the attribute does not exist. ๐
the server sends back the result of the modify it attempted in a Modify Response, defined like so ๐
ModifyResponse ::= [APPLICATION 7] LDAPResult
once the server gets a Modify Request, it does the necessary modifications to the DIT โจ the server returns a single Modify Response that says either the DIT modification finished successfully, or why it failed ๐ซ because the list of modifications in the Modify Request has to be atomic, the client can expect that no modifications were performed if the Modify Response shows any sort of error. and if the Modify Response says the Modify Operation completed successfully, then all the requested modifications were performed ๐ซถ but if the connection fails, it's indeterminate whether the modification happened or not ๐ญ
the Modify Operation cannot be used to remove any of an entry's distinguished values, the ones that form the entry's relative distinguished name ๐ซ trying to do that gets you the error notAllowedOnRDN. if you want to rename an entry, use the Modify DN Operation described in section 4.9 instead ๐ฆ
if an equality match filter hasn't been defined for an attribute type, clients MUST NOT attempt to delete individual values of that attribute from an entry using the "delete" form of a modification, and MUST instead use the "replace" form. ๐ it's giving "replace or nothing" for that situation ๐
last thing, and it matters: because LDAP is simplified, there isn't a direct mapping from the modifications in an LDAP ModifyRequest onto the EntryModifications of a DAP ModifyEntry operation. different LDAP-DAP gateway implementations may represent the change in different ways ๐ but if successful, the final effect of the operations on the entry MUST be identical. ๐ the vibe can differ, but the result has to match, periodt ๐
4.7. Add Operation โจ
Okay so the Add Operation is how a client asks the server to add a brand new entry to the directory ๐ธ The Add Request looks like this:
AddRequest ::= [APPLICATION 8] SEQUENCE {
entry LDAPDN,
attributes AttributeList }
AttributeList ::= SEQUENCE OF SEQUENCE {
type AttributeDescription,
vals SET OF AttributeValue }
The parameters of the Add Request are:
entry: the Distinguished Name of the entry to be added. Ngl, the server won't dereference any aliases while it's hunting for the entry being added ๐attributes: the list of attributes that make up the content of the entry being added. Clients MUST include distinguished values (the ones forming the entry's own RDN) in this list, theobjectClassattribute, and values of any mandatory attributes of the listed object classes. Clients MUST NOT supply thecreateTimestamporcreatorsNameattributes, since the server generates those automatically ๐ค
The entry named in the entry field of the AddRequest MUST NOT exist for the AddRequest to succeed. The parent of the entry to be added MUST exist. Picture this: a client tries to add "CN=JS,O=Foo,C=US", but "O=Foo,C=US" doesn't exist, while "C=US" does. The server would return the error noSuchObject with the matchedDN field set to "C=US" ๐ If the parent entry exists but lives outside any naming context the server holds, the server SHOULD return a referral to the server that holds the parent entry ๐ฆ
Servers implementations SHOULD NOT restrict where entries can be located in the directory. Some servers MAY allow the administrator to restrict which classes of entries can be added to the directory ๐
When an Add Request arrives, the server will try to do the add it asked for. The result comes back to the client in the Add Response:
AddResponse ::= [APPLICATION 9] LDAPResult
A success response means the new entry is now present in the directory. Iconic ๐
4.8. Delete Operation
The Delete Operation lets a client ask for an entry to be removed from the directory ๐๏ธ The Delete Request is defined like this:
DelRequest ::= [APPLICATION 10] LDAPDN
The Delete Request is just the Distinguished Name of the entry to be deleted. The server won't dereference aliases while it resolves the name of the target entry, and only leaf entries (the ones with no subordinate entries) can be deleted with this operation. So no deleting the whole family tree in one go ๐ณ๐ซ
The server reports the result of the delete attempt in the Delete Response:
DelResponse ::= [APPLICATION 11] LDAPResult
When a Delete Request comes in, the server will try to remove the entry. The result of that attempt goes back to the client in the Delete Response ๐ซถ
4.9. Modify DN Operation
The Modify DN Operation lets a client change the leftmost (least significant) component of an entry's name, or move a whole subtree of entries to a new spot in the directory ๐ฆ Here's the Modify DN Request:
ModifyDNRequest ::= [APPLICATION 12] SEQUENCE {
entry LDAPDN,
newrdn RelativeLDAPDN,
deleteoldrdn BOOLEAN,
newSuperior [0] LDAPDN OPTIONAL }
The parameters of the Modify DN Request are:
entry: the Distinguished Name of the entry to be changed. This entry may or may not have subordinate entries.newrdn: the RDN that will form the leftmost component of the entry's new name.deleteoldrdn: a boolean parameter that controls whether the old RDN attribute values are kept as attributes of the entry, or deleted from it ๐งนnewSuperior: if it's present, this is the Distinguished Name of the entry that becomes the immediate superior of the existing entry ๐
The server reports the result of the name change in the Modify DN Response:
ModifyDNResponse ::= [APPLICATION 13] LDAPResult
When a ModifyDNRequest arrives, the server will try to perform the name change. The result of that attempt is returned to the client in the Modify DN Response โจ
Here's an example. Say the entry named in the "entry" parameter is "cn=John Smith,c=US", the newrdn parameter is "cn=John Cougar Smith", and newSuperior is absent. Then this operation tries to rename the entry to "cn=John Cougar Smith,c=US". If an entry with that name already exists, the operation fails with the error code entryAlreadyExists ๐
If deleteoldrdn is TRUE, the values forming the old RDN get deleted from the entry. If it's FALSE, those values stick around as non-distinguished attribute values of the entry. The server may skip the operation and return an error code if the deleteoldrdn setting would cause a schema inconsistency in the entry ๐ค
Heads up, bestie: X.500 only lets the ModifyDN operation touch entries that live inside a single server. If the LDAP server is mapped onto DAP, that restriction applies, and the resultCode affectsMultipleDSAs comes back if this error happens. In general, clients MUST NOT expect to be able to move entries and subtrees between servers whenever they feel like it ๐ซ
4.10. Compare Operation
The Compare Operation lets a client check an assertion against an entry in the directory ๐ The Compare Request is defined as follows:
CompareRequest ::= [APPLICATION 14] SEQUENCE {
entry LDAPDN,
ava AttributeValueAssertion }
The parameters of the Compare Request are:
entry: the name of the entry to be compared with.ava: the assertion that an attribute in the entry is to be compared against.
The server reports the result of the compare in the Compare Response:
CompareResponse ::= [APPLICATION 15] LDAPResult
When a Compare Request arrives, the server will try to do the requested comparison. The result comes back to the client in the Compare Response. Note that errors and the comparison result are all returned in the same construct, so keep your eyes peeled ๐
Some directory systems may set up access controls that let certain attributes (like userPassword) be compared but not read ๐ In a search result, an attribute of that type might come back with an empty set of values. Sneaky, right? ๐
4.11. Abandon Operation
The Abandon Operation lets a client ask the server to abandon an operation that's still outstanding ๐ The Abandon Request is defined as follows:
AbandonRequest ::= [APPLICATION 16] MessageID
The MessageID MUST be that of a an operation which was requested earlier in this connection.
(The abandon request has its own message id too. That's different from the id of the earlier operation being abandoned, so don't mix them up ๐ง )
There's no response defined for the Abandon Operation. Once a client sends an Abandon Operation, it can expect that the operation identified by the Message ID in the Abandon Request has been abandoned ๐ซ If a server gets an Abandon Request for a Search Operation while it's in the middle of sending search responses, that server MUST cease transmitting entry responses to the abandoned request immediately, and MUST NOT send the SearchResponseDone. Of course, the server MUST ensure that only properly encoded LDAPMessage PDUs are transmitted ๐
Clients MUST NOT send abandon requests for the same operation multiple times. They MUST also be prepared to receive results from operations they've abandoned, since those may have been in transit when the abandon was requested ๐ฌ
Servers MUST discard abandon requests for message IDs they don't recognize, for operations that can't be abandoned, and for operations that have already been abandoned ๐๏ธ
4.12. Extended Operation
An extension mechanism was added in this version of LDAP so that additional operations can be defined for services that aren't available anywhere else in the protocol, like digitally signed operations and results โ๏ธ๐ฅ
The extended operation lets clients make requests and receive responses with predefined syntaxes and semantics. These may be defined in RFCs or be private to particular implementations. Each request MUST have a unique OBJECT IDENTIFIER assigned to it ๐
ExtendedRequest ::= [APPLICATION 23] SEQUENCE {
requestName [0] LDAPOID,
requestValue [1] OCTET STRING OPTIONAL }
The requestName is a dotted-decimal representation of the OBJECT IDENTIFIER that corresponds to the request. The requestValue is information in a form defined by that request, wrapped up inside an OCTET STRING ๐
The server responds to this with an LDAPMessage containing the ExtendedResponse:
ExtendedResponse ::= [APPLICATION 24] SEQUENCE {
COMPONENTS OF LDAPResult,
responseName [10] LDAPOID OPTIONAL,
response [11] OCTET STRING OPTIONAL }
If the server doesn't recognize the request name, it MUST return only the response fields from LDAPResult, containing the protocolError result code ๐ฌ
5. Protocol Element Encodings and Transfer โจ
Only one underlying service is defined here. Clients and servers SHOULD implement the mapping of LDAP over TCP described in 5.2.1 ๐งฆ
5.1. Mapping Onto BER-based Transport Services
The protocol elements of LDAP are encoded for exchange using the Basic Encoding Rules (BER) [11] of ASN.1 [3]. But BER has a lot of overhead for certain elements, so there are extra restrictions on BER-encodings of LDAP protocol elements ๐ They are:
- Only the definite form of length encoding will be used.
OCTET STRINGvalues will be encoded in the primitive form only.- If the value of a BOOLEAN type is true, the encoding MUST have its contents octets set to hex "FF".
- If a value of a type is its default value, it MUST be absent. Only some BOOLEAN and INTEGER types have default values in this protocol definition.
These restrictions don't apply to ASN.1 types wrapped inside OCTET STRING values, such as attribute values, unless it's noted otherwise ๐
5.2. Transfer Protocols
This protocol is designed to run over connection-oriented, reliable transports, with all 8 bits in an octet being significant in the data stream ๐ง
5.2.1. Transmission Control Protocol (TCP)
The LDAPMessage PDUs get mapped directly onto the TCP bytestream ๐ It is recommended that server implementations running over TCP MAY provide a protocol listener on the assigned port, 389. Servers may instead provide a listener on a different port number. Clients MUST support contacting servers on any valid TCP port ๐
6. Implementation Guidelines โจ
This document describes an Internet protocol ๐
6.1. Server Implementations ๐
okay so the server MUST be capable of recognizing all the mandatory attribute type names and implementing the syntaxes specified in [5]. Servers MAY also recognize additional attribute type names ๐ง
6.2. Client Implementations ๐
bestie, clients that request referrals MUST make sure they don't loop between servers. They MUST NOT repeatedly contact the same server for the same request with the same target entry name, scope and filter. Some clients might be using a counter that goes up each time referral handling happens for an operation, and these kinds of clients MUST be able to handle a DIT with at least ten layers of naming contexts between the root and a leaf entry ๐ญ
Unless you've already agreed on things with a server, clients SHOULD NOT assume that servers support any particular schemas beyond the ones referenced in section 6.1. Different schemas can have different attribute types with the same names, so it's giving confusion if you don't check ๐ The client can retrieve the subschema entries referenced by the subschemaSubentry attribute in the server's root DSE or in entries held by the server โจ
7. Security Considerations ๐ฅ
okay this section is SERIOUS, so pay attention ๐
When used with a connection-oriented transport, this version of the protocol provides facilities for the LDAP v2 authentication mechanism, simple authentication using a cleartext password, as well as any SASL mechanism [12]. SASL allows for integrity and privacy services to be negotiated ๐
It is also permitted that the server can return its credentials to the client, if it chooses to do so.
Cleartext passwords are strongly discouraged where the underlying transport service cannot guarantee confidentiality, because they may result in disclosure of the password to unauthorized parties. Not the vibe ๐
When used with SASL, it should be noted that the name field of the BindRequest is not protected against modification. Thus, if the distinguished name of the client (an LDAPDN) is agreed through the negotiation of the credentials, it takes precedence over any value in the unprotected name field ๐ซถ
Implementations which cache attributes and entries obtained via LDAP MUST ensure that access controls are maintained if that information is to be provided to multiple clients, since servers may have access control policies which prevent the return of entries or attributes in search results except to particular authenticated clients. For example, caches could serve result information only to the client whose request caused it to be cache ๐
8. Acknowledgements ๐ธ
This document is an update to RFC 1777, by Wengyik Yeong, Tim Howes, and Steve Kille. Design ideas included in this document are based on those discussed in ASID and other IETF Working Groups. The contributions of individuals in these working groups is gratefully acknowledged ๐
9. Bibliography ๐
[1] ITU-T Rec. X.500, "The Directory: Overview of Concepts, Models and Service", 1993.
[2] Yeong, W., Howes, T., and S. Kille, "Lightweight Directory Access Protocol", RFC 1777, March 1995.
[3] ITU-T Rec. X.680, "Abstract Syntax Notation One (ASN.1) - Specification of Basic Notation", 1994.
[4] Kille, S., Wahl, M., and T. Howes, "Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names", RFC 2253, December 1997.
[5] Wahl, M., Coulbeck, A., Howes, T., and S. Kille, "Lightweight Directory Access Protocol (v3): Attribute Syntax Definitions", RFC 2252, December 1997.
[6] ITU-T Rec. X.501, "The Directory: Models", 1993.
[7] Berners-Lee, T., Masinter, L., and M. McCahill, "Uniform Resource Locators (URL)", RFC 1738, December 1994.
[8] ITU-T Rec. X.511, "The Directory: Abstract Service Definition", 1993.
[9] Howes, T., and M. Smith, "The LDAP URL Format", RFC 2255, December 1997.
[10] Bradner, S., "Key words for use in RFCs to Indicate Requirement Levels", RFC 2119, March 1997.
[11] ITU-T Rec. X.690, "Specification of ASN.1 encoding rules: Basic, Canonical, and Distinguished Encoding Rules", 1994.
[12] Meyers, J., "Simple Authentication and Security Layer", RFC 2222, October 1997.
[13] Universal Multiple-Octet Coded Character Set (UCS) - Architecture and Basic Multilingual Plane, ISO/IEC 10646-1 : 1993.
[14] Yergeau, F., "UTF-8, a transformation format of Unicode and ISO 10646", RFC 2044, October 1996.
10. Authors' Addresses ๐
Mark Wahl
Mark Wahl
Critical Angle Inc.
4815 W Braker Lane #502-385
Austin, TX 78759
USA
Phone: +1 512 372-3160
EMail: M.Wahl@critical-angle.com
Tim Howes
Tim Howes
Netscape Communications Corp.
501 E. Middlefield Rd., MS MV068
Mountain View, CA 94043
USA
Phone: +1 650 937-3419
EMail: howes@netscape.com
Steve Kille
Steve Kille
Isode Limited
The Dome, The Square
Richmond
TW9 1DT
UK
Phone: +44-181-332-9091
EMail: S.Kille@isode.com
Appendix A - Complete ASN.1 Definition โจ
okay bestie, this is the full ASN.1 definition all in one place ๐ง every type is here exactly as written, so you can copy it straight from the page ๐
Lightweight-Directory-Access-Protocol-V3 DEFINITIONS
IMPLICIT TAGS ::=
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 },
controls [0] Controls OPTIONAL }
MessageID ::= INTEGER (0 .. maxInt)
maxInt INTEGER ::= 2147483647 -- (2^^31 - 1) --
LDAPString ::= OCTET STRING
LDAPOID ::= OCTET STRING
LDAPDN ::= LDAPString
RelativeLDAPDN ::= LDAPString
AttributeType ::= LDAPString
AttributeDescription ::= LDAPString
AttributeDescriptionList ::= SEQUENCE OF
AttributeDescription
AttributeValue ::= OCTET STRING
AttributeValueAssertion ::= SEQUENCE {
attributeDesc AttributeDescription,
assertionValue AssertionValue }
AssertionValue ::= OCTET STRING
Attribute ::= SEQUENCE {
type AttributeDescription,
vals SET OF AttributeValue }
MatchingRuleId ::= LDAPString
LDAPResult ::= SEQUENCE {
resultCode ENUMERATED {
success (0),
operationsError (1),
protocolError (2),
timeLimitExceeded (3),
sizeLimitExceeded (4),
compareFalse (5),
compareTrue (6),
authMethodNotSupported (7),
strongAuthRequired (8),
-- 9 reserved --
referral (10), -- new
adminLimitExceeded (11), -- new
unavailableCriticalExtension (12), -- new
confidentialityRequired (13), -- new
saslBindInProgress (14), -- new
noSuchAttribute (16),
undefinedAttributeType (17),
inappropriateMatching (18),
constraintViolation (19),
attributeOrValueExists (20),
invalidAttributeSyntax (21),
-- 22-31 unused --
noSuchObject (32),
aliasProblem (33),
invalidDNSyntax (34),
-- 35 reserved for undefined isLeaf --
aliasDereferencingProblem (36),
-- 37-47 unused --
inappropriateAuthentication (48),
invalidCredentials (49),
insufficientAccessRights (50),
busy (51),
unavailable (52),
unwillingToPerform (53),
loopDetect (54),
-- 55-63 unused --
namingViolation (64),
objectClassViolation (65),
notAllowedOnNonLeaf (66),
notAllowedOnRDN (67),
entryAlreadyExists (68),
objectClassModsProhibited (69),
-- 70 reserved for CLDAP --
affectsMultipleDSAs (71), -- new
-- 72-79 unused --
other (80) },
-- 81-90 reserved for APIs --
matchedDN LDAPDN,
errorMessage LDAPString,
referral [3] Referral OPTIONAL }
Referral ::= SEQUENCE OF LDAPURL
LDAPURL ::= LDAPString -- limited to characters permitted in URLs
Controls ::= SEQUENCE OF 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 and 2 reserved
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 AttributeDescriptionList }
Filter ::= CHOICE {
and [0] SET OF Filter,
or [1] SET OF 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,
-- at least one must be present
substrings SEQUENCE OF CHOICE {
initial [0] LDAPString,
any [1] LDAPString,
final [2] LDAPString } }
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 SEQUENCE {
type AttributeDescription,
vals SET OF AttributeValue }
SearchResultReference ::= [APPLICATION 19] SEQUENCE OF LDAPURL
SearchResultDone ::= [APPLICATION 5] LDAPResult
ModifyRequest ::= [APPLICATION 6] SEQUENCE {
object LDAPDN,
modification SEQUENCE OF SEQUENCE {
operation ENUMERATED {
add (0),
delete (1),
replace (2) },
modification AttributeTypeAndValues } }
AttributeTypeAndValues ::= SEQUENCE {
type AttributeDescription,
vals SET OF AttributeValue }
ModifyResponse ::= [APPLICATION 7] LDAPResult
AddRequest ::= [APPLICATION 8] SEQUENCE {
entry LDAPDN,
attributes AttributeList }
AttributeList ::= SEQUENCE OF SEQUENCE {
type AttributeDescription,
vals SET OF AttributeValue }
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,
response [11] OCTET STRING OPTIONAL }
END
Full Copyright Statement ๐
Copyright (C) The Internet Society (1997). All Rights Reserved. ๐
okay so the Internet Society owns the copyright on this one, and every right is reserved ๐ but they're being super generous about sharing it, bestie ๐ซถ You can copy it and hand it out to people, and you can make derivative works that comment on or explain it or help people actually implement it. You can prepare those, copy them, publish them, and distribute them, either the whole thing or just bits, with no restrictions of any kind ๐ฆ The one catch is that the copyright notice and this paragraph have to stay on every copy and every derivative work ๐
Now the important bit ๐ The document itself may not be modified in any way. That means you can't remove the copyright notice, and you can't remove the references to the Internet Society or other Internet organizations. There are two exceptions. The first is if you need to do it to develop Internet standards, and then the copyright procedures in the Internet Standards process must be followed ๐ The second is if you need to translate it into a language other than English. Nobody's allowed to freestyle edits on the original, periodt ๐
The limited permissions above are perpetual ๐ They will not be revoked by the Internet Society or its successors or assigns, so they're not going anywhere โจ
This document and the information contained herein is provided on an "AS IS" basis and THE INTERNET SOCIETY AND THE INTERNET ENGINEERING TASK FORCE DISCLAIMS ALL WARRANTIES, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO ANY WARRANTY THAT THE USE OF THE INFORMATION HEREIN WILL NOT INFRINGE ANY RIGHTS OR ANY IMPLIED WARRANTIES OF MERCHANTABILITY OR FITNESS FOR A PARTICULAR PURPOSE. ๐
๐ฆ where this page comes from
- ietf: rfc2251 1997-12
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms