Are you a world traveler? ZoneTick is a cool utility that'll help you stay in touch over multiple time zones!
 
LDAP Security  
Nik Okuntseff  Windows 2000 Security Programming 

LDAP Security

This section describes how to use LDAP on Microsoft platforms with different security credentials. LDAP servers may use various client authentication mechanism. For example, Exchange 5.5 provides the following authentication methods for LDAP protocol (see Figure below).


Exchange 5.5 LDAP protocol authentication choices.

The topic of this section is how one would programmatically use different security contexts for LDAP queries. Here is how to do it in Visual Basic.

Private Sub Bind_Click()
  Dim strUser As String
  Dim strPassword As String
  Dim strServer As String
  Dim strPort As String
  Dim strObjectDN As String
  
  strUser = Account.Text
  strPassword = Password.Text
  strServer = Server.Text
  strPort = Port.Text
  strObjectDN = ObjectDN.Text
    
  Dim dso As IADsOpenDSObject
  Set dso = GetObject("LDAP:")
  
  Dim strPath As String
  strPath = "LDAP://" & strServer & ":" & strPort & "/" & strObjectDN
  
  Dim objTop As IADs
  Set objTop = dso.OpenDSObject(strPath, strUser, strPassword, ADS_SECURE_AUTHENTICATION)
  
  'Use the object, display something.
  MsgBox objTop.Class
    
  Set objTop = Nothing
  Set dso = Nothing
End Sub

My sample application with this code is located in App/VbLdapSecurity directory. Here is its dialog screen. Notice that LDAP port number my be selected as well, different from the default 389. The strPath parameter for the default values shown on the Figure would look like LDAP://Tazdevil:389/o=Infowave. Notice how the port is used in this string.


VbLdapSecurity application.

This is possible with C/C++ as well. Here is how you can do it by using Windows LDAP API. The sample is named (App/LdapBind).

#include <stdio.h>
#include <rpc.h>
#include <winldap.h>

int main()
{
  // Change as necessary.
  char * pszServer = "tazdevil";
  char * pszUser = "user";
  char * pszPassword = "password";
  char * pszDomain = "infowave";

  // Open LDAP connection.
  LDAP * pld = NULL;
  pld = ldap_open(pszServer, 389);
  if (!pld) return -1;

  // Prepare credentials.
  SEC_WINNT_AUTH_IDENTITY cred;
  cred.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
  cred.User = (unsigned char *) pszUser;
  cred.UserLength = strlen(pszUser);
  cred.Password = (unsigned char *) pszPassword;
  cred.PasswordLength = strlen(pszPassword);
  cred.Domain = (unsigned char *) pszDomain;
  cred.DomainLength = strlen(pszDomain);

  // Bind with negotiated authentication.
  ULONG ul = ldap_bind_s(pld,
	  NULL,
	  (char *) &cred,
	  LDAP_AUTH_NEGOTIATE);
  if (S_OK != ul)
    printf("Failed to bind to LDAP server. Error: %d\n", LdapGetLastError());
  else
    printf("Successful LDAP connection to: %s", pszServer);
  
  // Unbind.
  ul = ldap_unbind_s(pld);
  return 0;
}

The sample above uses Windows LDAP API (functions ldap_open, ldap_bind_s, and ldap_unbind_s). Alternatively, you can use ADSI with C++ as shown below. This sample is called App/AdsiBind.

#include <stdio.h>
#include <iads.h>
#include <adshlp.h>

int main()
{
  HRESULT hr;
  IADsOpenDSObject * pDSO;

  hr = ::CoInitialize(NULL);
  if (FAILED(hr)) return hr;

  hr = ADsGetObject(L"LDAP:", IID_IADsOpenDSObject, (void **) &pDSO);
  if (FAILED(hr)) return hr;

  LPDISPATCH pDisp = NULL;
  
  // Change prameters as necessary here. For example, if server name is tazdevil, organization DN is o=infowave,
  // user name niko and password xaxaxa the line becomes.
  // hr = pDSO->OpenDSObject(L"LDAP://tazdevil/o=infowave", L"niko", L"xaxaxa", ADS_SECURE_AUTHENTICATION, &pDisp);
  hr = pDSO->OpenDSObject(L"LDAP://server/o=orgname", L"username", L"password", ADS_SECURE_AUTHENTICATION, &pDisp);
  pDSO->Release();
  
  // If authentication fails, it happens here.
  if (FAILED(hr))
  {
    printf("Failed to bind to the object. Error: 0x%08X\n", hr);	  
    return hr;
  }

  printf("Bind successful!\n");

  IADs * pADs;
  hr = pDisp->QueryInterface(IID_IADs, (void **) &pADs);
  pDisp->Release();

  if (FAILED(hr)) return hr;

  // Use pADs here.
  pADs->Release();

  CoUninitialize();
  return 0;
}

 
[ Contents | Home ]

Send comments and suggestions to niko@wrconsulting.com
Copyright © 2000 by Nik Okuntseff