2016-01-10 44 views
0

我們的應用程序使用LDAP進行身份驗證。當使用ldap_bind_s時,它返回LDAP_SUCCES,而ldap_simple_bind_s返回具有錯誤憑證的LAP_INVALID_CREDENTIALS。你能解釋一下這個區別嗎,如果使用ldap_simple_bind_s是安全的?ldap_simple_bind_s返回LDAP_INVALID_CREDENTIALS

下面是使用這兩種方法的示例應用程序。

#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); 
} 

回答

0

ldap_simple_bind_s憑證不是用戶名,密碼而是DN,密碼。 您需要從LDAP中檢索DN,或者從用戶名構建DN(假設所有DN都是相同構建的)。