UnboundID LDAP SDK for Java

Ping Identity
Product Information

LDAPv3 Wire Protocol Reference

The LDAP Bind Operation

The LDAP bind operation is used to authenticate a client to the directory server. LDAPv3 supports two basic types of authentication:

A client can send a bind request at any time on a connection. If the connection has already been authenticated with an earlier bind request, sending another bind request can be used to re-authenticate the connection as a different user (or the same user if you send the same credentials). If the bind attempt does not succeed, the connection will revert to an unauthenticated state. And any request sent on a connection before the client performs a bind will also be treated as unauthenticated.

LDAP doesn’t do anything to protect bind credentials from anyone who can observe the communication between the client and the server. Certain SASL mechanisms do provide the ability to obscure sensitive information like passwords, but other SASL mechanisms do not, and there is also no protection for simple authentication. Unless you know that you’re using a SASL mechanism that does adequately protect the authentication credentials, and you also know that there won’t be any other sensitive information transferred over the connection, you are strongly encouraged to encrypt the communication between the client and the server (for example, using TLS).

The Bind Request

The bind request protocol operation is defined as follows in RFC 4511 section 4.2:

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 }

The LDAPDN and LDAPString dependencies are defined as follows elsewhere in RFC 4511:

LDAPDN ::= LDAPString
           -- Constrained to <distinguishedName> [RFC4514]

LDAPString ::= OCTET STRING -- UTF-8 encoded,
                            -- [ISO10646] characters

The elements of the bind request protocol op are as follows:

We’ll provide specific examples of simple and SASL bind requests later in this section.

The Bind Response

The bind response protocol operation is defined as follows in RFC 4511 section 4.2.2:

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

This means that the bind response has all of the elements of the LDAPResult protocol op (result code, matched DN, diagnostic message, and optional referral URLs), which we’ve already discussed in depth in an earlier section, plus an optional set of server SASL credentials. The server SASL credentials will only be included in the response to a SASL bind request, and only in response to certain kinds of SASL bind requests.

The bind response protocol operation has a BER type of 0x61 (application class, constructed, tag number one). We will provide examples of bind responses later in this section.

The Simple Bind Operation

As described above, the simple bind operation is used to authenticate with a DN and password. There are actually two kinds of simple binds: anonymous and authenticated. The anonymous simple bind has empty strings for both the DN and the password, while an authenticated simple bind has non-empty values for both of those fields.

The original LDAPv3 specification (RFC 4511 section 4.2.2) stated that an anonymous simple bind only required that the password be empty, but allowed the DN to be non-empty. This led to security vulnerabilities in a number of applications that used an LDAP server to authenticate users but didn’t bother checking to see whether the user actually provided a password. The revised LDAPv3 specification (RFC 4513 section 5.1.2) now recommends that servers reject simple binds that include a non-empty DN but an empty password with an unwillingToPerform (53) result.

When a non-empty password is provided, it must be the clear-text representation of that password, without any encryption, hashing, or other kind of obfuscation. So a communication security layer like TLS is strongly recommended when using an authenticated simple bind to ensure that the credentials are protected.

The following example demonstrates the encoding for an anonymous simple bind request with a message ID of one and no request controls:

30 0c -- Begin the LDAPMessage sequence
   02 01 01 --  The message ID (integer value 1)
   60 07 -- Begin the bind request protocol op
      02 01 03 -- The LDAP protocol version (integer value 3)
      04 00 -- Empty bind DN (0-byte octet string)
      80 00 -- Empty password (0-byte octet string with type context-specific
            -- primitive zero)

And the following example shows the encoding for an authenticated simple bind request for user uid=jdoe,ou=People,dc=example,dc=comt with password secret123, also with message ID one and no request controls:

30 39 -- Begin the LDAPMessage sequence
   02 01 01 -- The message ID (integer value 1)
   60 34 -- Begin the bind request protocol op
   02 01 03 -- The LDAP protocol version (integer value 3)
   04 24 75 69 64 3d 6a 64 6f 65 -- The bind DN (36-byte 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
         61 6d 70 6c 65 2c 64 63
         3d 63 6f 6d
   80 09 73 65 63 72 65 74 31 32 -- The password (9-byte octet string "secret123"
         33                      -- with type context-specific primitive zero)

The bind response protocol operation for a simple bind request is merely an LDAPResult with type 0x61. Assuming that the server returned a successful response to either of the above requests, with no matched DN, diagnostic message, referral URLs, or controls, it would be encoded as follows:

30 0c -- Begin the LDAPMessage sequence
   02 01 01 -- The message ID (integer value 1)
   61 07 -- Begin the bind 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)

