Enabling LDAPS (i.e LDAPS via SSL/TLS on port 636 or LDAPS via starttls on port 389) on active directory controllers requires a valid certificate to be added to each domain controller. Overall this process is reasonably documented, for example at How to enable LDAP over SSL with a third-party certification authority and Event ID 1220 — LDAP over SSL and LDAP over SSL (LDAPS) Certificate.

So the basic steps are generate a keypair, create a CSR, submit the CSR, obtain a cert and import a certificate into the AD DS personal store. Pretty usual process for certificates.

The missing bit of information is what to do when using OpenSSL to generate the key-pair and CSR. The certificate provided by the CA is likely to be in text .crt/.cer format (i.e. contains —–BEGIN CERTIFICATE—– and —–END CERTIFICATE—–). To import into the AD DS personal store we need to use a .pfx which includes the private key, the certificate and CA cert.

To create a .pfx we can do something like (all on one line…):

openssl pkcs12 -export -out servername.pfx -inkey servername- key.pem -in servername-crt.pem -certfile /path/to/rootCAcertificate.pem

We then transfer the .pfx file to the domain controller in question and follow the above documents’ directions.

I ran into a problem performing memberOf LDAP queries against an Active Directory controller. Turns out that  while almost everyone is able to read most attributes from user objects, by default memberOf is not visible. The result is that queries using memberOf do not return a result. I was frustrated that the queries worked when tested on a domain controller using the LDP.exe utility, when tested as a domain admin. I was focused on getting the LDAP query correct and had not stopped to consider that the LDAP bind account I was using could not read the memberOf attribute.

Anyway, turns out that “Read Member Of” is a property you can assign via the Active Directory Users and Computers MMC. Right click on the top OU from where you want the permission to be granted (this might be the root of the AD tree or a sub-OU) and select “Properties”. Select the “Security” tab and then click “Advanced”. You can now add a permission for the LDAP bind user (or group as needed) using the “Add” button. Select a principal (i.e. user / group as needed), choose “Allow” for the “Type” and then you’ll probably want “Applies to” to be “This object and all descendant objects”. Scroll the bottom of the screen and choose “Clear all” and then find and select the property “Read Member Of”. Save and close the windows and your LDAP bind account should be able to filter based on group membership.

The below is a simple Perl snippet (based on code from http://search.cpan.org/dist/perl-ldap-0.55/lib/Net/LDAP/Examples.pod) to test the LDAP queries.

use Net::LDAP;

$ldap = Net::LDAP->new ( "dc01.example.com" ) or die "$@";
#if you has LDAPS enabled you can use the following instead
#$ldap = Net::LDAP->new ( "ldaps://dc01.example.com" ) or die "$@";
$mesg = $ldap->bind ( "CN=ldapbind,OU=Services,DC=ad,DC=example,DC=com",
 password => "LongSecretPassword",
 version => 3 );

#@Attrs = (); # to request all attributes
 my @Attrs = ( 'cn','mail','givenName','sn','sAMAccountName');
 my $base = "DC=ad,DC=example,DC=com";
 #find members of the group
 #my $filter = "(memberOf=CN=Some-group,OU=Groups,DC=ad,DC=example,DC=com)";
 #find all objects with a sn attribute
 #my $filter = "sn=*";
 #find active users within the specified group
 my $filter = "(&(objectCategory=person)(objectClass=user)(!(userAccountControl:1.2.840.113556.1.4.803:=2))(memberOf=CN=Other-group,OU=Groups,DC=ad,DC=example,DC=com))";
 #my $result = LDAPsearch ( $ldap, $query, \@Attrs );
 my $result = $ldap->search ( base => "$base",
 scope => "sub",
 filter => "$filter",
 attrs => \@Attrs
 );

my @entries = $result->entries;
 my $entr;

foreach $entr ( @entries ) {
 print "DN: ", $entr->dn, "\n";

my $attr;
 foreach $attr ( sort $entr->attributes ) {
 # skip binary we can't handle
 next if ( $attr =~ /;binary$/ );
 print " $attr : ", $entr->get_value ( $attr ) ,"\n";
 }
 print "#-------------------------------\n";
 }

A useful summary of LDAP search options supported by AD servers (incl for disabled accounts and nested-group membership) is in an article titled “Active Directory: LDAP Syntax Filters“.