top of page

AD LDS and LDAPS

10 minutes ago
8 min read

How to Install and Secure an LDAP Server on Windows Server Using AD LDS and LDAPS

LDAP authentication is a common component of enterprise infrastructure. Many applications rely on directory services to identify users, validate credentials, and manage access.

But what happens when you need LDAP authentication without deploying a complete Active Directory domain?

Microsoft Active Directory Lightweight Directory Services (AD LDS) provides an alternative.

In this lab, we'll install AD LDS on Windows Server, configure an independent directory, create a test user, enable encrypted LDAP communication, and validate the environment using native Windows administration tools.

We'll also cover several real troubleshooting scenarios, including certificate trust issues, failed password operations, invalid credentials, and applications that successfully connect to LDAP but cannot discover users.


1. Understanding LDAP, AD LDS, and LDAPS

LDAP (Lightweight Directory Access Protocol) is a protocol for accessing and managing directory information.

AD LDS (Active Directory Lightweight Directory Services) is Microsoft's LDAP-compatible directory service that does not require an Active Directory Domain Services domain controller.

LDAPS (LDAP over TLS) protects LDAP communication by establishing an encrypted TLS connection before LDAP messages are exchanged.

Technology

Purpose

LDAP

Directory queries and authentication operations

AD LDS

Independent directory service for applications

LDAPS

Encrypted LDAP communication

TLS certificate

Establishes server identity and supports encryption

Trusted Root CA

Establishes trust in the certificate issuer

LDP.exe

Tests LDAP connectivity, binds, and searches

ADSI Edit

Manages directory objects and attributes

Lab architecture
Windows Server: LDAP-SRV01
          |
          +-- AD LDS Instance: LABLDAP
          |       |
          |       +-- LDAP  TCP/389
          |       +-- LDAPS TCP/636
          |       |
          |       +-- DC=lab,DC=local
          |              |
          |              +-- OU=Users
          |              |     |
          |              |     +-- CN=ldaptest
          |              |
          |              +-- CN=Roles
          |
          +-- TLS Server Certificate
          |
          +-- Trusted Root CA
          |
          +-- PowerShell / LDP.exe / ADSI Edit
          |
          +-- Enterprise Application

The names and addresses used throughout this article are examples and should be replaced with values appropriate for your environment.


2. Windows Server Requirements and Licensing

Before installing AD LDS, make sure Windows Server is properly licensed.

AD LDS is available as a Windows Server role, so a separate AD LDS product license is not normally purchased just to install the role. However, the underlying Windows Server deployment must be appropriately licensed.

Important licensing considerations:

  • Windows Server Standard or Datacenter: The server or virtual machine requires appropriate Windows Server licensing.

  • Client Access Licenses (CALs): Users or devices accessing Windows Server functionality may require Windows Server CALs, depending on the licensing terms and applicable exceptions.

  • External Connector: May be an alternative for qualifying external-user access.

  • Remote Desktop Services: Additional RDS licensing may be required for qualifying remote desktop access.

  • Evaluation editions: Suitable for permitted testing and evaluation, but not a substitute for production licensing.


Licensing requirements depend on the Windows Server version, virtualization model, access patterns, and Microsoft Product Terms.


3. Installing AD LDS with PowerShell

Open Windows PowerShell as Administrator.

Check whether AD LDS is already installed:

Get-WindowsFeature ADLDS

Install the role and management tools:

Install-WindowsFeature ADLDS -IncludeManagementTools

Verify installation:

Get-WindowsFeature ADLDS

Expected installation state:

Install State
-------------
Installed

Launch the AD LDS installation wizard:

& "$env:SystemRoot\ADAM\adaminstall.exe"

Select a unique instance and configure the following lab settings:

Instance Name: LABLDAP

LDAP Port: 389
LDAPS Port: 636

Application Partition:
DC=lab,DC=local

Choose the service account, instance administrators, and required LDIF schema files during installation.

AD LDS can operate without a traditional AD DS domain. For a standalone lab, the service identity and administrator permissions must still be configured correctly.


Verify the service
Get-Service ADAM_*

Expected example:

Status    Name
------    ----
Running   ADAM_LABLDAP

If required:

Start-Service ADAM_LABLDAP

Or restart:

