LDAP - The Lightweight Directory Access Protocol
Regarding ADSI, the LDAP protocol is very important as ADSI actually is
an interface for the use of LDAP with self developed scripts and applications.
This section of the SelfADSI Tutorial describes the Lightweight Directory
Access Protocol (LDAP).
The following topics are available:
|LDAP History||RFC Standards|
|The Communication Model||The Structure of LDAP Packets|
|LDAP Commands||The Data Model of the Directory|
|Object Classes and Attributes||The RootDSE Object|
|Free and Commercial LDAP Software|
Originally, LDAP was established in conjunction with the OSI Recommendation X.500 for directory services. Most directory services today refer somehow to X.500. The equivalent for X.500 in the world of ISO specifications is called ISO/IEC standard 9594. However, all relevant documents are not available online for free, but can be purchased e.g. at ITU Online Bookshop or at ISO Online Store.
The X.500 standard was defined in its original form between 1984 and 1988 - the Data Model, the Informational Model, the Functional Model, the Namespace Model as well as an Authentication Framework for directory services are described here. In the course of this, an accessing protocol for directory services was specified too: the Directory Access Protocol (DAP). DAP is a quite complex application protocol which fulfills all the requirements of the OSI Model and is, furthermore, based only upon the relevant OSI transport protocols - and not upon TCP/IP.
One of the most important books concerning X.500 is available online: Understanding
X.500 - The Directory by David Chadwick.
Due to the immense complexity of X.500 and DAP, the University of Michigan designed the Lightweight Directory Protocol in 1993 - despite the name, it offers all operations necessary for accessing a directory service. Moreover, it is based upon TCP/IP - this fact was virtually more important for the success of LDAP than its clear protocol structure. In the beginning, LDAP was a mere Front End for X.500 server but has become mainstream as an independent directory system since 1995. LDAP directory servers do not necessarily need to be X.500 servers but utilize all the hierarchies and naming described in the X.500 specification.
In 1995, the LDAP version 2 was adopted in RFC 1777 by the IETF working group ( 'Access Searching and Indexing of Directories ASID'). Among other things, LDAP was based on top of TCP/IP for the first time here.
The current LDAP version 3 was finally set up in RFC 2251 in 1997. In this process, most notably an upgrade of the authentication via LDAP was added (in version 2 there were only anonymous or unencrypted logons). In addition, by establishing UTF-8 and Unicode, the formatting of the data within a directory was modernized.
Concerning LDAP, there are lots of RCF documents that play an important
role (outdated standards are colored in dark gray, main standards are bold):
|RFC 1484: Using the OSI Directory to achieve User Friendly Naming|
|RFC 1485: A String Representation of Distinguished Names|
|RFC 1487: X.500 Lightweight Directory Access Protocol|
|RFC 1488: The X.500 String Representation of Standard Attribute Syntaxes|
|RFC 1588: A String Representation of LDAP Search Filters|
|RFC 1777: Lightweight Directory Access Protocol (replaces 1487) [LDAP v2]|
|RFC 1778: The String Representation of Standard Attribute Syntaxes (replaces 1488) [for LDAP v2]|
|RFC 1779: A String Representation of Distinguished Names (replaces 1485)|
|RFC 1781: Using the OSI Directory to Achieve User Friendly Naming (replaces 1484)|
|RFC 1798: Connection-less Lightweight X.500 Directory Access Protocol|
|RFC 1823: The LDAP Application Program Interface|
|RFC 1959: An LDAP URL Format|
|RFC 1960: A String Representation of LDAP Search Filters (replaces RFC 1588)|
|RFC 2251: Lightweight Directory Access Protocol (v3) [LDAP v2]|
|RFC 2252: Lightweight Directory Access Protocol (v3): Attribute Syntax Definitions|
|RFC 2253: Lightweight Directory Access Protocol (v3): UTF-8 String Representation of Distinguished Names (replaces RFC 1779)|
|RFC 2254: The String Representation of LDAP Search Filters (replaces RFC 1960)|
|RFC 2255: The LDAP URL Format|
|RFC 2256: A Summary of the X.500(96) User Schema for use with LDAPv3|
|RFC 2307: An Approach for Using LDAP as a Network Information Service|
|RFC 2559: Internet X.509 Public Key Infrastructure Operational Protocols - LDAPv2|
|RFC 2696: LDAP Control Extension for Simple Paged Results Manipulation|
|RFC 2820: Access Control Requirements for LDAP|
|RFC 2829: Authentication Methods for LDAP|
|RFC 2830: Lightweight Directory Access Protocol (v3): Extension for Transport Layer Security|
|RFC 2849: The LDAP Data Interchange Format (LDIF) - Technical Specification|
|RFC 3377: Lightweight Directory Access Protocol (v3): Technical Specification (specifies the valid LDAP-RFCs)|
|RFC 3352: Connection-less Lightweight Directory Access Protocol (CLDAP) to Historic Status (replaces RFC 1798)|
|RFC 3494: Lightweight Directory Access Protocol version 2 (LDAPv2) to Historic Status (describes the outdated LDAPv2 RFCs)|
|RFC 3698: Lightweight Directory Access Protocol (LDAP): Additional Matching Rules|
|RFC 3771: The Lightweight Directory Access Protocol (LDAP) Intermediate Response Message (extends RFC 2251)|
|RFC 4370 : Lightweight Directory Access Protocol (LDAP) Proxied Authorization Control|
|RFC 4373 : Lightweight Directory Access Protocol (LDAP) Bulk Update/Replication Protocol (LBURP)|
|RFC 4510 : Lightweight Directory Access Protocol (LDAP): Technical Specification Road Map (specifies the valid LDAP-RFCs)|
|RFC 4511 : Lightweight Directory Access Protocol (LDAP): The Protocol (replaces 2251, 2830, 3771)|
|RFC 4512 : Lightweight Directory Access Protocol (LDAP): Directory Information Models (replaces RFC 2251, 2252, 2556, 3674)|
|RFC 4513 : Lightweight Directory Access Protocol (LDAP): Authentication Methods, Security Mechanisms (replaces RFC 2251, 2829, 2830)|
|RFC 4514 : Lightweight Directory Access Protocol (LDAP): String Representation of Distinguished Names (replaces RFC 2253)|
|RFC 4515 : Lightweight Directory Access Protocol (LDAP): String Representation of Search Filters (replaces RFC 2254)|
|RFC 4516 : Lightweight Directory Access Protocol (LDAP): Uniform Resource Locator (replaces RFC 2255)|
|RFC 4517 : Lightweight Directory Access Protocol (LDAP): Syntaxes and Matching Rules (replaces RFC 2251, 2252, 3698)|
|RFC 4518 : Lightweight Directory Access Protocol (LDAP): Internationalized String Preparation (replaces RFC 2251, 2830, 3771)|
|RFC 4519 : Lightweight Directory Access Protocol (LDAP): Schema for User Applications (replaces RFC 2256, 2247, 2798, 2377)|
|RFC 4520 : Internet Assigned Numbers Authority (IANA) Considerations for the Lightweight Directory Access Protocol (LDAP)|
|RFC 4521 : Considerations for Lightweight Directory Access Protocol (LDAP) Extensions|
|RFC 4522 : Lightweight Directory Access Protocol (LDAP): The Binary Encoding Option|
|RFC 4523 : Lightweight Directory Access Protocol (LDAP): Schema Definitions for X.509 Certificates|
|RFC 4524 : COSINE LDAP/X.500 Schema|
|RFC 4525 : Lightweight Directory Access Protocol (LDAP): Modify-Increment Extension|
|RFC 4526 : Lightweight Directory Access Protocol (LDAP): Absolute True and False Filters|
|RFC 4527 : Lightweight Directory Access Protocol (LDAP): Read Entry Controls|
|RFC 4528 : Lightweight Directory Access Protocol (LDAP): Assertion Control|
|RFC 4529 : Requesting Attributes by Object Class in the Lightweight Directory Access Protocol|
|RFC 4530 : Lightweight Directory Access Protocol (LDAP): entryUUID Operational Attribute|
|RFC 4531 : Lightweight Directory Access Protocol (LDAP): Turn Operation|
|RFC 4532 : Lightweight Directory Access Protocol (LDAP): "Who am I?"|
|RFC 4533 : The Lightweight Directory Access Protocol (LDAP) Content Synchronization Operation|
Within an LDAP communication, a client establishes a TCP connection to
a directory server. According to X.500 habits, the server is also called DSA
(Directory Service Agent). Meanwhile, there are implementations
of a connectionless LDAP protocol available where queries are sent directly
In doing so, TCP/UDP Port 389 is normally used, whereas Port 636 comes into operation if connecting via SSL/TLS (Secure Socket Layer/Transport Level Security).
The server can refer a client to another server. This referral was established in LDAP version 3 and allows load balancing in larger directory systems being provided by different server.
Servers are able to synchronize their directories among each other. However, there are no specific LDAP requests designed for this task - but the servers can use the standard LDAP protocol commands or synchronize their databases by the use of other mechanisms.
During the communication, the client transmits one or more requests to the server which gives the equivalent response. This communication need not to be strictly synchronous, i.e. the client can send several requests before the server responds the first one and it also hasn't to consider the order of the incoming requests for its responds. A single client's request can also be responded with several messages from the server.
An LDAP request (or LDAP frame) is structured as follows:
The content of an LDAP message is encoded like in the LDAP RFCs in ASN.1 (Abstract Syntax Notation) (shown in a shortened notation here). The actual, precise data representation within the network packets is implemented with BER (Basic Encoding Rules). This might be a bit confusing at the beginning, however, the most important parts of the data (e.g. object and attribute names) are shown in ASCII so that they can be identified directly in the hex code of a packet sniffer.
The detailed technical structure can be gathered from the standard specification in RFC 2251. The individual commands are further explained later in this SelfADSI section. Anyhow, I'd like to check out one example for a detailed analysis of an LDAP message on the basis of an LDAP search. Please have a look onto the packet record of an LDAP session.
The decoding states that the examined packet would be an LDAP search for user objects in the entire naming context "dc=karakorum,dc=net". Returned shall be the attribute displayName.
Let's focus on the hexadecimal section of the LDAP message one more time (highlighted dark above) - and together with the ASN.1 definition of an LDAP search operation. In order to understand the exact codification, you will necessarily need to know about the specifications of Basic Encoding Rules (BER). Move your mouse over the values for further explanations:
From a technical point of view, the different LDAP commands could rather
be regarded as protocol operations. One of these operations was studied
in detail in the last paragraph. An in-depth examination of all LDAP command
aspects can be found in
| Bind Request:......................||Logon of a client to an LDAP server. Different procedures
for SASL authentication (Simple Authentication and Security Layer)
are supported. Even a clear text authentication is possible - or an
anonymous bind operation, where no logon data is passed. How an ADSI
scripting implements a bind operation can be read in the section 'Connecting
with the directory and objects' here in the SelfADSI tutorial.
In ADSI scripts, a BindRequest is always triggered when functions like GetObject or OpenDSObject are used or an ADO search is performed in the directory.
| Bind Response:...................|| LDAP server reply to a BindRequest.
| UnBind Request:.................||By using this command, the client ends the LDAP protocol session
which will NOT be responded by the server, but all requests still due
become disallowed at once and the connection is ended. ADSI scripts
don't need to process this operation explicitly - after completing
a script the LDAP connection is automatically discarded by a time-out
of the server.
| Search Request:.................||This command searches for one or more objects within the directory
where several attributes are given back which the client can pass in
the search request.
An LDAP filter is passed with the request as a search criteria. The client can also define the directory container the search shall begin with: The so-called BaseDN. Moreover, via a scope parameter it can be determined if the search shall also expand to existing sub containers.
In ADSI scripts, this operation is e.g. used for ADO searches as well as in GetInfo and GetInfoEx calls. Again, an LDAP bind is used internally but this time, the object itself is stated as BaseDN and 'baseObject' as the scope value, i.e. the 'search' only refers to the corresponding object.
Concerning searches in ADSI scripts please read the comments of the following paragraph 'searching for objects in the directory' here in the SelfADSI-Tutorials.
| Search ResultEntry:............||With this protocol operation the server gives back a matching entry
for a SearchRequest. There can be several of those packages in one
response frame in case that more than one object of a single search
shall be given back as a match. However, the return of the matches
can occur via several independent network frames.
| Search ResultDone:............||For completing a SearchRequest, the LDAP server returns a SearchResultDone.
This reply is given back immediately if a search was unsuccessful or
| Modify Request:..................||This command allows access to attributes of an object. The use of
ADD, REPLACE and DELETE operations are possible, however these possibilities
do not refer to the entire object but only to the attributes inside
In ADSI scripts a ModifyRequest is used if the Put or PutEx methods utilized.
| Modify Response:...............||LDAP server reply to a ModifyRequest.
| Add Request:......................||A directory object can be created with this call. In ADSI scripts
an AddRequest is used if the Create method
called in container objects.
| Add Response:....................||LDAP server reply to an AddRequest.
| Del Request:.....................||A directory object can be deleted here. An AddRequest is used in
ADSI by calling the function Delete for
| Del Response:..................||LDAP server reply to a DelRequest.
| ModifyDN Request:..........||This command can rename an object - the Relative Distinguished Name
of the object then is changed in the directory. The remaining pathname
of the object can be changed, too: through this, the object is moved
to another container.
This LDAP operation is used in ADSI scripts by using the method MoveHere. By the way, MoveHere is the only way of renaming an object in ADSI.
| ModifyDN Response:........|| LDAP server reply to a ModifyDNRequest.
| Compare Request:............|| At the server, clients can check if attributes of objects possess
certain values. This LDAP operation isn't used directly in ADSI.
| Compare Response:.........|| LDAP server reply to a CompareRequest.
| Abandon Request:............|| With this command a running LDAP request can be stopped by the client.
This is mainly important for complex and extensive search requests
possibly drawing high server performance but whose results are no longer
needed by the client.
| SearchResult Reference:||A special reply of an LDAP server to a client's request. The results
are not given back by the server directly but the server refers to
other LDAP servers containing relevant directory objects or sections
and at which the client can carry on the search.
| Extended Request:...........||This kind of request was specified in the LDAP standard for providing
diverse implementations with the possibility to add some more operations,
e.g. signed LDAP requests. The several sub types of the ExtendedRequests
are defined by so-called OBJECT IDENTIFIER OIDs. These definitions
are subject to one's sole discretion.
| Extended Response:........|| LDAP server reply to an ExtendedRequest.
| Intermediate Response:..||This type of LDAP reply has been specified in RFC
3771 after the actual LDAPv3 definition. The server can give
back 'provisional replies' to a client. Especially relevant for client's
requests that have to be completed by the server in several steps,
e.g. deleting whole sub structures in the directory or designing
and synchronizing new replicas onto other servers.
Even if there are no such requests in the common standard, it is possible to implement these kinds of extensions with the LDAP operation ExtendedRequest. The possibility can be used more flexible by using IntermediateResponse.
LDAP servers save objects' data in a hierarchical tree structure, the so-called Directory Information Tree (DIT). The notation 'Naming Context' is in use, too. The LDAP server itself is often called DSA (Directory Services Agent) and can contain several DIT tree structures / naming contexts.
An LDAP hierarchy consists of objects containing 0 to n subordinate child objects. However, each child object possesses exactly one parent object, it can't be contained in several containers. An exception is the Root object at the top of the Naming Context hierarchy - it doesn't possess an superior object. Customary examples for normal container objects are Organizational Units (OUs).
Each object has a name that needs to be unique within its container - this is the Relative Distinguished Name (RDN). If you concatenate now the RDNs of the object and all its superior parent container objects, then you get an unambiguous identifier of the object within the LDAP hierarchy - this is the complete Distinguished Name (DN) of the object. An example:
You get detailed explanations concerning the design of LDAP pathnames in the equivalent section of the SelfADSI tutorial.
Objects within an LDAP hierarchy are divided into classes. Each class is defined by a name and a certain amount of attributes. Some of the attributes are mandatory in all objects of a specific class ('MUST' attributes). Other attributes are optional - they either can be written with no value or can be missing in these objects at all ('MAY' attributes).
The definition of the classes and their attributes is stored in the service directory system itself. Again, the classes are organized in a hierarchical manner: classes can originate from other classes - objects then inherit all the attributes of their hierarchical superior classes, additional to the properties of their own class (the so-called structural object class). The directory service system often has an abstract object class named 'top' all other classes originate from.
RootDSE is a set of information by which general attributes of an LDAP server can be retrieved. You could say that RootDSE is a specific server entry being available at the root of the directory tree (DIT - Directory Information Tree) without being part of the name context itself.
In a technical sense, RootDSE is an object that can be retrieved directly from a server without further specification of an LDAP path:
rootDSE = GetObject("LDAP://server/rootDSE")
Via an LDAP query (e.g. ADO) the RootDSE object can be retrieved by using an empty base DN ("") and the following LDAP query filter: "(objectClass=*)".
This request should also be possible as anonymous LDAP user on every LDAP server if it supports LDAP v3. Correspondingly, RootDSE is specified as standard attribute of an LDAP server in RFC 4512 - LDAP: Directory Information Models. Alltogether, seven main attributes are mentioned for the RootDSE object in the LDAP standard, that should at least be given back by an LDAP server:
Moreover, the different LDAP servers give back some additional attributes.
Please inform yourself in the links of the accordant provider web sites:
Since LDAP has become common standard for directory systems and accesses, the range of software for LDAP clients and LDAP servers has increased. The following types of servers can be differentiated:
- Pure LDAP directory servers (e.g. OpenLDAP, Sun iPlanet, Siemens DirX)
- X.500 servers, offering an LDAP interface (e.g. Isode M-Vault X.500)
- Diverse application servers, providing an LDAP interface (e.g. Microsoft Active Directory , Novell eDirectory, IBM Lotus Domino)
- Database server, providing an LDAP interface (e.g. Oracle Internet Directory)