Active Directory Authentication with C ++ on Linux

I am surprised that there are few such examples. I basically need to do user / password authentication in Active Directory. I can initialize the connection to the active directory, but it always gives me the error "Invalid credentials". I wonder if I will give him something wrong. This is my first attempt with LDAP. In this regard, I am open to another (well-documented) solution.

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

EDIT:

I wanted to make sure that everything was fine on the server side, so some tests with ldapsearch. It didn't work at first, but I finally got it (with ldapsearch, anyway).

 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" 

This may not be the best way. To begin with, the key is the -D argument and passes the name sAMAccountName at the end. I will not have a common name - only the Windows login and password. The above command will show the user their information if the password passes.

The caveat (I think) is that ldap_sasl_bind_s () does not have the equivalent of setting -D (binddn). Looking at this question / answer , it looks like ldap_interactive_bind_s () can, but it is a bit more active since I need to pass a callback.

In the above example, where I set the password, but does not have the name binddn / username of any type, who does this suggest, I'm trying to authenticate like?

+5
source share
1 answer

SamAccountName = MYDOMAIN \ UserName, dc = MYDOMAIN, DC = local

This username format is incorrect. You do not need to specify sAMAccountName in your username and you do not need to specify dc if you are not using Distinguished Name . You have few username options.

  • Great name

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

  1. sAMaccountName

Jsmith

  1. User path from previous version of Windows

"Fabrikam \ jeffsmith".

  1. Username (UPN)

jeffsmith@Fabrikam.com

Having said that, I’m not sure that the username is the only problem you have encountered. I do not run your code locally.

Although this answer cannot directly answer your question, since I have not tested this code on a Linux machine, it can give you an idea or put you in the right direction. I would not be surprised if this method is only for Windows.

According to MSDN, there are several methods that you can use to authenticate a user.

The ADsOpenObject function is bound to an ADSI object using explicit username and password credentials.

This method takes the following parameters:

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

Using this method, you can bind to an object in Active Directory by specifying username and password .

If the binding is successful, the return code is S_OK , otherwise you will receive different error messages.

I do not write programs in C++ on a daily basis. I usually work with Active Directory and Active Directory Lightweight Services in the C# world. But this sample code that I wrote shows you how to call the ADsOpenObject method to bind to an ADSI object using the specified credentials. In your case, just 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; } 

Depending on your setup, you may need to configure ADS_AUTHENTICATION_ENUM . I suggest installing an SSL certificate and using the ADS_USE_SSL binding. Working with non-SSL passwords in AD can be a nightmare.

+2
source

All Articles