如何用C++通过LDAP连接Windows Server 2019 Active Directory?
关于LDAP连接AD的两个疑问解答
嘿,作为常跟AD和LDAP打交道的人,我来帮你把这两个问题理清楚:
一、hostname参数该传服务器名称还是AD域名?
其实这两种输入都支持,但各有适用场景:
- 如果传入Windows Server的服务器名称(比如
DC01),ldap_init会直接尝试连接这台特定的域控制器。好处是目标明确,适合测试阶段;但缺点是如果这台DC故障,连接就会直接失败,没有冗余能力。 - 如果传入Active Directory的域名(比如
contoso.com),ldap_init会通过DNS自动查找域内可用的域控制器,选一台正常运行的DC建立连接。这种方式更适合生产环境,自带故障转移,可靠性更高。
你的代码里用的ldap_init对两种格式都兼容,具体选哪个看你的需求——测试用服务器名没问题,正式环境建议用域名。
二、服务器名称无法解析的问题,是否需要Windows Server的DNS服务?
必须要! Active Directory本身就高度依赖DNS来实现域控制器定位、名称解析等核心功能。你遇到的解析错误,本质就是客户端没法通过DNS找到目标服务器的IP地址。
解决思路大概是这样:
- 确认你的Windows Server 2019已经安装并配置了AD集成DNS(一般部署AD时会自动安装,可通过服务器管理器检查角色);
- 把Windows客户端的DNS服务器地址设置为这台AD服务器的IP(别用公共DNS,比如8.8.8.8,否则解析不了AD内部的服务器名或域名);
- 可以在客户端用
nslookup 服务器名称或nslookup AD域名测试,看能不能正常返回IP,验证解析是否正常。
附你提供的C++代码
// 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;
内容的提问来源于stack exchange,提问作者sham
相关产品推荐
相关产品推荐

