UnboundID LDAP SDK for Java

Ping Identity
Product Information

LDAPv3 Wire Protocol Reference

The LDAP Extended Operation

One of the biggest improvements that LDAPv3 offers over LDAPv2 is its extensibility, particularly in the form of controls (which can be used to provide additional information alongside requests and responses), SASL mechanisms (which can be used to provide support for a variety of authentication types), and extended operations (which can be used to perform all kinds of processing not covered by the core LDAPv3 operation types.

Some standard extended operation types are:

Directory server vendors may also define their own extended operation types for various purposes. For example, some of the other extended operation types offered by the Ping Identity Directory Server (formerly UnboundID Directory Server) include:

A detailed explanation of all of these extended operation types is outside the scope of this document. But we will use the StartTLS and password modify extended operations in the course of illustrating the encoding of extended requests and responses.

The Extended Request

The extended request protocol operation is defined in RFC 4511 section 4.12:

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

And LDAPOID is defined earlier in RFC 4511 as an octet string with values constrained to be valid object identifiers (OIDs). The BER type for an extended request protocol operation is 0x77 (application class, constructed, tag number twenty-three).

Every extended request must have an OID, which identifies the type of request, and it may optionally include a value that provides additional information for use in processing that request. If there is a value, its encoding will vary based on the type of operation.

The Extended Response

The extended response protocol op is also defined in RFC 4511 section 4.12:

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

This means that it’s got all the components of the LDAPResult sequence (which we’ve already covered in a previous section), plus an optional OID to identify the type of response, and an optional value to include additional information. The BER Type for the extended response is 0x78 (application class, constructed, tag number twenty-four).

An OID is really only necessary if a single request can yield multiple types of responses, but some types of extended responses always include an OID even if they’re the only kind of response for the associated request. In cases where the response has an OID, that OID may be the same as or different from the request OID.

Unsolicited Notifications

The vast majority of the time, LDAP is a request-response protocol. The client sends a request, and the server sends back one or more responses. But sometimes, the server might need to send a message to the client without there having been a corresponding request. For example, if the server is shutting down, it would be nice to tell any connected clients about it before disconnecting them. This can be accomplished with unsolicited notifications.

An unsolicited notification is simply an extended response that the server sends to the client without a corresponding extended request. Unsolicited notifications always use a message ID of zero, and they always have a responseName element (an OID) to indicate what kind of notification it is. They may or may not have a responseValue, and they may use other LDAPResult fields to provide additional information to the client.

RFC 4511 defines one type of unsolicited notification: the notice of disconnection notification (in section 4.4.1). It is used to indicate that the server is about to close the connection to the client for some reason (e.g., because the server is shutting down, because the connection has been idle for too long, because the client did something the server didn’t like, etc.). The notice of disconnection unsolicited notification has an OID of 1.3.6.1.4.1.1466.20036 and no value. The result code may provide a general indication of the disconnect reason, and there may be a diagnostic message with additional details.

For example, let’s say that the server wants to send a notice of disconnection to the client with a result code of unavailable (52) and a diagnostic message of “The Directory Server is shutting down”. That unsolicited notification would be encoded as follows:

30 49 -- Begin the LDAPMessage sequence
   02 01 00 -- The message ID (integer value 0)
   78 44 -- Begin the extended response protocol op
      0a 01 34 -- unavailable result code (enumerated value 52)
      04 00 -- No matched DN (0-byte octet string)
      04 25 54 68 65 20 44 69 72 65 -- The diagnostic message (octet string
            63 74 6f 72 79 20 53 65 -- "The Directory Server is shutting down")
            72 76 65 72 20 69 73 20
            73 68 75 74 74 69 6e 67
            20 64 6f 77 6e
      8a 16 31 2e 33 2e 36 2e 31 2e -- The extended response OID (octet string
            34 2e 31 2e 31 34 36 36 -- "1.3.6.1.4.1.1466.20036")
            2e 32 30 30 33 36

Example: The StartTLS Extended Operation

As a first example, let’s look at a StartTLS extended request, which is defined in RFC 4511 section 4.14. This request has an OID of 1.3.6.1.4.1.1466.20037 and no value. A StartTLS request with message ID one is encoded as follows:

30 1d -- Begin the LDAPMessage sequence
   02 01 01 -- The message ID (integer value 1)
   77 18 -- Begin the extended request protocol op
      80 16 31 2e 33 2e 36 2e 31 2e -- The extended request OID
            34 2e 31 2e 31 34 36 36 -- (octet string "1.3.6.1.4.1.1466.20037"
            2e 32 30 30 33 37       -- with type context-specific primitive zero)

The StartTLS response doesn’t have a value, but it may optionally contain an OID. If it doesn’t have an OID, then the StartTLS extended response is just a simple LDAPResult. But if it does have an OID, then that OID must be the same as the request OID (1.3.6.1.4.1.1466.20037). The following example demonstrates the appropriate encoding for a successful StartTLS response that does include the OID:

30 24 -- Begin the LDAPMessage sequence
   02 01 01 -- The message ID (integer value 1)
   78 1f -- Begin the extended response protocol op
      0a 01 00 -- success result code (enumerated value 0)
      04 00 -- No matched DN (0-byte octet string)
      04 00 -- No diagnostic message (0-byte octet string)
      8a 16 31 2e 33 2e 36 2e 31 2e -- The extended response OID
            34 2e 31 2e 31 34 36 36 -- (octet string "1.3.6.1.4.1.1466.20037"
            2e 32 30 30 33 37       -- with type context-specific primitive zero)

Note that the StartTLS response is always sent in the clear; the TLS negotiation doesn’t happen until after the StartTLS response is sent, and then everything after that point will be encrypted.

Example: The Password Modify Extended Operation

The password modify extended operation, defined in RFC 3062, is a little more complicated than the StartTLS operation, since the request always includes a value, and the response may optionally include a value.

The password modify extended request has an OID of 1.3.6.1.4.1.4203.1.11.1. The value is BER-encoded and uses the following encoding:

PasswdModifyRequestValue ::= SEQUENCE {
  userIdentity    [0]  OCTET STRING OPTIONAL
  oldPasswd       [1]  OCTET STRING OPTIONAL
  newPasswd       [2]  OCTET STRING OPTIONAL }

The elements of this request value are:

For example, let’s consider a password modify request with message ID 1, a userIdentity of uid=jdoe,ou=People,dc=example,dc=com, an oldPasswd of secret123, and no newPasswd value. That request would be encoded as follows:

30 53 -- Begin the LDAPMessage sequence
   02 01 01 -- The message ID (integer value 1)
   77 4e -- Begin the extended request protocol op
   80 17 31 2e 33 2e 36 2e 31 2e -- The extended request OID
         34 2e 31 2e 34 32 30 33 -- (octet string "1.3.6.1.4.1.4203.1.11.1"
         2e 31 2e 31 31 2e 31    -- with type context-specific primitive zero)
   81 33 -- Begin the extended request value
      30 31 -- Begin the value sequence
         80 24 75 69 64 3d 6a 64 6f 65 -- The userIdentity (octet string
               2c 6f 75 3d 50 65 6f 70 -- "uid=jdoe,ou=People,dc=example,dc=com"
               6c 65 2c 64 63 3d 65 78 -- with type context-specific primitive zero)
               61 6d 70 6c 65 2c 64 63
               3d 63 6f 6d
         81 09 73 65 63 72 65 74 31 32 -- The oldPasswd (octet string "secret123"
               33                      -- with type context-specific primitive one)

The password modify extended response doesn’t include a response OID. It may optionally include a response value, but that will only be if the request didn’t specify a newPasswd value and the server generated a new password for the target user. In that case, the response value will have the following encoding:

PasswdModifyResponseValue ::= SEQUENCE {
  genPasswd       [0]     OCTET STRING OPTIONAL }

If we assume that the server successfully processed the above request and generated a password of AdapterSystemGrainPlaymate, then the extended response would have the following encoding:

30 2f -- Begin the LDAPMessage sequence
   02 01 01 -- The LDAP message ID (integer value 1)
   78 2a -- Begin the extended response protocol op
      0a 01 00 -- success result code (enumerated value 0)
      04 00 -- No matched DN (0-byte octet string)
      04 00 -- No diagnostic message (0-byte octet string)
      8b 21 -- Begin the extended response value
         30 1f -- Begin the value sequence
            80 1d 41 64 61 70 74 65 72 53 -- The genPasswd (octet string
                  74 65 76 65 6e 73 6f 6e -- "AdapterSystemGrainPlaymate" with
                  47 72 61 69 6e 50 6c 61 -- type context-specific primitive zero)
                  79 6d 61 74 65

Previous: The LDAP Delete Operation Next: The LDAP Modify Operation