如何从 C++ 使用 LDAP 连接到 Active Directory?

How to connect to Active Directory using LDAP from C++?

我在 Windows Server 2019 上设置了 Active Directory。我正在尝试使用 LDAP 从 Windows 客户端连接到 Active Directory。我使用了这段代码,对 Microsoft 文档稍作修改:

//  Verify that the user passed a hostname.
if (hostname!=NULL)
{
    //  Convert argv[] to a wchar_t*
    size_t origsize = strlen(argv[1]) + 1;
    size_t convertedChars = 0;
    wchar_t wcstring[newsize];
    mbstowcs_s(convertedChars, wcstring, origsize, argv[1], _TRUNCATE);
    wcscat_s(wcstring, L" (wchar_t *)");
    hostName = wcstring;
}
else
{
    hostName = NULL;
}

//  Initialize a session. LDAP_PORT is the default port, 389.
pLdapConnection = ldap_init(hostName, LDAP_PORT);

if (pLdapConnection == NULL)
{
    //  Set the HRESULT based on the Windows error code.
    char hr = HRESULT_FROM_WIN32(GetLastError());
    printf( "ldap_init failed with 0x%x.\n",hr);
    goto error_exit;
}
else
    printf("ldap_init succeeded \n");

//  Set the version to 3.0 (default is 2.0).
returnCode = ldap_set_option(pLdapConnection,
                             LDAP_OPT_PROTOCOL_VERSION,
                             (void*)&version);
if(returnCode == LDAP_SUCCESS)
    printf("ldap_set_option succeeded - version set to 3\n");
else
{
    printf("SetOption Error:%0X\n", returnCode);
    goto error_exit;
}

// Connect to the server.
connectSuccess = ldap_connect(pLdapConnection, NULL);

if(connectSuccess == LDAP_SUCCESS)
    printf("ldap_connect succeeded \n");
else
{
    printf("ldap_connect failed with 0x%x.\n",connectSuccess);
    goto error_exit;
}

//  Bind with current credentials (login credentials). Be
//  aware that the password itself is never sent over the 
//  network, and encryption is not used.
printf("Binding ...\n");

returnCode = ldap_bind_s(pLdapConnection, NULL, NULL,
                         LDAP_AUTH_NEGOTIATE);
if (returnCode == LDAP_SUCCESS)
    printf("The bind was successful");
else
    goto error_exit;

//  Normal cleanup and exit.
ldap_unbind(pLdapConnection);
return 0;

//  On error cleanup and exit.
error_exit:
    ldap_unbind(pLdapConnection);
    return -1;

我是 Active Directory 的新手,之前从未使用过 Windows 服务器。

  1. 如何在此 LDAP 查询中连接到 Active Directory?我是在代码中的主机名中传递服务器名称还是 Active Directory 域名?

  2. 我还收到服务器名称未解析错误。我应该使用 Windows 服务器或本地 lan 中的 dns 服务来消除错误吗?

这是来自 Microsoft 文档的 link 代码:
here

  1. How do I connect to Active Directory in this LDAP query? Do I pass the server name or the Active Directory domain name in the host name in the code?

根据 code sample shared by you in the question,文档明确指出代码可以通过以下方式执行: (i) 将服务器名称作为命令行参数传递, (ii) 或者在没有参数的情况下执行无服务器绑定尝试。

来自Microsoft DOCS on Serverless Binding and RootDSE

If possible, do not hard-code a server name. Furthermore, under most circumstances, binding should not be unnecessarily tied to a single server. Active Directory Domain Services support serverless binding, which means that Active Directory can be bound to on the default domain without specifying the name of a domain controller. For ordinary applications, this is typically the domain of the logged-on user. For service applications, this is either the domain of the service logon account or that of the client that the service impersonates.

由于您是 Active Directory 的新手,我建议您通过传递您的 AD 域名(例如 domain.local、corp.org 等)来尝试 运行 代码).

  1. Also I am getting a server name not resolved error. Should I use the dns service in Windows server or my local lan in order to get rid of the error?

如果没有更多信息,这将很难回答。默认情况下,名称解析首先由 etc/hosts 文件完成,如果无法通过前者解析,则由 DNS 完成!您应该主要依赖后者,即正确的 DNS 设置。

您需要调查查找您提供的主机名失败的原因。您可以通过在命令提示符下检查命令 nslookup yourADServerHostNamenslookup yourADServerFQDN 的输出来进行简单测试,并检查它是否已解析为预期的 IP 地址。


注意:请确保您在执行代码的系统的网络设置中使用了正确的 DNS 服务器条目。