Introduction

This feature introduces NTLM support for ApacheDS as a SASL mechanism when ApacheDS is ONLY running on a Windows host. It utilizes native Win32 system libraries on the Windows host to tap into the SMB stack by forwarding NTLM messages between the LDAP client, ApacheDS and (most likely) an SMB Server. It should work for both local (no SMB then) and remote users.

NTLM Background

An authentication mechanism used by various MS network protocols replaced by Kerberos for domain users. Still needed however for access to Servers not part of the domain and to authenticate local users. NTLM piggy backs on existing wire protocols in a protocol specific fashion. NTLM is a part of the Security Support Provider Interface (SSPI) in Windows. There are two versions: NTLMv1 and NTLMv2.

Unlike Kerberos which requires a 3rd party to validate identity NTLM does not. NTLM uses signing for integrity with digital signatures using shared common secret key with a Message Authentication Code (MAC). Confidentiality can be achieved with sealing using symmetric-key encryption and a signature. The important thing to note for this implementation, is that NTLM requests can be passed through. Because NTLM is not like Kerberos it allows this but since it does it cannot protect against man in the middle attacks as does Kerberos.

There are 3 message types involved in an NTLM authentication sequence:

  • Type 1: request to server contains list of features supported by the client and requested of the server.
  • Type 2: response from server containing a list of supported features and agreed upon by the server. Contains a challenge generated by the server.
  • Type 3: response from client to challenge with domain, user name, w/ one or more responses to challenge.

SASL NTLM Interaction

The SASL Bind requires 2 iterations of a bind request response interchange. This is to negotiate the encryption types and process the challenge issued by the server in the Type 2 message. Here's a depiction of the multi-part bind interaction between the players in an NTLM transaction:

In LDAP a challenge is indicated by the server sending a BindResponse message with the resultCode set to saslBindInProgress[14]. This indicates that the server requires the client to send a new BindRequest message with the same SASL mechanism to continue the authentication process. This is used to continue the SASL Bind with the second Bind request as seen in the depiction above. The last SASL Bind Response from the server will contain either a success[0] LDAP result code or some other result code to indicate an error occurred.

Here's the pcap file used for the screenshots below. Make sure you go toggle LDAP as the protocol (ran this on port 1024 so it is not auto-recognized). To do so just use the menu's, Analyze->"Decode As", and select LDAP from the transport tab like so:

First LDAP Bind Request PDU in Wireshark

First LDAP Bind Response PDU in Wireshark

Second LDAP Bind Request PDU in Wireshark

Second LDAP Bind Response (final) PDU in Wireshark

For More Information:

NTLM Information

LDAP Bind Information

LDAP Specifics: NTLM Message Type Transport Over LDAP

The LDAP Client uses SASL bind. It uses authentication choice option 3 depicted below in the LDAP ASN.1 description for BindRequests:

 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 }

With AuthenticationChoice3 the SaslCredentials structure has the mechanism set to 'NTLM'. During the course of the interaction the LDAP Client generates the Type 1 and Type 3 NTLM requests itself. These raw requests are base64 encoded and set into the credentials field of the SaslCredentials structure.

ApacheDS upon receiving these requests extracts the credentials and base64 decodes the Type 1 or Type 2 messages. ApacheDS then uses the Win32 API JNI wrapper to pass through these requests to the host which utilizes whatever mechanism available to communicate with the SMB server based on it's configuration.

The SASL Bind Response after the Type 1 request message contains the Type 2 NTLM challenge response from the server in the serverSaslCreds field of the BindResponse structure as seen here in the ASN.1 description:

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

The raw Type 2 message contained in this field is base64 encoded. The client must base64 decode this message before processing it.

Pass-Thru Mechanism: Native Win32 Interface

ApacheDS will not do much with the NTLM messages besides shuffle them back and forth as an intermediary through a Win32 JNI wrapper. The Win32 library will allow callers to start an NTLM negotiation by the host through some protocol (most likely SMB) to authenticate the user with a Windows Server. What server is used to do this is dependent on the configuration of the host ApacheDS is running on. The authentication may simply take place locally or require communication with another Windows server.

ApacheDS thus acts as an LDAP Gateway to interface with the Win32 SSPI. It takes the NTLM Type 1 request, base64 decodes the opaque data structure, and calls methods on the Win32 API Java wrapper to get back a Type 2 request containing the NTLM challenge. ApacheDS then tunnels back the Type 2 NTLM response to the client in the serverSaslCreds field, as described above, in the SASL Bind Response. The client generates the Type 3 NTLM challenge response, from the user password, the domain and the Type 2 challenge. The LDAP client tunnels this structure after base64 encoding it to ApacheDS in the second SASL Bind Request. ApacheDS again extracts this Type 3 message from the SaslCredentials.credentials field, base64 decodes it and makes another call to the Win32 API Java wrapper.

ApacheDS simply tunnels the requests with base64 encode/decode operations on the NTLM requests/responses. The NTLM data is opaque and ApacheDS need not be concerned with the content it contains. The SASL Bind Request's mechanism is sufficient for ApacheDS to switch the mechanism and understand how to deal with the authentication. Even the DN supplied in the Bind operation is not considered since the NTLM payloads contain all the information needed to perform the handoff to the host via the Win32 API.

Native Library

We're in the process of determining the API of the Java Wrapper and the Win32 calls required for the interaction. More to come soon.

AD Style Principal Names with Simple Bind

An optional nice to have feature, which can be implemented later to makes ApacheDS look and feel more like ActiveDirectory or ADAM.

This is an interesting possibility now. Because we have direct access to the Win32 SSPI via the Win32 interface it's possible with slight modifications to the LDAP frontend of ApacheDS to allow users to bind with <username>@<domain> principals rather than using a DN for the bind principal. Active Directory allows this kind of authentication to take place, and by doing so allows local host users, as well as NT/200* domain users to conveniently authenticate.

Supporting this feature will require changes to the BindOperationContext and the LDAP codec in ApacheDS to not parse the bind principal as a DN but to leave it as a String. If the parse fails then a String form can be left perhaps in the BindOpContext.

  • No labels