本文介绍了不能“ ldap_bind_s"" ldap_bind_s& quot;到C ++中的AD(0x31错误代码)的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在尝试根据来自MSDN的这些说明.直到调用 ldap_bind_s 都可以,但是随后我收到了0x31代码的错误(提供的凭据无效).

用户名和密码正确,我已经检查了好几次了.

使用C ++ MSVS2015.这是我的代码示例.

  PWSTR host_name = L"ad.server.ip.address";LDAP * pLdapConnection = NULL;pLdapConnection = ldap_init(主机名,LDAP_PORT);如果(pLdapConnection == NULL){printf("ldap_init失败,出现0x%x.\ n",LdapGetLastError());ldap_unbind(pLdapConnection);返回-1;}别的printf("ldap_init成功\ n");ULONG版本= LDAP_VERSION3;ULONG lRtn = 0;lRtn = ldap_set_option(pLdapConnection,LDAP_OPT_PROTOCOL_VERSION,(void *)& version);如果(lRtn == LDAP_SUCCESS)printf("ldap版本设置为3.0 \ n");别的{printf("SetOption Error:%0lX \ n",lRtn);ldap_unbind(pLdapConnection);返回小时;}lRtn = ldap_connect(pLdapConnection,NULL);如果(lRtn == LDAP_SUCCESS)printf("ldap_connect成功\ n");别的{printf("ldap_connect失败,出现0x%lx.\ n",lRtn);ldap_unbind(pLdapConnection);返回-1;}PWSTR pMyDN = L"DC = ad,DC = domain,DC = name";SEC_WINNT_AUTH_IDENTITY秒;//[email protected]无符号短登录名[18] = {'a','d','m','@','a','d','.','d','o','m','a','i','n','.','n','a','m','e'};//18secIdent.User =登录;secIdent.UserLength = 18;//我的密码未签名的短密码[10] = {'m','y','p','a','s','s','w','o','r','d'};//10secIdent.Password =密码;secIdent.PasswordLength = 10;//ad.domain.name无符号短域[14] = {'a','d','.','d','o','m','a','i','n','.','n','a','m','e'};//14secIdent.Domain = dmn;secIdent.DomainLength = 14;secIdent.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;lRtn = ldap_bind_s(pLdapConnection,//会话句柄pMyDN,//域DN(PWCHAR)& secIdent,//凭据结构LDAP_AUTH_NEGOTIATE);//验证模式如果(lRtn == LDAP_SUCCESS){printf("ldap_bind_s成功\ n");secIdent.Password = NULL;//删除密码指针pPassword = NULL;//删除密码指针}别的{printf("ldap_bind_s失败,出现0x%lx.\ n",lRtn);ldap_unbind(pLdapConnection);返回-1;} 

控制台输出:

  ldap_init成功ldap版本设置为3.0ldap_connect成功ldap_bind_s失败,出现0x31.无法执行查询.无法绑定到LDAP 

在我看来,该错误可能是由于编码或域名引起的.但是根据此答案 SEC_WINNT_AUTH_IDENTITY 结构中的域字段将被忽略.我也尝试设置 secIdent.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; 没有任何结果.


UPD.

下面是可以成功连接到同一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_AUTH_SIMPLE 身份验证方法,而不是 ldap_bind_s()中的 LDAP_AUTH_NEGOTIATE ,或者只使用 ldap_simple_bind_s()

工作代码段

  PWSTR host_name = L"ad.server.ip.address";LDAP * pLdapConnection = NULL;pLdapConnection = ldap_init(主机名,LDAP_PORT);如果(pLdapConnection == NULL){printf("ldap_init失败,出现0x%x.\ n",LdapGetLastError());ldap_unbind(pLdapConnection);返回-1;}别的printf("ldap_init成功\ n");ULONG版本= LDAP_VERSION3;ULONG lRtn = 0;lRtn = ldap_set_option(pLdapConnection,//会话句柄LDAP_OPT_PROTOCOL_VERSION,//选项(void *)& version);//选项值如果(lRtn == LDAP_SUCCESS)printf("ldap版本设置为3.0 \ n");别的{printf("SetOption Error:%0lX \ n",lRtn);ldap_unbind(pLdapConnection);返回0;}lRtn = ldap_connect(pLdapConnection,NULL);如果(lRtn == LDAP_SUCCESS)printf("ldap_connect成功\ n");别的{printf("ldap_connect失败,出现0x%lx.\ n",lRtn);ldap_unbind(pLdapConnection);返回-1;}PWCHAR user_name = L"[email protected]";PWCHAR密码= L"mypassword";lRtn = ldap_simple_bind_s(pLdapConnection,用户名,密码);如果(lRtn == LDAP_SUCCESS){printf("ldap_simple_bind_s成功\ n");}别的{printf("ldap_simple_bind_s失败,出现0x%lx.\ n",lRtn);ldap_unbind(pLdapConnection);返回-1;} 

I'm trying to connect to AD in Windows Server 2008 according to these instructions from MSDN. Until calling ldap_bind_s all is ok, but then I got error with 0x31 code(The supplied credential is invalid).

Username and password are correct, I've checked for several times.

Using C++ MSVS 2015. Here is my code sample.

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;

//[email protected]
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;
}

Console output:

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

It seems to me that the error can be occured by encoding or domain name. But according to this answer, domain field in SEC_WINNT_AUTH_IDENTITYstructure is ignored. Also I tried to set secIdent.Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE; without any result.


UPD.

Below is PHP code snippet that performs successful connection to same AD Server

$this->c = ldap_connect("ad.server.ip.address");
ldap_set_option($this->c, LDAP_OPT_PROTOCOL_VERSION, 3);
$r = ldap_bind($this->c,'[email protected]','mypassword');
解决方案

Just found a solution after watching this example

I should use LDAP_AUTH_SIMPLE authentication method instead of LDAP_AUTH_NEGOTIATE in ldap_bind_s() or simply use ldap_simple_bind_s().

Working code snippet

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"[email protected]";
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;
}

这篇关于不能“ ldap_bind_s"" ldap_bind_s& quot;到C ++中的AD(0x31错误代码)的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-21 02:06