Windows 上的 LDAP 绑定与 VCE
LDAP binding on Windows vs. VCE
我被赋予了一项简单的任务,即在 C# 应用程序中从 Windows Compact 7 设备对 AD 进行 Windows 身份验证。现在 - 14 天后我仍然在挣扎,所以任何帮助将不胜感激。
无论如何 - 到目前为止我设法想出的是在我的电脑上使用 wldap32.dll 进行 Windows 身份验证。我远不是 C++ 专家,使用 Visual C++ 更不是,所以请多多包涵。
这是我的 C++ 代码:
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;
}
还有我的 C# 示例包装器:
[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(); }
}
所以 - 使用上面的代码,我可以在我的 PC 上使用我自己的凭据进行身份验证。 运行 WCE 设备上的相同代码,我可以连接到AD 服务器,但是当我尝试ldap_bind_s 时,它returns LDAP_AUTH_METHOD_NOT_SUPPORTED。所以我认为 wldap32.dll 的 ARM 版本与 x86 版本不同。
然后我尝试使用ldap_bind(没有'_s')方法。这在我的 PC 和 WCE 设备上都无法正常工作,而且总是 returns 0xFFFF_FFFF.
基本上我的问题是:
LDAP_AUTH_METHOD_NOT_SUPPORTED 是什么意思,我在 WCE7 设备上还有哪些其他方法?和
ldap_bindreturns0xFFFF_FFFF是什么意思?
但我们将不胜感激任何意见或建议。提前致谢!
您的 WEC7 设备供应商是否在 OS 版本中包含 LDAP 功能?
或者,如果供应商是您,您是否在 Platform Builder 项目中指定了 SYSGEN_LDAP?
如果您可以访问设备的 \Windows 目录中的 ceconfig.h 文件,请尝试检查该文件。
我被赋予了一项简单的任务,即在 C# 应用程序中从 Windows Compact 7 设备对 AD 进行 Windows 身份验证。现在 - 14 天后我仍然在挣扎,所以任何帮助将不胜感激。
无论如何 - 到目前为止我设法想出的是在我的电脑上使用 wldap32.dll 进行 Windows 身份验证。我远不是 C++ 专家,使用 Visual C++ 更不是,所以请多多包涵。 这是我的 C++ 代码:
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;
}
还有我的 C# 示例包装器:
[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(); }
}
所以 - 使用上面的代码,我可以在我的 PC 上使用我自己的凭据进行身份验证。 运行 WCE 设备上的相同代码,我可以连接到AD 服务器,但是当我尝试ldap_bind_s 时,它returns LDAP_AUTH_METHOD_NOT_SUPPORTED。所以我认为 wldap32.dll 的 ARM 版本与 x86 版本不同。
然后我尝试使用ldap_bind(没有'_s')方法。这在我的 PC 和 WCE 设备上都无法正常工作,而且总是 returns 0xFFFF_FFFF.
基本上我的问题是:
LDAP_AUTH_METHOD_NOT_SUPPORTED 是什么意思,我在 WCE7 设备上还有哪些其他方法?和
ldap_bindreturns0xFFFF_FFFF是什么意思?
但我们将不胜感激任何意见或建议。提前致谢!
您的 WEC7 设备供应商是否在 OS 版本中包含 LDAP 功能?
或者,如果供应商是您,您是否在 Platform Builder 项目中指定了 SYSGEN_LDAP?
如果您可以访问设备的 \Windows 目录中的 ceconfig.h 文件,请尝试检查该文件。