The Distinguished Name Contains Invalid Syntax
The Distinguished Name Contains Invalid Syntax
I discovered that a Network Monitor trace is your best friend for trying to solve bind problems with the System.DirectoryServices.Protocols.LdapConnection object.
First, some background. I was getting an error trying to connect to a customer’s LDAP directory from a C# console application. I could successfully connect with a freeware client, LDAP Search:
but the C# code failed on the Bind() statement using the exact same values.
// Create the LDAP server (directory) object using FQDN name
port = (port == 0) ? 389 : port; // Assure a good default value
LdapDirectoryIdentifier directory = new LdapDirectoryIdentifier(host, port, true, false);
// Create the LDAP connection object
LdapConnection connection = new LdapConnection(directory);
connection.Timeout = new TimeSpan(0, 0, 10);
connection.Credential = new System.Net.NetworkCredential(loginName, loginPassword);
// Set the LDAP protocol version that the LDAP server is expecting
// Reference: https://msdn.microsoft.com/en-us/library/bb332056.aspx
connection.SessionOptions.ProtocolVersion = 3; // Set protocol to LDAPv3
// Bind to the LDAP server
connection.Bind();
The first step is to install Network Monitor 3.4, available for free download from https://www.microsoft.com/downloads/en/details.aspx?FamilyID=983b941d-06cb-4658-b7f6-3088333d062f&displaylang=en.
Setting up Network Monitor is very simple. Accept defaults for all options. Double click to start the application.
To limit the size of the capture, on the Start Page, change the Network Settings to only capture packets from the LAN connection:
Next, click the New Capture tab. In Visual Studio, step through your application code up to the line where the failure occurs, and then click the Start button in the toolbar.
Back in Visual Studio, step over the line to trigger the error; and then, switch back to Network Monitor and stop the capture. Depending upon the network activity, the capture could be very large, up to thousands of rows. A quick way to get this mass of data down to size is to right click one of the LDAP packet lines, and select Find Conversations > TCP.
Now, only the packets to and from the LDAP server are shown.
It turns out the root cause of the error message was that the LdapConnection object by default tries to use Negotiate authentication. The customer’s LDAP server doesn’t understand NTLM, and replied with an “invalid DN” error, as seen in this trace:
The fix was to explicitly specify the AuthType parameter.
A subsequent error uncovered through the network capture was the LDAP server required LDAP version 3.
The following code now binds without error:
private static void AddGroupMembershipsAsRoles(/*ClaimCollection claims, */ String emailAddress, String host, Int32 port, String loginName, String loginPassword)
{
try
{
// Create the LDAP server (directory) object using FQDN name
LdapDirectoryIdentifier directory = new LdapDirectoryIdentifier(host, port, true, false);
// Create the LDAP connection object
LdapConnection connection = new LdapConnection(directory);
connection.Timeout = new TimeSpan(0, 0, 10);
// LDAP server requires basic authentiction, by default LdapConnection was using NTLM (negotiate)
connection.Credential = new System.Net.NetworkCredential(loginName, loginPassword);
connection.AuthType = AuthType.Basic;
// Set the LDAP protocol version that the LDAP server is expecting
// Reference: https://msdn.microsoft.com/en-us/library/bb332056.aspx
connection.SessionOptions.ProtocolVersion = 3; // Set protocol to LDAPv3
// Bind to the LDAP server
connection.Bind();