在Linux上使用C ++对Active Directory进行身份验证

时间:2015-07-29 15:14:21

标签: c++ linux active-directory kerberos

我很惊讶那里的例子很少。我基本上需要针对Active Directory进行用户/通过身份验证。我能够初始化到活动目录的连接,但它总是给我一个“无效的凭据”错误。我想知道我是不是错了。这是我第一次使用LDAP。就此而言,我对另一个(也许有很多文件记录)解决方案持开放态度。

#include <iostream>
#include <stdio.h>

#define LDAP_SERVER "ldap://hq.mydomain.local/"

#include <ldap.h>

int main( int argc, char** argv )
{
    LDAP    *ld;
    int     version( LDAP_VERSION3 );
    int     rc;
    char    bind_dn[100];
    berval  creds;
    berval* serverCreds;

    if( ldap_initialize( &ld, LDAP_SERVER ) ) {
        std::cerr << "Error initializing ldap..." << std::endl;
        return 1;
    }

    ldap_set_option( ld, LDAP_OPT_PROTOCOL_VERSION, &version );

    creds.bv_val = "password";
    creds.bv_len = strlen("password");

    rc = ldap_sasl_bind_s( ld, "sAMAccountName=MYDOMAIN\\UserName,dc=mydomain,dc=local", "GSSAPI", &creds, NULL, NULL, &serverCreds );

    if ( rc != LDAP_SUCCESS ) {
        std::cerr << "ERROR: " << ldap_err2string( rc ) << std::endl; 
        return 1;
    } else {
        std::cout << "Success." << std::endl;
    }

    return 0;

}

编辑:

我想确保服务器端的一切正常,所以使用ldapsearch进行了一些测试。它最初没有用,但我终于得到了它(无论如何都是ldapsearch)。

ldapsearch -D first.last@mydomain.local -H "ldap://hq.mydomain.local:389" -b "ou=Development,ou=Domain Users,dc=mydomain,dc=local" -W "sAMAccountName=first.last"

也许不是最好的方式。对于初学者,键是-D参数,并在结尾传递sAMAccountName。我不会有通用名称 - 只有Windows登录名和密码。如果密码通过,上面的命令将向用户显示他的信息。

警告(我认为)是ldap_sasl_bind_s()没有相当于设置-D(binddn)标志。看看this question/answer它看起来像ldap_interactive_bind_s(),但它更复杂一些,因为我必须传回一个回电。

上面的示例中我设置了密码,但没有任何类型的binddn / username,是谁假设我正在尝试进行身份验证?

1 个答案:

答案 0 :(得分:2)

  

sAMAccountName赋= MYDOMAIN \用户名,DC = MYDOMAIN,DC =本地

此用户名格式不正确。您无需在用户名中指定sAMAccountName,也无需指定dc,除非您使用Distinguished Name。用户名很少。

  1. 尊敬的名字
  2.   

    CN = Jeff Smith,OU = Sales,DC = Fabrikam,DC = Com

    1. sAMaccountName
    2.   

      jsmith的

      1. 以前版本的Windows的用户路径
      2.   

        &#34;的Fabrikam \ jeffsmith&#34;

        1. 用户主要姓名(UPN)
        2.   

          jeffsmith@Fabrikam.com

          话虽如此,我不确定用户名是否是您遇到的唯一问题。我没有在本地运行你的代码。

          虽然这个答案可能无法直接回答你的问题,但由于我没有在Linux机器上测试过这段代码,它可以给你一个想法或让你朝着正确的方向前进。 如果此方法仅限于Windows,我不会感到惊讶。

          根据MSDN,您可以使用少量methods来验证用户身份。

            

          ADsOpenObject函数使用显式用户名和密码凭据绑定到ADSI对象。

          此方法接受以下参数:

          HRESULT ADsOpenObject(
            _In_  LPCWSTR lpszPathName,
            _In_  LPCWSTR lpszUserName,
            _In_  LPCWSTR lpszPassword,
            _In_  DWORD   dwReserved,
            _In_  REFIID  riid,
            _Out_ VOID    **ppObject
          );
          

          使用此方法,您可以通过指定usernamepassword绑定到Active Directory中的对象。

          如果绑定成功,则返回代码为S_OK,否则您将收到不同的错误消息。

          我不会每天在C++编写程序。我通常在Active Directory世界中使用Active Directory Lightweight ServicesC#。但是我编写的示例代码向您展示了如何使用指定的凭据调用ADsOpenObject方法绑定到ADSI对象。在您的情况下,只需authenticate

          #include <iostream>
          #include "activeds.h"
          
          using namespace std;
          
          int main(int argc, char* argv[])
          {
             HRESULT hr;
             IADsContainer *pCont;
             IDispatch *pDisp = NULL;
             IADs *pUser;
          
             CoInitialize(NULL);
          
             hr = ADsOpenObject( L"LDAP://yourserver",
                         L"username",
                         L"password",
                         ADS_FAST_BIND, //authentication option     
                         IID_IADs,
                         (void**) &pUser);
          
          
             if (SUCCEEDED(hr))
             {
                cout << "Successfully authenticated";
             }
             else
                cout << "Incorrect username or password";
             return hr;
          }
          

          根据您的设置,您可能需要调整ADS_AUTHENTICATION_ENUM。我建议您安装 SSL证书并使用ADS_USE_SSL绑定。在AD中处理没有SSL的密码可能是噩梦。

相关问题