Restart-Service ADAM_LABLDAP

4. Creating a TLS Certificate for LDAPS

LDAP on TCP/389 does not inherently encrypt communication. To protect authentication traffic, we'll configure LDAPS on TCP/636.

For a standalone lab, we can generate a self-signed server certificate.

Use a resolvable hostname that matches the certificate:

$dnsName = "ldap-srv01.lab.example"

Create the certificate:

$cert = New-SelfSignedCertificate `
  -DnsName $dnsName `
  -CertStoreLocation "Cert:\LocalMachine\My" `
  -KeyAlgorithm RSA `
  -KeyLength 2048 `
  -HashAlgorithm SHA256 `
  -KeyExportPolicy NonExportable `
  -KeyUsage DigitalSignature,KeyEncipherment `
  -Type SSLServerAuthentication `
  -NotAfter (Get-Date).AddYears(2)

This example creates a laboratory server certificate. Production environments should use an appropriately managed certificate issued by a trusted CA.


Verify the certificate
Get-ChildItem Cert:\LocalMachine\My |
Select-Object Subject,Issuer,NotAfter,Thumbprint,HasPrivateKey

Verify that:

  • The certificate is valid.

  • Its DNS name matches the LDAP endpoint.

  • Server Authentication is included in Enhanced Key Usage.

  • The private key exists.

  • The AD LDS service can access the private key.


AD LDS can use a certificate from the Local Computer Personal store or the appropriate AD LDS instance service Personal store, depending on configuration.


5. Importing the Certificate into Trusted Root Certification Authorities

This was one of the important steps in our lab.

Creating a certificate does not automatically mean that LDAP clients will trust it.

For a self-signed certificate, the certificate acts as its own issuer. In a controlled lab, we can explicitly trust it.

First, export the public certificate:

New-Item -ItemType Directory `
  -Path "C:\LDAPLab" `
  -Force

Export-Certificate `
  -Cert $cert `
  -FilePath "C:\LDAPLab\ldap-server.cer"

Import the public certificate into Trusted Root:

Import-Certificate `
  -FilePath "C:\LDAPLab\ldap-server.cer" `
  -CertStoreLocation "Cert:\LocalMachine\Root"

This trusts the self-signed certificate on that computer.

For certificates issued by an internal CA, import the root CA certificate, not the individual server certificate, into Trusted Root. Intermediate CA certificates belong in the appropriate Intermediate Certification Authorities store.


Verify with the Windows Certificate Manager

Open:

certlm.msc

Navigate to:

Certificates - Local Computer
    |
    +-- Personal
    |     |
    |     +-- Certificates
    |
    +-- Trusted Root Certification Authorities
          |
          +-- Certificates

The server certificate and its private key must be available to the AD LDS service.

The trusted root establishes the trust chain. These are separate requirements.


Verify using CertUtil

Inspect the Personal certificate store:

certutil -store My

Inspect the Trusted Root store:

certutil -store Root

Check the certificate file:

certutil -dump "C:\LDAPLab\ldap-server.cer"

Security tip: Never import an unknown certificate into Trusted Root. Trusting a certificate authority or self-signed certificate can affect which identities the computer accepts as trusted.

For production deployments, distribute trusted CA certificates through an approved certificate management process.


6. Restart AD LDS and Validate LDAPS

After configuring the certificate, restart the instance:

Restart-Service ADAM_LABLDAP

Check whether the LDAPS port is listening:

Get-NetTCPConnection -State Listen |
Where-Object LocalPort -eq 636

Expected example:

LocalAddress  LocalPort  State
------------  ---------  ------
0.0.0.0       636        Listen

Identify the owning process:

Get-NetTCPConnection -LocalPort 636 -State Listen |
Select-Object LocalAddress,LocalPort,OwningProcess

Test network connectivity:

Test-NetConnection ldap-srv01.lab.example -Port 636

Expected:

TcpTestSucceeded : True

Remember that an open TCP port proves connectivity, not successful TLS certificate validation or LDAP authentication.


7. Creating LDAP Users with ADSI Edit

Launch ADSI Edit:

adsiedit.msc

Connect to the AD LDS instance:

Server:
LDAP-SRV01:389

Naming Context:
DC=lab,DC=local

Create an organizational unit:

OU=Users,DC=lab,DC=local

Inside it, create a user object:

CN=ldaptest,OU=Users,DC=lab,DC=local

The required object classes and available attributes depend on the schema imported into the AD LDS instance.


Configure the user's password

For password operations, use an authenticated secure connection and an account with appropriate permissions.

In ADSI Edit:

  1. Locate the user.

  2. Right-click and select Reset Password.

  3. Enter a password meeting the applicable policy.

  4. Confirm the operation.

  5. Check the user's account status.

Inspect:

msDS-UserAccountDisabled

For an enabled AD LDS user, the expected value is:

FALSE

Do not confuse an AD LDS user with a traditional Windows domain user. The available attributes and authentication behavior can differ.


8. Testing LDAPS Authentication with LDP.exe

LDP.exe is one of the most useful built-in tools for troubleshooting LDAP.

Launch:

ldp.exe

Navigate to:

Connection > Connect

Configure:

Server: ldap-srv01.lab.example
Port: 636
SSL: Enabled

A successful connection should display RootDSE information.

Next:

Connection > Bind

Choose Simple Bind and enter:

User:
CN=ldaptest,OU=Users,DC=lab,DC=local

Password:
Your test account password

A successful bind confirms that the directory accepted the supplied credentials.


Search for directory objects

Navigate to:

Browse > Search

Configure:

Base DN:
DC=lab,DC=local

Filter:
(objectClass=*)

Scope:
Subtree

Click Run.

To find the test user:

Base DN:
OU=Users,DC=lab,DC=local

Filter:
(cn=ldaptest)

Scope:
Subtree

The search should return matching objects that the authenticated account has permission to read.


9. Testing LDAPS Authentication with PowerShell

PowerShell provides an independent way to validate LDAP authentication without relying on an enterprise application's interface.

Add-Type -AssemblyName System.DirectoryServices.Protocols

$server = "ldap-srv01.lab.example"
$port = 636

$dn = "CN=ldaptest,OU=Users,DC=lab,DC=local"

$credential = Get-Credential -UserName $dn

$identifier = [System.DirectoryServices.Protocols.LdapDirectoryIdentifier]::new(
    $server,
    $port
)

$connection = [System.DirectoryServices.Protocols.LdapConnection]::new(
    $identifier
)

$connection.AuthType = [System.DirectoryServices.Protocols.AuthType]::Basic
$connection.SessionOptions.ProtocolVersion = 3
$connection.SessionOptions.SecureSocketLayer = $true

try {
    $connection.Bind($credential.GetNetworkCredential())
    Write-Host "LDAPS authentication successful"
}
catch {
    Write-Host "LDAPS authentication failed"
    Write-Host $_.Exception.Message
}
finally {
    $connection.Dispose()
}

This test preserves normal certificate validation and avoids placing the password directly in the script.


10. Troubleshooting Real LDAP Problems

Problem: LDAPS is not listening on TCP/636

Check the service:

Get-Service ADAM_LABLDAP

Inspect certificates:

Get-ChildItem Cert:\LocalMachine\My

Review the directory service event log:

Get-WinEvent -LogName "ADAM (LABLDAP)" -MaxEvents 10 |
Select-Object Id,LevelDisplayName,Message

Check certificate validity, private key permissions, service configuration, and whether another application is using the port.


Problem: LDAP error 49 — Invalid Credentials

Example:

ldap_simple_bind_s() failed:
Invalid Credentials

LDAP Error 49

Check:

  • User distinguished name

  • Password

  • Account enabled status

  • Password policy

  • Bind mechanism

  • Directory service authentication restrictions

For Microsoft directory implementations, additional diagnostic data may help identify account restrictions.


Problem: Password reset returns a constraint violation

Example:

A constraint violation occurred.

Possible causes include password policy violations, unsupported operations, incorrect permissions, or directory configuration problems.

Verify the password policy and perform the operation over a secure connection.

Do not disable password security requirements merely to bypass the error.


Problem: LDAP Bind succeeds, but application login fails

This was an important troubleshooting scenario in the lab.

We successfully established encrypted LDAP connectivity and authenticated a directory user through LDP.exe.

However, the enterprise application could verify its LDAP connection while still failing to discover or authenticate the user at the application level.

This demonstrates that several different stages are involved:

TCP Connectivity
       |
       v
TLS Negotiation
       |
       v
LDAP Bind
       |
       v
Directory Search
       |
       v
Attribute Mapping
       |
       v
Application Authorization
       |
       v
Application Login

Each stage must be validated independently.


Problem: Application cannot discover LDAP users

Check the search base:

DC=lab,DC=local

Check the LDAP filter:

(objectClass=user)

Verify that the user can be found using LDP.exe.

Applications designed for traditional AD DS may depend on attributes such as:

sAMAccountName
userPrincipalName
displayName
mail
memberOf

AD LDS may not provide the same attributes or semantics without additional schema configuration.

The application's supported directory types and attribute mapping requirements should be checked before modifying the AD LDS schema.


Problem: TLS certificate is not trusted

Inspect the certificate stores:

certutil -store My
certutil -store Root

Confirm that the server certificate has the correct DNS identity and that its issuing CA is trusted by the LDAP client.

Also verify that the certificate is not expired and that the service can access the corresponding private key.

Never bypass certificate validation as a permanent troubleshooting workaround.


Troubleshooting LDAP Error 49 (Data 533) – Enabling an AD LDS User Account

During LDAP authentication testing, the user account failed to authenticate even after successfully resetting its password through ADSI Edit.

LDP.exe returned the following error:

ldap_simple_bind_s() failed: 49
Invalid Credentials
LDAP Error 49
Data 533

The diagnostic code 533 indicates that the user account is disabled.

How to fix it:

  1. Open ADSI Edit using adsiedit.msc.

  2. Connect to the AD LDS instance.

  3. Navigate to the user account, for example:

CN=ldaptest,OU=Users,DC=lab,DC=local
  1. Right-click the user and select Properties.

  2. Locate the attribute msDS-UserAccountDisabled.

  3. Change its value from:

TRUE → FALSE
  1. Click OK, then Apply to save the changes.

Understanding the attribute:

Value

Description

TRUE

User account is disabled; authentication is blocked.

FALSE

User account is enabled; authentication is permitted if credentials and other requirements are valid.

Validation

After enabling the account, reconnect using LDP.exe over LDAPS (TCP 636) and perform a Simple Bind with the user's distinguished name and password.

Expected result:

Authenticated as:
CN=ldaptest,OU=Users,DC=lab,DC=local

Security Tip: Resetting a user's password does not automatically enable a disabled AD LDS account. Always verify msDS-UserAccountDisabled when troubleshooting LDAP Error 49 with diagnostic code 533. Enable only authorized accounts with appropriate permissions.


11. Windows Firewall and Network Security

LDAPS should only be accessible from authorized clients.

For a controlled lab, a restricted firewall rule can be created:

New-NetFirewallRule `
  -DisplayName "LDAPS - Authorized Clients" `
  -Direction Inbound `
  -Protocol TCP `
  -LocalPort 636 `
  -RemoteAddress 192.0.2.0/24 `
  -Action Allow

The example network is a documentation address range. Replace it with the actual authorized client subnet.

Also ensure broader firewall rules do not unintentionally permit unrestricted access.

Avoid exposing LDAP or LDAPS directly to the public internet.


12. Security Recommendations

For production deployments, consider:

  • TLS certificates issued by a trusted internal or public CA.

  • Certificate expiration monitoring and renewal procedures.

  • Restricted access to LDAP ports.

  • Dedicated service accounts with least-privilege permissions.

  • Centralized authentication event monitoring.

  • Secure handling of credentials.

  • Regular Windows Server security updates.

  • Documented certificate trust and revocation procedures.

  • Application-specific LDAP schema compatibility testing.


AD LDS should also be monitored for configuration changes, unauthorized directory modifications, and unexpected authentication activity.



Recent Posts

See All
Notepad's Hidden Gem

Most people think of Notepad as just a simple text editor. You open it, type your notes, and close it. Nothing fancy, right? Well......

 
 
 
Try macOS on Windows

In this post, I will show you how to install macOS on Windows using VirtualBox hypervisor. #1) You need to install Microsoft Visual C++...

 
 
 

Comments


STENGE.info | Built with curiosity. Secured by knowledge.

bottom of page