![](/img/trans.png)
[英]JNI ERROR (app bug): attempt to use stale Local 0x31 (should be 0x39)
[英]Can not “ldap_bind_s” to AD in C++ (0x31 error code)
我正在嘗試根據MSDN的這些說明連接到Windows Server 2008中的AD。 直到調用ldap_bind_s
都可以,但是隨后我收到了0x31代碼的錯誤( 提供的憑據無效 )。
用戶名和密碼正確,我已經檢查了好幾次了。
使用C ++ MSVS2015。這是我的代碼示例。
PWSTR host_name = L"ad.server.ip.address";
LDAP* pLdapConnection = NULL;
pLdapConnection = ldap_init(host_name, LDAP_PORT);
if (pLdapConnection == NULL)
{
printf("ldap_init failed with 0x%x.\n", LdapGetLastError());
ldap_unbind(pLdapConnection);
return -1;
}
else
printf("ldap_init succeeded \n");
ULONG version = LDAP_VERSION3;
ULONG lRtn = 0;
lRtn = ldap_set_option(
pLdapConnection,
LDAP_OPT_PROTOCOL_VERSION,
(void*)&version);
if (lRtn == LDAP_SUCCESS)
printf("ldap version set to 3.0 \n");
else
{
printf("SetOption Error:%0lX\n", lRtn);
ldap_unbind(pLdapConnection);
return hr;
}
lRtn = ldap_connect(pLdapConnection, NULL);
if (lRtn == LDAP_SUCCESS)
printf("ldap_connect succeeded \n");
else
{
printf("ldap_connect failed with 0x%lx.\n", lRtn);
ldap_unbind(pLdapConnection);
return -1;
}
PWSTR pMyDN = L"DC=ad,DC=domain,DC=name";
SEC_WINNT_AUTH_IDENTITY secIdent;
//adm@ad.domain.name
unsigned short login[18] = { 'a', 'd', 'm', '@', 'a', 'd', '.', 'd', 'o', 'm', 'a', 'i', 'n', '.', 'n', 'a', 'm', 'e' }; //18
secIdent.User = login;
secIdent.UserLength = 18;
//mypassword
unsigned short password[10] = { 'm', 'y', 'p', 'a', 's', 's', 'w', 'o', 'r', 'd' }; //10
secIdent.Password = password;
secIdent.PasswordLength = 10;
//ad.domain.name
unsigned short domain[14] = { 'a', 'd', '.', 'd', 'o', 'm', 'a', 'i', 'n', '.', 'n', 'a', 'm', 'e' }; //14
secIdent.Domain = dmn;
secIdent.DomainLength = 14;
secIdent.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
lRtn = ldap_bind_s(
pLdapConnection, // Session Handle
pMyDN, // Domain DN
(PWCHAR)&secIdent, // Credential structure
LDAP_AUTH_NEGOTIATE); // Auth mode
if (lRtn == LDAP_SUCCESS)
{
printf("ldap_bind_s succeeded \n");
secIdent.Password = NULL; // Remove password pointer
pPassword = NULL; // Remove password pointer
}
else
{
printf("ldap_bind_s failed with 0x%lx.\n", lRtn);
ldap_unbind(pLdapConnection);
return -1;
}
控制台輸出:
ldap_init succeeded
ldap version set to 3.0
ldap_connect succeeded
ldap_bind_s failed with 0x31.
Cannot execute query. Cannot bind to LDAP
在我看來,該錯誤可能是由於編碼或域名引起的。 但是根據此答案 , SEC_WINNT_AUTH_IDENTITY
結構中的域字段SEC_WINNT_AUTH_IDENTITY
被忽略。 我也試圖設置secIdent.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
沒有任何結果。
以下是可成功連接到同一AD服務器的PHP代碼段
$this->c = ldap_connect("ad.server.ip.address");
ldap_set_option($this->c, LDAP_OPT_PROTOCOL_VERSION, 3);
$r = ldap_bind($this->c,'adm@ad.domain.name','mypassword');
看完這個例子才 找到解決方案
我應該在ldap_bind_s()
使用LDAP_AUTH_SIMPLE
身份驗證方法,而不是LDAP_AUTH_NEGOTIATE
,或者僅使用ldap_bind_s()
ldap_simple_bind_s()
。
工作代碼段
PWSTR host_name = L"ad.server.ip.address";
LDAP* pLdapConnection = NULL;
pLdapConnection = ldap_init(host_name, LDAP_PORT);
if (pLdapConnection == NULL)
{
printf("ldap_init failed with 0x%x.\n", LdapGetLastError());
ldap_unbind(pLdapConnection);
return -1;
}
else
printf("ldap_init succeeded \n");
ULONG version = LDAP_VERSION3;
ULONG lRtn = 0;
lRtn = ldap_set_option(
pLdapConnection, // Session handle
LDAP_OPT_PROTOCOL_VERSION, // Option
(void*)&version); // Option value
if (lRtn == LDAP_SUCCESS)
printf("ldap version set to 3.0 \n");
else
{
printf("SetOption Error:%0lX\n", lRtn);
ldap_unbind(pLdapConnection);
return 0;
}
lRtn = ldap_connect(pLdapConnection, NULL);
if (lRtn == LDAP_SUCCESS)
printf("ldap_connect succeeded \n");
else
{
printf("ldap_connect failed with 0x%lx.\n", lRtn);
ldap_unbind(pLdapConnection);
return -1;
}
PWCHAR user_name = L"adm@ad.domain.name";
PWCHAR password = L"mypassword";
lRtn = ldap_simple_bind_s(pLdapConnection, user_name, password);
if (lRtn == LDAP_SUCCESS)
{
printf("ldap_simple_bind_s succeeded \n");
}
else
{
printf("ldap_simple_bind_s failed with 0x%lx.\n", lRtn);
ldap_unbind(pLdapConnection);
return -1;
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.