ldap_simple_bind_s返回LDAP_INVALID_CREDENTIALS

时间:2016-01-10 19:52:48

标签: c++ ldap

我们的应用程序使用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);
}

1 个答案:

答案 0 :(得分:0)

ldap_simple_bind_s凭据不是用户名,密码而是DN,密码。 您需要从LDAP检索DN,或者从用户名构建它(假设DN都是相同构建的)。