Question

I would like to ask you a question about implementing mutual authentication with Kerberos, using SSPI and LDAP API.

I am using the guidelines described in: ldap_sasl_bind_s(GSSAPI) - What should be provided in the credentials BERVAL structure.

Here is the algorithm I am using:


//--------------------------------------------------------------------------------------------
// client side

AcquireCredentialsHandle(NULL, "Kerberos", SECPKG_CRED_BOTH, NULL, &secIdent, NULL, NULL, &kClientCredential, &kClientTimeOut); 
// AcquireCredentialsHandle returns SEC_E_OK

// begin validation

unsigned long ulClientFlags = ISC_REQ_CONNECTION | ISC_REQ_MUTUAL_AUTH | ISC_REQ_DELEGATE;

int iCliStatus = InitializeSecurityContext(&kClientCredential, isContextNull(kClientContext) ? NULL : &kClientContext, 
                             pacTargetName, ulClientFlags, 0, SECURITY_NATIVE_DREP, pkServerToken, 
                             0, &kClientContext, &kClientToken, &ulContextAttr, NULL);

// InitializeSecurityContext returns SEC_I_CONTINUE_NEEDED

//--------------------------------------------------------------------------------------------
// server side

// ldap_init returns ok

ldap_set_option(ld, LDAP_OPT_SIGN, LDAP_OPT_OFF);
ldap_set_option(ld, LDAP_OPT_ENCRYPT, LDAP_OPT_OFF);

unsigned long ulVersion = LDAP_VERSION3;
ldap_set_option(ld, LDAP_OPT_VERSION, &ulVersion);

// ldap_connect returns LDAP_SUCCESS

// build the credentials based on what InitializeSecurityContext returned
BERVAL creds;
creds.bv_len = kClientToken.pBuffers[0].cbBuffer;
creds.bv_val = reinterpret_cast(kClientToken.pBuffers[0].pvBuffer);

BERVAL* pServerCreds = NULL;
int iError = ldap_sasl_bind_s(ld, "", "GSSAPI", &creds, NULL, NULL, &pServerCreds);

// ldap_sasl_bind_s returns LDAP_SUCCESS

unsigned long ulError = 0;
ldap_get_option(ld, LDAP_OPT_ERROR_NUMBER, &ulError);

// ulError is equal to LDAP_SASL_BIND_IN_PROGRESS

And here is the problem: both LDAP error codes are ok, but pServerCreds points to an empty BERVAL structure (not NULL, but bv_len equals to 0), and it should contain the server credential I have to pass to the next InitializeSecurityContext call. If I use that data to build the SecBufferDesc structure for the following call, it returns SEC_E_INVALID_TOKEN.

Is ldap_sasl_bind_s supposed to return an empty BERVAL or am I doing something wrong?

I have tested the authentication using full SSPI calls (AcceptSecurityContext for the server) and it works just as expected. The problem is that I need the server to be cross-platform, so I cannot use SSPI.

Thanks for taking the time to answer! Juan

Was it helpful?

Solution

I found the problem.

According to this thread there is a bug with ldap_sasl_bind_s returning empty server credentials in Windows XP. I have tested my application under Windows 2008 Server and the credentials are properly returned.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top