ldap_simple_bind_s 返回 LDAP_INVALID_CREDENTIALS
ldap_simple_bind_s returned LDAP_INVALID_CREDENTIALS
我们的应用程序使用 LDAP 进行身份验证。当使用 ldap_bind_s 时,它返回 LDAP_SUCCES 而 ldap_simple_bind_s 返回 LAP_INVALID_CREDENTIALS 并且凭据错误。你能解释一下区别吗,如果使用 ldap_simple_bind_s 是安全的?
这是使用这两种方法的示例应用程序。
#include <iostream>
#include <string>
#include <windows.h>
#include <winldap.h>
#include <boost/lexcal_cast.hpp>
using namespace std;
void test_ldap_bind_s(const std::string& hostname, int port, const std::string& username, const std::string& password)
{
ULONG version = LDAP_VERSION3;
ULONG portNumber = port;
long timeout = 5;
LDAP* ldap = ldap_init(const_cast<PCHAR>(hostname.c_str()), portNumber);
ULONG error_code = LdapGetLastError();
std::string error_str = ldap_err2string(error_code);
if (0x0 == ldap)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_init -> " << error_str << endl;
error_code = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, static_cast<void*>(&version));
error_str = ldap_err2string(error_code);
if (error_code != LDAP_SUCCESS)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_set_option LDAP_VERSION3 -> " << error_str << endl;
l_timeval ldap_connect_timeout;
ldap_connect_timeout.tv_sec = timeout;
ldap_connect_timeout.tv_usec = 0;
error_code = ldap_connect(ldap, &ldap_connect_timeout);
error_str = ldap_err2string(error_code);
if (error_code != LDAP_SUCCESS)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_connect -> " << error_str << endl;
SEC_WINNT_AUTH_IDENTITY secWinntAuthIdentity;
ZeroMemory(static_cast<void*>(&secWinntAuthIdentity), sizeof(SEC_WINNT_AUTH_IDENTITY));
secWinntAuthIdentity.User = reinterpret_cast<unsigned char*>(const_cast<char*>(username.c_str()));
secWinntAuthIdentity.UserLength = username.length();
secWinntAuthIdentity.Password = reinterpret_cast<unsigned char*>(const_cast<char*>(password.c_str()));
secWinntAuthIdentity.PasswordLength = password.length();
secWinntAuthIdentity.Domain = 0;
secWinntAuthIdentity.DomainLength = 0;
secWinntAuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
error_code = ldap_bind_s(ldap, NULL, reinterpret_cast<char*>(&secWinntAuthIdentity), LDAP_AUTH_NEGOTIATE);
error_str = ldap_err2string(error_code);
if (error_code != LDAP_SUCCESS)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_bind_s -> " << error_str << endl << endl;
}
void test_ldap_simple_bind_s(const std::string& hostname, int port, const std::string& username, const std::string& password)
{
ULONG version = LDAP_VERSION3;
ULONG portNumber = port;
long timeout = 5;
LDAP* ldap = ldap_init(const_cast<PCHAR>(hostname.c_str()), portNumber);
ULONG error_code = LdapGetLastError();
std::string error_str = ldap_err2string(error_code);
if (0x0 == ldap)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_init -> " << error_str << endl;
error_code = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, static_cast<void*>(&version));
error_str = ldap_err2string(error_code);
if (error_code != LDAP_SUCCESS)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_set_option LDAP_VERSION3 -> " << error_str << endl;
l_timeval ldap_connect_timeout;
ldap_connect_timeout.tv_sec = timeout;
ldap_connect_timeout.tv_usec = 0;
error_code = ldap_connect(ldap, &ldap_connect_timeout);
error_str = ldap_err2string(error_code);
if (error_code != LDAP_SUCCESS)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_connect -> " << error_str << endl;
error_code = ldap_simple_bind_s(ldap, const_cast<PCHAR>(username.c_str()), const_cast<PCHAR>(password.c_str()));
error_str = ldap_err2string(error_code);
if (error_code != LDAP_SUCCESS)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_bind_s -> " << error_str << endl << endl;
}
int main(int argc, char* argv[])
{
string username = argv[1];
string password = argv[2];
string hostname = argv[3];
int port = boost::lexical_cast<int>(argv[4]);
test_ldap_bind_s(hostname, port, username, password);
test_ldap_simple_bind_s(hostname, port, username, password);
}
ldap_simple_bind_s 凭据不是用户名、密码而是 DN、密码。
您需要从 LDAP 检索 DN,或从用户名构建它(假设 DN 都是相同构建的)。
我们的应用程序使用 LDAP 进行身份验证。当使用 ldap_bind_s 时,它返回 LDAP_SUCCES 而 ldap_simple_bind_s 返回 LAP_INVALID_CREDENTIALS 并且凭据错误。你能解释一下区别吗,如果使用 ldap_simple_bind_s 是安全的?
这是使用这两种方法的示例应用程序。
#include <iostream>
#include <string>
#include <windows.h>
#include <winldap.h>
#include <boost/lexcal_cast.hpp>
using namespace std;
void test_ldap_bind_s(const std::string& hostname, int port, const std::string& username, const std::string& password)
{
ULONG version = LDAP_VERSION3;
ULONG portNumber = port;
long timeout = 5;
LDAP* ldap = ldap_init(const_cast<PCHAR>(hostname.c_str()), portNumber);
ULONG error_code = LdapGetLastError();
std::string error_str = ldap_err2string(error_code);
if (0x0 == ldap)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_init -> " << error_str << endl;
error_code = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, static_cast<void*>(&version));
error_str = ldap_err2string(error_code);
if (error_code != LDAP_SUCCESS)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_set_option LDAP_VERSION3 -> " << error_str << endl;
l_timeval ldap_connect_timeout;
ldap_connect_timeout.tv_sec = timeout;
ldap_connect_timeout.tv_usec = 0;
error_code = ldap_connect(ldap, &ldap_connect_timeout);
error_str = ldap_err2string(error_code);
if (error_code != LDAP_SUCCESS)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_connect -> " << error_str << endl;
SEC_WINNT_AUTH_IDENTITY secWinntAuthIdentity;
ZeroMemory(static_cast<void*>(&secWinntAuthIdentity), sizeof(SEC_WINNT_AUTH_IDENTITY));
secWinntAuthIdentity.User = reinterpret_cast<unsigned char*>(const_cast<char*>(username.c_str()));
secWinntAuthIdentity.UserLength = username.length();
secWinntAuthIdentity.Password = reinterpret_cast<unsigned char*>(const_cast<char*>(password.c_str()));
secWinntAuthIdentity.PasswordLength = password.length();
secWinntAuthIdentity.Domain = 0;
secWinntAuthIdentity.DomainLength = 0;
secWinntAuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
error_code = ldap_bind_s(ldap, NULL, reinterpret_cast<char*>(&secWinntAuthIdentity), LDAP_AUTH_NEGOTIATE);
error_str = ldap_err2string(error_code);
if (error_code != LDAP_SUCCESS)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_bind_s -> " << error_str << endl << endl;
}
void test_ldap_simple_bind_s(const std::string& hostname, int port, const std::string& username, const std::string& password)
{
ULONG version = LDAP_VERSION3;
ULONG portNumber = port;
long timeout = 5;
LDAP* ldap = ldap_init(const_cast<PCHAR>(hostname.c_str()), portNumber);
ULONG error_code = LdapGetLastError();
std::string error_str = ldap_err2string(error_code);
if (0x0 == ldap)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_init -> " << error_str << endl;
error_code = ldap_set_option(ldap, LDAP_OPT_PROTOCOL_VERSION, static_cast<void*>(&version));
error_str = ldap_err2string(error_code);
if (error_code != LDAP_SUCCESS)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_set_option LDAP_VERSION3 -> " << error_str << endl;
l_timeval ldap_connect_timeout;
ldap_connect_timeout.tv_sec = timeout;
ldap_connect_timeout.tv_usec = 0;
error_code = ldap_connect(ldap, &ldap_connect_timeout);
error_str = ldap_err2string(error_code);
if (error_code != LDAP_SUCCESS)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_connect -> " << error_str << endl;
error_code = ldap_simple_bind_s(ldap, const_cast<PCHAR>(username.c_str()), const_cast<PCHAR>(password.c_str()));
error_str = ldap_err2string(error_code);
if (error_code != LDAP_SUCCESS)
{
cout << error_code << ": " << error_str << endl << endl;
return;
}
cout << "ldap_bind_s -> " << error_str << endl << endl;
}
int main(int argc, char* argv[])
{
string username = argv[1];
string password = argv[2];
string hostname = argv[3];
int port = boost::lexical_cast<int>(argv[4]);
test_ldap_bind_s(hostname, port, username, password);
test_ldap_simple_bind_s(hostname, port, username, password);
}
ldap_simple_bind_s 凭据不是用户名、密码而是 DN、密码。 您需要从 LDAP 检索 DN,或从用户名构建它(假设 DN 都是相同构建的)。