The SASL Bind Operation

SASL is the Simple Authentication and Security Layer, and it’s based on the specification described in RFC 4422. SASL is an extensible framework that allows for a wide variety of authentication types, including the creation of custom types. Each flavor of SASL authentication is called a mechanism, and the SASL mechanism that the client wants to use is identified by name. There SASL bind request may also include additional information, called SASL credentials, to use in the authentication process.

Some common SASL mechanisms include:

The Ping Identity Directory Server (formerly UnboundID Directory Server) also defines a number of additional SASL mechanisms for stronger authentication types, including:

Describing all of the ins and outs of all these SASL mechanisms is beyond the scope of this document. But to illustrate the encoding for SASL requests and responses, let’s look at an example using the CRAM-MD5 mechanism. Although this mechanism is no longer considered secure, it is good for illustration purposes because it is fairly simple, because it involves a multi-stage bind process, and because it involves a response that includes server SASL credentials.

The CRAM-MD5 authentication process operates as follows:

  1. The client sends a bind request with a version of 3, an empty name, a SASL mechanism name of CRAM-MD5, and no SASL credentials. If we assume a message ID of one and no request controls, that bind request would be encoded as:

    30 16 -- Begin the LDAPMessage sequence
       02 01 01 -- The message ID (integer value 1)
       60 11 -- Begin the bind request protocol op
          02 01 03 -- The LDAP protocol version (integer value 3)
          04 00 -- Empty bind DN (0-byte octet string)
          a3 0a -- Begin the SASL authentication sequence
             04 08 43 52 41 4d 2d 4d 44 35 -- The SASL mechanism name
                                           -- (the octet string "CRAM-MD5")
  2. The server returns a bind response with a result code of saslBindInProgress (14) and server SASL credentials that are a randomly-generated challenge string encapsulated in angle brackets. If we assume that the server generated a challenge string of <10a13c7bf708ca0f399ca99e927da88b>, the bind response would be encoded as:

    30 30 -- Begin the LDAPMessage sequence
       02 01 01 -- The message ID (integer value 1)
       61 2b -- Begin the bind response protocol op
       0a 01 0e -- saslBindInProgress result code (enumerated value 14)
       04 00 -- No matched DN (0-byte octet string)
       04 00 -- No diagnostic message (0-byte octet string)
       87 22 3c 31 30 61 31 33 63 37 -- The server SASL credentials (the octet string
             62 66 37 30 38 63 61 30 -- "<10a13c7bf708ca0f399ca99e927da88b>")
             66 33 39 39 63 61 39 39
             65 39 32 37 64 61 38 38
             62 3e
  3. The client sends a second bind request with a version of 3, an empty name, a SASL mechanism name of CRAM-MD5, and SASL credentials that are comprised of the authentication ID followed by a space and a hexadecimal representation (with all letters in lowercase) of the HMAC-MD5 digest of the challenge string (returned in step 2) using the user’s password as the key. Let’s assume that the user wants to authenticate with a username of jdoe (which will be indicated by an authentication ID of u:jdoe) and a password of secret123. The hexadecimal representation of the HMAC-MD5 digest of the string <10a13c7bf708ca0f399ca99e927da88b> using a key of secret123 is d52116c87c31d9cc747600f9486d2a1d, so the second bind request (this time, with message ID two) is:

    30 3f -- Begin the LDAPMessage sequence
       02 01 02 -- The message ID (integer value 2)
       60 3a -- Begin the bind request protocol op
          02 01 03 -- The LDAP protocol version (integer value 3)
          04 00 -- Empty bind DN (0-byte octet string)
          a3 33 -- Begin the SASL authentication sequence
             04 08 43 52 41 4d 2d 4d 44 35 -- The SASL mechanism name
                                           -- (the octet string "CRAM-MD5")
             04 27 75 3a 6a 64 6f 65 20 64 -- The SASL credentials (the octet string
                   35 32 31 31 36 63 38 37 -- "u:jdoe d52116c87c31d9cc747600f9486d2a1d")
                   63 33 31 64 39 63 63 37
                   34 37 36 30 30 66 39 34
                   38 36 64 32 61 31 64
  4. Assuming that the credentials were correct and the account is usable, the server returns a bind response with a result code of success (0) and no server SASL credentials. This is encoded as:

    30 0c -- Begin the LDAPMessage sequence
       02 01 02 -- The message ID (integer value 2)
       61 07 -- Begin the bind 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)

Previous: The LDAP Add Operation Next: The LDAP Compare Operation