Click to See Complete Forum and Search --> : ldap_bind_s authenticates even with wrong domain parameter for LDAP_AUTH_NEGOTIATE


ram_kumar_c
April 24th, 2009, 09:55 AM
As part of our application's support for AD authentication, we ran into this problem.
We find that "ldap_bind_s " authenticates a user for "method" specified as "LDAP_AUTH_NEGOTIATE ", even in cases where the domain parameter is incorrect .
Looking into the event log on the LDAP server, we find that, when the domain parameter is correct, it authenticates using Kerberos protocol. When the domain parameter is incorrect, it authenticates the user using NTLM protocol.

1. We would like to know why the API behaves this way - takes the domain information, but authenticates the user even when it is incorrect.
2. Also, we would like to know if there is a way to prevent authentication, if the domain parameter is incorrect.

Not accepting domain parameter is not an option, as that would close the door for Kerberos authentication altogether.

The following is the code for a simple, console application, that can be used to reproduce the problem:

int main(int argc, char* argv[])
{
TCHAR Host[256];
LDAP* pLdapConnection = NULL;
ULONG version = LDAP_VERSION3;
ULONG getOptSuccess = 0;
ULONG connectSuccess = 0;
INT iRtn = 0;
ULONG option=0;
//----------------------------------------------------------
// Get the host name from the command line. If no host name
// was passed, set the pointer to NULL to use 'serverless'
// binding.
//----------------------------------------------------------
printf( "Enter the host name\n");
scanf("%s",Host);
//----------------------------------------------------------
// Initialize a session. LDAP_PORT is the default port, 389.
//----------------------------------------------------------
pLdapConnection = ldap_init(Host, LDAP_PORT);
if (pLdapConnection == NULL)
{
printf( "ldap_init failed with 0x%x.\n",GetLastError());
goto error_exit;
}
else
{
printf("ldap_init succeeded \n");
}
//-------------------------------------------------------
// Set the version to 3.0 (default is 2.0).
//-------------------------------------------------------
iRtn = ldap_set_option(pLdapConnection,
LDAP_OPT_PROTOCOL_VERSION,
(void*)&version);

if(iRtn == LDAP_SUCCESS)
{
printf("ldap_set_option succeeded, version set to 3\n");
}
else
{
printf("SetOption Error:%0X\n", iRtn);
goto error_exit;
}
char Domain[256];
char User[256];
char Pwd[256];
SEC_WINNT_AUTH_IDENTITY sec;
printf( "Enter the domain name\n");
scanf("%s",Domain);
sec.Domain = (unsigned char *)Domain;
sec.DomainLength = strlen( (char *)sec.Domain );
sec.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;

printf( "Enter the user name\n");
scanf("%s",User);
sec.User = (unsigned char *)User;
sec.UserLength = strlen( (char *)sec.User );

printf( "Enter the password \n");
scanf("%s",Pwd);
sec.Password = (unsigned char *)Pwd;
sec.PasswordLength = strlen( (char *)sec.Password );

iRtn = ldap_bind_s(pLdapConnection, NULL, (PCHAR)&sec, LDAP_AUTH_NEGOTIATE);
if (iRtn == LDAP_SUCCESS)
printf("The bind was successful");
else
{
printf("The bind failed");
goto error_exit;
}
//----------------------------------------------------------
// Normal cleanup and exit.
//----------------------------------------------------------
ldap_unbind(pLdapConnection);
getch();
return 0;
//----------------------------------------------------------
// On error cleanup and exit.
//----------------------------------------------------------
error_exit:
ldap_unbind(pLdapConnection);
getch();
return -1;
}