I have been given the simple task to do Windows authentication against the AD from a Windows Compact 7 device in a C# app. Now - 14 days later I'm still struggling, so any help would be greatly appreciated.
Anyway - what I’ve managed to come up with so far is doing Windows authentication on my PC using the wldap32.dll. I’m far from a C++ expert, and with Visual C++ even less so, so bear with me. Here is my C++ code:
EXPORT_METHOD unsigned long Authenticate(char *userName, char *password, char *domain)
{
unsigned long result = 0;
unsigned short *uUserName = (unsigned short *)userName;
unsigned short *uPassword = (unsigned short *)password;
unsigned short *uDomain = (unsigned short *)domain;
PWCHAR hostName = NULL;
LDAP* pLdapConnection = NULL;
ULONG version = LDAP_VERSION3;
size_t origsize = strlen("ELLAB.COM") + 1;
size_t convertedChars = 0;
wchar_t wcstring[100];
mbstowcs_s(&convertedChars, wcstring, origsize, "ELLAB.COM", _TRUNCATE);
wcscat_s(wcstring, L" (wchar_t *)");
hostName = wcstring;
// Initialize a session. LDAP_PORT is the default port, 389.
pLdapConnection = ldap_init(hostName, LDAP_PORT);
if (pLdapConnection == NULL)
{
#ifdef DEBUG
AfxMessageBox(_T("Unable to Init"));
#endif // DEBUG
result = 0xff;
}
else
{
// Set the version to 3.0 (default is 2.0).
result = ldap_set_option(pLdapConnection, LDAP_OPT_PROTOCOL_VERSION, (void*)&version);
if (result != LDAP_SUCCESS)
{
#ifdef DEBUG
AfxMessageBox(_T("Unable to Set Optins"));
#endif // DEBUG
}
else
{
// Connect to the server.
result = ldap_connect(pLdapConnection, NULL);
if (result != LDAP_SUCCESS)
{
#ifdef DEBUG
AfxMessageBox(_T("Unable to Connect"));
#endif // DEBUG
}
else
{
// Be aware that the password itself is never sent over the network, and encryption is not used.
SEC_WINNT_AUTH_IDENTITY NtAuthIdentity;
ZeroMemory(&NtAuthIdentity, sizeof(NtAuthIdentity));
NtAuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
NtAuthIdentity.Domain = uDomain;
NtAuthIdentity.DomainLength = sizeof(uDomain);
NtAuthIdentity.User = uUserName;
NtAuthIdentity.UserLength = sizeof(uUserName);
NtAuthIdentity.Password = uPassword;
NtAuthIdentity.PasswordLength = sizeof(uPassword);
//if (ldap_bind_s(pLdapConnection, NULL, NULL, LDAP_AUTH_NEGOTIATE) == LDAP_SUCCESS)
result = ldap_bind_s(pLdapConnection, NULL, (PWCHAR)&NtAuthIdentity, LDAP_AUTH_NTLM);
//if (result != LDAP_SUCCESS)
{
#ifdef DEBUG
AfxMessageBox(_T("Unable to Bind using ldap_bind_s"));
#endif // DEBUG
result = ldap_bind(pLdapConnection, NULL, (PWCHAR)&NtAuthIdentity, LDAP_AUTH_NTLM);
if (result != LDAP_SUCCESS)
{
#ifdef DEBUG
AfxMessageBox(_T("Unable to Bind using ldap_bind"));
#endif // DEBUG
}
}
}
}
// Normal cleanup and exit.
ldap_unbind(pLdapConnection);
}
return result;
}
And my C# sample wrapper:
[DllImport(@"C:\Users\ckbn.ELLAB\Documents\Visual Studio 2015\Projects\WCE7_LDAP\Debug\LDAPHandler.dll", CharSet = CharSet.Unicode)]
public static extern int Authenticate(string userName, string password, string domain);
private void buttonAuthenticate_Click(object sender, EventArgs e)
{
try
{
textBoxResult.Text = "";
LDAPReturns result = (LDAPReturns)Authenticate(textBoxUserName.Text, textBoxPassword.Text, textBoxDomain.Text);
switch (result)
{
case LDAPReturns.LDAP_SUCCESS:
textBoxResult.Text = "User '" + textBoxUserName.Text + "' is authenticated";
break;
default:
textBoxResult.Text = result.ToString();
break;
}
}
catch (Exception ex) { textBoxResult.Text = "Failed: " + ex.ToString(); }
}
So - using the above code I can authenticate with my own credentials on my PC. Running the same code on the WCE device, I can connect to the AD server, but when I try to ldap_bind_s, it returns LDAP_AUTH_METHOD_NOT_SUPPORTED. So I’m thinking the the ARM version of the wldap32.dll is different from the x86 version.
Then I tried to use the ldap_bind (without ‘_s’) method. This is not working nighter on my PC nor on the WCE device and always returns 0xFFFF_FFFF.
So basically my questions are:
What does LDAP_AUTH_METHOD_NOT_SUPPORTED means, and what other methods do I have on a WCE7 device? and
What does it means when ldap_bind returns 0xFFFF_FFFF?
But any input or suggestion would be highly appreciated. Thanks in advance!
Did the vendor of your WEC7 device include the LDAP feature in the OS build?
Or, if the vendor is you, did you specify SYSGEN_LDAP in your Platform Builder project?
Try checking the ceconfig.h file in the \Windows directory of your device if you have access to that.