RFC 1777
Lightweight Directory Access Protocol
RFC 1777 โจ Lightweight Directory Access Protocol ๐
Part 1 of 5 ๐
okay bestie, this is the RFC that gave us LDAP ๐ฆ It was written by W. Yeong (Performance Systems International), T. Howes (University of Michigan), and S. Kille (ISODE Consortium), in March 1995. It's a Standards Track document, and it obsoletes RFC 1487 ๐ It doesn't update anything.
Status of This Memo ๐
this one is an Internet standards track protocol for the Internet community, and it's asking for discussion and suggestions for improvements ๐ซถ If you want to know where it stands in standardization, go check the current edition of the "Internet Official Protocol Standards" (STD 1). Distribution of this memo is unlimited, so share it all you want ๐ธ
Abstract ๐ฆ
so LDAP is designed to give you access to the X.500 Directory without eating all the resources that the Directory Access Protocol (DAP) needs ๐ It's aimed at simple management apps and browser apps that just want simple read/write interactive access to the X.500 Directory. It's meant to complement DAP, not replace it, ngl ๐
Key aspects of LDAP are:
- Protocol elements are carried directly over TCP or other transport, skipping much of the session/presentation overhead โจ
- Lots of protocol data elements are encoded as ordinary strings (e.g., Distinguished Names) ๐ง
- A lightweight BER encoding is used to encode all protocol elements ๐
1. History ๐
the tremendous interest in X.500 [1,2] technology on the Internet led to efforts to lower the high "cost of entry" that comes with using it ๐ญ Examples are the Directory Assistance Service [3] and DIXIE [4]. Those efforts were a success, but they were built on particular implementations, so they didn't apply as widely. This document keeps going with defining Directory protocol alternatives, but it's different because it deliberately avoids depending on any particular implementation ๐
2. Protocol Model ๐
the general model here is clients performing protocol operations against servers. A client sends a protocol request describing the operation it wants to a server, and the server handles the necessary operations on the Directory. Once those are done, the server sends back a response with any results or errors to the requesting client ๐ The goal is to make life easier by keeping clients as simple as possible, so that loads of apps can use the Directory ๐ฅ
ngl this next bit is important: servers are required to return responses whenever the protocol defines a response, but there's no requirement for synchronous behavior on the client or server side. Requests and responses for multiple operations can be exchanged in any order between clients and servers, as long as clients eventually get a response for every request that needs one ๐ซถ
Because servers do the operations on behalf of clients, protocol servers are expected to handle referrals themselves instead of passing them back to the client ๐ฆ This protocol has no provisions for returning referrals to clients. The model is that servers make sure all the necessary operations happen in the Directory, and only final results or errors go back to the clients ๐
Also, this protocol can be mapped to a strict subset of the directory abstract service, so it can be cleanly provided by the DAP โจ
3. Mapping Onto Transport Services ๐ง
this protocol is designed to run over connection-oriented, reliable transports, where all 8 bits in an octet are significant in the data stream ๐ธ Two underlying services are specified here, though others are possible too ๐
3.1. Transmission Control Protocol (TCP) ๐
the LDAPMessage PDUs are mapped directly onto the TCP bytestream ๐ฆ Server implementations running over TCP should provide a protocol listener on port 389 ๐
3.2. Connection Oriented Transport Service (COTS) ๐ธ
the connection gets established. No special use of T-Connect is made. Each LDAPMessage PDU is mapped directly onto T-Data ๐
4. Elements of Protocol โจ
Okay so every protocol operation gets wrapped up in the same envelope, called the LDAPMessage ๐ It looks like this:
LDAPMessage ::=
SEQUENCE {
messageID MessageID,
protocolOp CHOICE {
bindRequest BindRequest,
bindResponse BindResponse,
unbindRequest UnbindRequest,
searchRequest SearchRequest,
searchResponse SearchResponse,
modifyRequest ModifyRequest,
modifyResponse ModifyResponse,
addRequest AddRequest,
addResponse AddResponse,
delRequest DelRequest,
delResponse DelResponse,
modifyRDNRequest ModifyRDNRequest,
modifyRDNResponse ModifyRDNResponse,
compareDNRequest CompareRequest,
compareDNResponse CompareResponse,
abandonRequest AbandonRequest
}
}
MessageID ::= INTEGER (0 .. maxInt)
The LDAPMessage is the envelope that holds the common fields every exchange needs ๐ Right now the only common field is the message ID, and it has to be different from the ID of every other request that's still outstanding in the same LDAP session it belongs to ๐ง
The message ID must be echoed in every LDAPMessage envelope that carries a response to the request. That means the response has to reuse the ID from the original request's LDAPMessage ๐
Besides the LDAPMessage, a few more definitions get used when describing protocol operations:
LDAPString ::= OCTET STRING
LDAPString is a notational convenience ๐ซถ Strings of this type are encoded as OCTET STRING, but the legal characters in them are limited to the IA5 character set.
LDAPDN ::= LDAPString
RelativeLDAPDN ::= LDAPString
An LDAPDN and a RelativeLDAPDN are the encoded forms of a Distinguished Name and a Relative Distinguished Name. The encoding follows the specification in [5], so that:
<distinguished-name> ::= <name>
<relative-distinguished-name> ::= <name-component>
Here, <name> and <name-component> are as defined in [5] ๐
AttributeValueAssertion ::=
SEQUENCE {
attributeType AttributeType,
attributeValue AttributeValue
}
This AttributeValueAssertion type is pretty similar to the one in the X.500 Directory standards ๐
AttributeType ::= LDAPString
AttributeValue ::= OCTET STRING
An AttributeType takes as its value the textual string that goes with that AttributeType in the X.500 Directory standards ๐ฆ For example, the AttributeType 'organizationName', which has object identifier 2.5.4.10, shows up in this protocol as the string "organizationName". If an implementation runs into an Attribute Type it can't match to a textual string, it may substitute an ASCII string encoding of the object identifier for that type. So organizationName could be written as "2.5.4.10" if the implementation can't work out the string "organizationName" for it ๐
A field of type AttributeValue holds an octet string that encodes a Directory AttributeValue type. The string encodings for the different Directory AttributeValue types can be found in companion documents that define the encodings of various attribute syntaxes, such as [6] ๐
LDAPResult ::=
SEQUENCE {
resultCode ENUMERATED {
success (0),
operationsError (1),
protocolError (2),
timeLimitExceeded (3),
sizeLimitExceeded (4),
compareFalse (5),
compareTrue (6),
authMethodNotSupported (7),
strongAuthRequired (8),
noSuchAttribute (16),
undefinedAttributeType (17),
inappropriateMatching (18),
constraintViolation (19),
attributeOrValueExists (20),
invalidAttributeSyntax (21),
noSuchObject (32),
aliasProblem (33),
invalidDNSyntax (34),
isLeaf (35),
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),
other (80)
},
matchedDN LDAPDN,
errorMessage LDAPString
}
LDAPResult is the construct this protocol uses to send success or failure signals from servers back to clients ๐ฅ When servers answer various requests, their responses include LDAPResult fields that show the final status of the operation. The errorMessage field is optional fun ๐ At the server's option, it can hold an ASCII string with a human-readable error explanation. That diagnostic isn't standardised, so implementations should not rely on the values returned. If the server doesn't want to send a text diagnostic, the errorMessage field should contain a zero length string.
For resultCodes of noSuchObject, aliasProblem, invalidDNSyntax, isLeaf, and aliasDereferencingProblem, the matchedDN field gets set to the name of the lowest entry (object or alias) in the DIT that matched. It's a truncated form of the name that was provided, or, if an alias was dereferenced, of the resulting name ๐ In every other case, the matchedDN field should be set to NULL DN (a zero length string) ๐ธ
4.1. Bind Operation
The Bind Operation starts a protocol session between a client and a server, and lets the server authenticate the client ๐ It must be the first operation request a server receives from a client in a session. The Bind Request is defined like this:
BindRequest ::=
[APPLICATION 0] SEQUENCE {
version INTEGER (1 .. 127),
name LDAPDN,
authentication CHOICE {
simple [0] OCTET STRING,
krbv42LDAP [1] OCTET STRING,
krbv42DSA [2] OCTET STRING
}
}
Here's what the Bind Request parameters are ๐
- version: This is the version number of the protocol that the session will use. This document describes version 2 of the LDAP protocol. There's no version negotiation, so the client should just set this parameter to whichever version it wants ๐
- name: This is the name of the Directory object the client wants to bind as. It can be a null value (a zero length string) for anonymous binds ๐ฆ
- authentication: This is the information used to authenticate the name, if one was given in the Bind Request. The "simple" option is pretty basic: the field holds just a cleartext password. This option should also be used for unauthenticated or anonymous binds, and in those cases the field contains a zero length string ๐ Kerberos version 4 [7] authentication to the LDAP server and the DSA works through the "krbv42LDAP" and "krbv42DSA" options, respectively. The two entities are treated as separate here, but nothing says they have to be different things, so a DSA could speak LDAP directly ๐ง Two separate options exist so that all implementations are supported. Each octet string should contain the kerberos ticket for the right service (for example, the kind returned by krb_mk_req()) โจ The suggested service name for authenticating to the LDAP server is "ldapserver", and the suggested service name for authenticating to the DSA is "x500dsa". In both cases, the suggested instance name is the name of the host the service runs on. The actual service names and instances depend on what's in the local kerberos principle database, so they might look different ๐
The Bind Operation needs a response, the Bind Response, which is defined as:
BindResponse ::= [APPLICATION 1] LDAPResult
A Bind Response is basically the server telling the client how its request to start a session went ๐
When a protocol server gets a Bind Request, it authenticates the requesting client if that's necessary, then tries to set up a protocol session with that client โจ After that, the server sends a Bind Response back to the client that says whether the session setup worked ๐
4.2. Unbind Operation
The Unbind Operation ends a protocol session ๐ It's defined like this:
UnbindRequest ::= [APPLICATION 2] NULL
The Unbind Operation has no defined response ๐ซถ Once a protocol client sends an UnbindRequest, it can assume the session is over. When a protocol server receives an UnbindRequest, it can assume the client has ended the session, and that any outstanding requests can be thrown out ๐
4.3. Search Operation ๐
Okay so the Search Operation is how a client asks a server to go digging through the Directory on its behalf ๐ต๏ธโโ๏ธโจ Here's what a Search Request looks like:
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),
attrsOnly BOOLEAN,
filter Filter,
attributes SEQUENCE OF AttributeType
}
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] AttributeType,
approxMatch [8] AttributeValueAssertion
}
SubstringFilter
SEQUENCE {
type AttributeType,
SEQUENCE OF CHOICE {
initial [0] LDAPString,
any [1] LDAPString,
final [2] LDAPString
}
}
Here are the parameters of the Search Request, bestie ๐
- baseObject: An LDAPDN that is the base object entry relative to which the search is to be performed. ๐ธ
- scope: An indicator of the scope of the search to be performed. The semantics of the possible values of this field are identical to the semantics of the scope field in the Directory Search Operation. ๐ฆ
- derefAliases: An indicator as to how alias objects should be handled in searching. The semantics of the possible values of this field are, in order of increasing value:
- neverDerefAliases: do not dereference aliases in searching or in locating the base object of the search;
- derefInSearching: dereference aliases in subordinates of the base object in searching, but not in locating the base object of the search;
- derefFindingBaseObject: dereference aliases in locating the base object of the search, but not when searching subordinates of the base object;
- derefAlways: dereference aliases both in searching and in locating the base object of the search. ๐ฅ
- sizelimit: A sizelimit that restricts the maximum number of entries to be returned as a result of the search. A value of 0 in this field indicates that no sizelimit restrictions are in effect for the search. ๐ง
- timelimit: A timelimit that restricts the maximum time (in seconds) allowed for a search. A value of 0 in this field indicates that no timelimit restrictions are in effect for the search. โฐ
- attrsOnly: An indicator as to whether search results should contain both attribute types and values, or just attribute types. Setting this field to TRUE causes only attribute types (no values) to be returned. Setting this field to FALSE causes both attribute types and values to be returned. ๐
- filter: A filter that defines the conditions that must be fulfilled in order for the search to match a given entry. ๐
- attributes: A list of the attributes from each entry found as a result of the search to be returned. An empty list signifies that all attributes from each entry found in the search are to be returned. โจ
The results of the search the server attempts after getting a Search Request come back in Search Responses, which look like this ๐ง
Search Response ::=
CHOICE {
entry [APPLICATION 4] SEQUENCE {
objectName LDAPDN,
attributes SEQUENCE OF SEQUENCE {
AttributeType,
SET OF AttributeValue
}
},
resultCode [APPLICATION 5] LDAPResult
}
Once a server gets a Search Request, it will perform the necessary search of the DIT. Then it sends back a whole sequence of responses made up of:
- Zero or more Search Responses, each consisting of an entry found during the search; with the response sequence terminated by
- A single Search Response containing an indication of success, or detailing any errors that have occurred.
Each entry that comes back will contain all attributes, complete with associated values if necessary, as specified in the 'attributes' field of the Search Request. Iconic โจ
Also, a fun little fact ๐ An X.500 "list" operation can be emulated by a one-level LDAP search operation with a filter checking for the existence of the objectClass attribute, and an X.500 "read" operation can be emulated by a base object LDAP search operation with the same filter. Main character energy for LDAP, no cap ๐
4.4. Modify Operation โ๏ธ
The Modify Operation lets a client ask a server to make a modification to the DIB on its behalf ๐ซถ Here's the Modify Request:
ModifyRequest ::=
[APPLICATION 6] SEQUENCE {
object LDAPDN,
modification SEQUENCE OF SEQUENCE {
operation ENUMERATED {
add (0),
delete (1),
replace (2)
},
modification SEQUENCE {
type AttributeType,
values SET OF
AttributeValue
}
}
}
Parameters of the Modify Request are:
- object: The object to be modified. The value of this field should name the object to be modified after all aliases have been dereferenced. The server will not perform any alias dereferencing in determining the object to be modified. ๐ฏ
- A list of modifications to be performed on the entry to be modified. The entire list of entry modifications should 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 may be taken on by the 'operation' field in each modification construct have the following 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 existing values of the given attribute with the new values listed, creating the attribute if necessary. ๐
The result of the modify the server attempts after getting a Modify Request comes back in a Modify Response, which looks like this:
ModifyResponse ::= [APPLICATION 7] LDAPResult
When a server gets a Modify Request, it will perform the necessary modifications to the DIB. Then it sends back a single Modify Response that either says the DIB modification finished successfully, or gives the reason the modification failed ๐
Here's the big deal ๐ฅ Because the list of modifications in the Modify Request has to be applied atomically, if the Modify Response shows any sort of error, the client can expect that no modifications to the DIB were performed. And if the Modify Response shows successful completion of the Modify Operation, the client can expect that all requested modifications were performed. All or nothing, periodt ๐
4.5. Add Operation โ
The Add Operation lets a client request that an entry be added to the Directory ๐ The Add Request looks like this:
AddRequest ::=
[APPLICATION 8] SEQUENCE {
entry LDAPDN,
attrs SEQUENCE OF SEQUENCE {
type AttributeType,
values SET OF AttributeValue
}
}
Parameters of the Add Request are:
- entry: the Distinguished Name of the entry to be added. Note that all components of the name except for the last RDN component must exist for the add to succeed. ๐ง
- attrs: the list of attributes that make up the content of the entry being added. ๐ธ
The result of the add the server attempts after getting an Add Request comes back in the Add Response, which looks like this:
AddResponse ::= [APPLICATION 9] LDAPResult
When a server gets an Add Request, it will attempt to perform the requested add. The result of that attempt gets sent back to the client in the Add Response ๐ฆ
4.6. Delete Operation ๐๏ธ
The Delete Operation lets a client request that an entry be removed from the Directory ๐ The Delete Request looks like this:
DelRequest ::= [APPLICATION 10] LDAPDN
The Delete Request is just the Distinguished Name of the entry to be deleted ๐ The result of the delete the server attempts after getting a Delete Request comes back in the Delete Response, which looks like this:
DelResponse ::= [APPLICATION 11] LDAPResult
When a server gets a Delete Request, it will attempt to perform the requested entry removal. The result of that delete attempt gets sent back to the client in the Delete Response. Note that only leaf objects may be deleted with this operation. ๐
4.7. Modify RDN Operation โจ
okay so the Modify RDN Operation is how a client renames an entry ๐ฆ it only changes the last bit of the name, so think of it like changing someone's nickname but not their whole family tree ๐ the request looks like this:
ModifyRDNRequest ::=
[APPLICATION 12] SEQUENCE {
entry LDAPDN,
newrdn RelativeLDAPDN,
deleteoldrdn BOOLEAN
}
there are three params you need to know about ๐
- entry: the name of the entry you want to change ๐
- newrdn: the RDN that's gonna be the new last component of the name โจ
- deleteoldrdn: a boolean that decides whether the old RDN attribute values stay on the entry as attributes, or get deleted from it ๐
the server's answer to your rename attempt comes back in the Modify RDN Response, which looks like this:
ModifyRDNResponse ::= [APPLICATION 13] LDAPResult
the server tries the rename as soon as it gets your request ๐ซถ and whatever happens comes back to you in that response. and the old RDN attributes are either deleted or kept, depending on what you set deleteoldrdn to ๐ธ no drama, just a clean rename ๐ญ
4.8. Compare Operation ๐ง
the Compare Operation is giving "is this a match??" energy ๐ a client uses it to check an assertion against an entry in the Directory. the request is:
CompareRequest ::=
[APPLICATION 14] SEQUENCE {
entry LDAPDN,
ava AttributeValueAssertion
}
two params here:
- entry: the name of the entry you're comparing against ๐
- ava: the assertion you want to check the entry against ๐
when the server gets a Compare Request, it runs the comparison and sends the result back in the Compare Response:
CompareResponse ::= [APPLICATION 15] LDAPResult
the server tries the comparison as soon as the request lands, and the outcome comes back in that response ๐ fun fact (well, fun for nerds ๐ค): errors and the comparison result both come back in the same construct. one response, two jobs, very efficient, very iconic โจ
6.9. Abandon Operation ๐ โโ๏ธ
the Abandon Operation lets a client ask the server to stop working on an operation that's still going ๐ the Abandon Request is:
AbandonRequest ::= [APPLICATION 16] MessageID
there's no response defined for the Abandon Operation. after a client sends one, it can expect that the operation identified by the Message ID in the Abandon Request has been abandoned ๐
super important bit: if a server gets an Abandon Request for a Search Operation while it's still sending results for that search, the server should stop sending responses for that search right away ๐ฅ no more results, the vibe is OVER ๐ซ
5. Protocol Element Encodings ๐
LDAP protocol elements get encoded for exchange using the Basic Encoding Rules (BER) [12] of ASN.1 [11] ๐ฆ but BER can get kinda heavy on overhead, so there are some extra rules for BER-encodings of LDAP protocol elements ๐ these are the restrictions:
- Only the definite form of length encoding will be used. ๐ธ
- Bitstrings and octet strings and all character string types will be encoded in the primitive form only. โจ
6. Security Considerations ๐
okay bestie, real talk ๐ญ this version of the protocol only gives you two authentication options: simple authentication using a cleartext password, and kerberos version 4 authentication. the cleartext password part is a big deal, so please be careful with it ๐
future versions of LDAP will likely add support for other authentication methods ๐ฎ keep an eye out ๐
7. Bibliography ๐
[1] The Directory: Overview of Concepts, Models and Service. CCITT Recommendation X.500, 1988.
[2] Information Processing Systems -- Open Systems Interconnection -- The Directory: Overview of Concepts, Models and Service. ISO/IEC JTC 1/SC21; International Standard 9594-1, 1988
[3] Rose, M., "Directory Assistance Service", RFC 1202, Performance Systems International, Inc., February 1991.
[4] Howes, T., Smith, M., and B. Beecher, "DIXIE Protocol Specification, RFC 1249, University of Michigan, August 1991.
[5] Kille, S., "A String Representation of Distinguished Names", RFC 1779, ISODE Consortium, March 1995.
[6] Howes, T., Kille, S., Yeong, W., and C. Robbins, "Lightweight Directory Access Protocol", RFC 1488, University of Michigan, ISODE Consortium, Performance Systems International, NeXor Ltd., July 1993.
[7] Kerberos Authentication and Authorization System. S.P. Miller, B.C. Neuman, J.I. Schiller, J.H. Saltzer; MIT Project Athena Documentation Section E.2.1, December 1987.
[8] The Directory: Models. CCITT Recommendation X.501 ISO/IEC JTC 1/SC21; International Standard 9594-2, 1988.
[10] The Directory: Abstract Service Definition. CCITT Recommendation X.511, ISO/IEC JTC 1/SC21; International Standard 9594-3, 1988.
[11] Specification of Abstract Syntax Notation One (ASN.1). CCITT Recommendation X.208, 1988.
[12] Specification of Basic Encoding Rules for Abstract Syntax Notation One (ASN.1). CCITT Recommendation X.209, 1988.
10. Authors' Addresses ๐ฆ
Wengyik Yeong
PSI Inc.
510 Huntmar Park Drive
Herndon, VA 22070
USA
Phone: +1 703-450-8001
EMail: yeongw@psilink.com
Tim Howes
University of Michigan
ITD Research Systems
535 W William St.
Ann Arbor, MI 48103-4943
USA
Phone: +1 313 747-4454
EMail: tim@umich.edu
Steve Kille
ISODE Consortium
PO Box 505
London
SW11 1DX
UK
Phone: +44-71-223-4062
EMail: S.Kille@isode.com
Appendix A - Complete ASN.1 Definition ๐งโโ๏ธ
Lightweight-Directory-Access-Protocol DEFINITIONS IMPLICIT TAGS ::=
BEGIN
LDAPMessage ::=
SEQUENCE {
messageID MessageID,
-- unique id in request,
-- to be echoed in response(s)
protocolOp CHOICE {
searchRequest SearchRequest,
searchResponse SearchResponse,
modifyRequest ModifyRequest,
modifyResponse ModifyResponse,
addRequest AddRequest,
addResponse AddResponse,
delRequest DelRequest,
delResponse DelResponse,
modifyDNRequest ModifyDNRequest,
modifyDNResponse ModifyDNResponse,
compareDNRequest CompareRequest,
compareDNResponse CompareResponse,
bindRequest BindRequest,
bindResponse BindResponse,
abandonRequest AbandonRequest,
unbindRequest UnbindRequest
}
}
BindRequest ::=
[APPLICATION 0] SEQUENCE {
version INTEGER (1 .. 127),
-- current version is 2
name LDAPDN,
-- null name implies an anonymous bind
authentication CHOICE {
simple [0] OCTET STRING,
-- a zero length octet string
-- implies an unauthenticated
-- bind.
krbv42LDAP [1] OCTET STRING,
krbv42DSA [2] OCTET STRING
-- values as returned by
-- krb_mk_req()
-- Other values in later versions
-- of this protocol.
}
}
BindResponse ::= [APPLICATION 1] LDAPResult
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),
alwaysDerefAliases (3)
},
sizeLimit INTEGER (0 .. maxInt),
-- value of 0 implies no sizelimit
timeLimit INTEGER (0 .. maxInt),
-- value of 0 implies no timelimit
attrsOnly BOOLEAN,
-- TRUE, if only attributes (without values)
-- to be returned.
filter Filter,
attributes SEQUENCE OF AttributeType
}
SearchResponse ::=
CHOICE {
entry [APPLICATION 4] SEQUENCE {
objectName LDAPDN,
attributes SEQUENCE OF SEQUENCE {
AttributeType,
SET OF
AttributeValue
}
},
resultCode [APPLICATION 5] LDAPResult
}
ModifyRequest ::=
[APPLICATION 6] SEQUENCE {
object LDAPDN,
modifications SEQUENCE OF SEQUENCE {
operation ENUMERATED {
add (0),
delete (1),
replace (2)
},
modification SEQUENCE {
type AttributeType,
values SET OF
AttributeValue
}
}
}
ModifyResponse ::= [APPLICATION 7] LDAPResult
AddRequest ::=
[APPLICATION 8] SEQUENCE {
entry LDAPDN,
attrs SEQUENCE OF SEQUENCE {
type AttributeType,
values SET OF AttributeValue
}
}
AddResponse ::= [APPLICATION 9] LDAPResult
DelRequest ::= [APPLICATION 10] LDAPDN
DelResponse ::= [APPLICATION 11] LDAPResult
ModifyRDNRequest ::=
[APPLICATION 12] SEQUENCE {
entry LDAPDN,
newrdn RelativeLDAPDN -- old RDN always deleted
}
ModifyRDNResponse ::= [APPLICATION 13] LDAPResult
CompareRequest ::=
[APPLICATION 14] SEQUENCE {
entry LDAPDN,
ava AttributeValueAssertion
}
CompareResponse ::= [APPLICATION 15] LDAPResult
AbandonRequest ::= [APPLICATION 16] MessageID
MessageID ::= INTEGER (0 .. maxInt)
LDAPDN ::= LDAPString
RelativeLDAPDN ::= LDAPString
okay bestie, the filter grammar is up next and it is SO good ๐โจ
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] AttributeType,
approxMatch [8] AttributeValueAssertion
}
LDAPResult ::=
SEQUENCE {
resultCode ENUMERATED {
success (0),
operationsError (1),
protocolError (2),
timeLimitExceeded (3),
sizeLimitExceeded (4),
compareFalse (5),
compareTrue (6),
authMethodNotSupported (7),
strongAuthRequired (8),
noSuchAttribute (16),
undefinedAttributeType (17),
inappropriateMatching (18),
constraintViolation (19),
attributeOrValueExists (20),
invalidAttributeSyntax (21),
noSuchObject (32),
aliasProblem (33),
invalidDNSyntax (34),
isLeaf (35),
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),
other (80)
},
matchedDN LDAPDN,
errorMessage LDAPString
}
ngl the result codes list is giving main character energy ๐ every single error has its own little number, no vibes-based guessing ๐
AttributeType ::= LDAPString
-- text name of the attribute, or dotted
-- OID representation
AttributeValue ::= OCTET STRING
AttributeValueAssertion ::=
SEQUENCE {
attributeType AttributeType,
attributeValue AttributeValue
}
SubstringFilter ::=
SEQUENCE {
type AttributeType,
SEQUENCE OF CHOICE {
initial [0] LDAPString,
any [1] LDAPString,
final [2] LDAPString
}
}
LDAPString ::= OCTET STRING
maxInt INTEGER ::= 65535
END
๐ฆ and that's the whole grammar, periodt ๐ ๐ธ
๐ฆ where this page comes from
- ietf: rfc1777 1995-03
- ๐ girlified by claude-haiku-5-5 on : a language model's rewrite of the original, under its terms