Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>I managed to perform an LDAP SASL bind over GSSAPI, using <code>ldap_sasl_bind_s</code>. For those interested, here are some pointers.</p> <p>For an abstract description of the actions a client and server need to perform during a GSSAPI SASL authentication, <strong>"The Kerberos V5 ("GSSAPI") Simple Authentication and Security Layer (SASL) Mechanism"</strong> RFC should be read; specifically, the 'Client Side of Authentication Protocol Exchange' section is of interest, because it gives an indication of the sequence of actions we need to perform to successfully bind to an LDAP server over Kerberos.</p> <p>The credentials <code>ldap_sasl_bind_s</code> expects - their form and their meaning - depend on the actual authentication mechanism being used, which in our case is Kerberos.</p> <p>In the Microsoft SDK, Kerberos is available through SSPI - which is roughly the Microsoft implementation of GSSAPI; the methods that are relevant for our particular case are: <code>AcquireCredentialsHandle</code>, <code>InitializeSecurityContext</code>, <code>DecryptMessage</code>, <code>EncryptMessage</code></p> <p>An LDAP SASL bind over Kerberos has 3 phases.</p> <h3>Phase 1</h3> <p>Call <code>AcquireCredentialsHandle</code> and <code>InitializeSecurityContext</code>.<br> Important notes here: </p> <ul> <li>pass to <code>AcquireCredentialsHandle</code> a pointer to a <code>SEC_WINNT_AUTH_IDENTITY</code> structure containing the actual credentials (realm, username, password), or <code>NULL</code> if the credentials of the current thread are to be used </li> <li>the target name should be an SPN mapped to the account under which the LDAP server is running</li> <li>when calling <code>InitializeSecurityContext</code>, mutual authentication must be requested. </li> </ul> <p>If all important arguments are correct - valid credentials, valid SPN, <code>NULL</code> input token - the <code>InitializeSecurityContext</code> call should return <code>SEC_I_CONTINUE_NEEDED</code> and properly fill the output token. The contents of this output token should go in the <code>BERVAL</code> structure <code>ldap_sasl_bind_s</code> expects as client credentials. </p> <p>Call <code>ldap_sasl_bind_s</code> with the output token from <code>InitializeSecurityContext</code> as client credentials. If all arguments are correct - empty DN, GSSAPI as the mechanism name - the actual call should return <code>LDAP_SUCCESS</code> and the most recent LDAP error for the LDAP session should be <code>LDAP_SASL_BIND_IN_PROGRESS</code>. </p> <p>As a side note, the most recent LDAP error for an LDAP session can be discovered by calling <code>ldap_get_option</code> on the session, with <code>LDAP_OPT_ERROR_NUMBER</code> as the option. </p> <h3>Phase 2</h3> <p>After the successful call to <code>ldap_sasl_bind_s</code>, its last argument points to a <code>BERVAL</code> structure containing the server credentials. The content of this <code>BERVAL</code> structure should now be used as the input token for the second call to <code>InitializeSecurityContext</code>. </p> <p>This second call to <code>InitializeSecurityContext</code> should return <code>SEC_OK</code> and an empty output token. </p> <p>This empty output token should be used as the client credentials for another call to <code>ldap_sasl_bind_s</code>. This second call to <code>ldap_sasl_bind_s</code> should return <code>LDAP_SUCCESS</code>, with the most recent LDAP error for the LDAP session being <code>LDAP_SASL_BIND_IN_PROGRESS</code>.</p> <h3>Phase 3</h3> <p>After the second successful call to <code>ldap_sasl_bind_s</code>, its last argument points to a <code>BERVAL</code> structure containing server data. This server data should be given as input to <code>DecryptMessage</code>. As specified in the previously mentioned RFC, the decrypted data must be 4 bytes long. </p> <p>The client should build its reply according to the information in the same RFC.<br> <strong>Note</strong>: In my case, I omitted the authorization id mentioned in the RFC. To my understanding, an empty authorization id leads to the authentication id being used for authorization as well. </p> <p>The reply the client built should then be passed as input to <code>EncryptMessage</code>. The output of the <code>EncryptMessage</code> call should then be passed as the client credentials for the third and final call to <code>ldap_sasl_bind_s</code>.</p> <p><strong>Note</strong>: The MSDN documentation for using <code>EncryptMessage</code> under Kerberos seems to be incomplete. Google's Code Search should assist with a working example. Also, for a working example of the flow described above, Samba's source code can be consulted.</p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload