I'm seeing an initial delay of 2-5 seconds between the time that I execute DirectorySearcher FindOne() and the first network packet I see go out to the LDAP server. After the initial execution, subsequent executions complete instantly for about 45 seconds. After that period of fast executions, the next execution will be delayed and again all subsequent executions will complete instantly. It seems like there's some sort of caching going on but I haven't been able to find any resources confirming that or describing what is causing the initial delay.
We noticed this on a client Windows 2008 server and then reproduced on our own Windows 2008 and Windows 7 boxes.
Here's what my simple .NET 4.0 C# app looks like. The delay occurs between the "Started" and "Finished" messages.
Any idea why this delay occurs on the initial FindOne() execution? Any help is much appreciated!
using System;
using System.Collections.Generic;
using System.Text;
using System.DirectoryServices;
namespace LdapTest
{
class Program
{
static void Main(string[] args)
{
string[] fetchAttributes;
fetchAttributes = new string[] { "{string[0]}" };
using (DirectoryEntry searchRoot = new DirectoryEntry("LDAP://localserver/ou=lab,dc=ourdomain,dc=com", "cn=binduser,ou=Services,dc=ourdomain,dc=com", "Password", AuthenticationTypes.ReadonlyServer))
{
using (DirectorySearcher searcher = new DirectorySearcher(searchRoot, "(sAMAccountName=UserName)", fetchAttributes, SearchScope.Subtree))
{
Console.WriteLine("Started");
SearchResult result = searcher.FindOne();
Console.WriteLine("Finished");
}
}
}
}
According to the LDAP ADsPath MSDN article, you should specify the
ServerBind
flag if your binding LDAP path points to a server to avoid unnecessary network traffic. It also recommends giving the full DNS name of the server. In addition, theReadonlyServer
flag is meaningless when pointing to a server. So my first suggestion is to replace theReadonlyServer
flag withServerBind
(and preferably give the full DNS name), or remove the server part of the string (in your example, make it LDAP://ou=lab,dc=ourdomain,dc=com or LDAP://ourdomain.com/ou=lab,dc=ourdomain,dc=com).The other thing to look at is that you're providing the username by distinguished name. If you look at the core API that DirectoryEntry uses, IADsOpenDSObject::OpenDSObject, it requires that the lpReserved flag [the
AuthenticationTypes
parameter in DirectoryEntry] is zero [None
] or includes the ADS_USE_SSL [SecureSocketsLayer
] flag when passing a distinguished name for the username. Note that theSecureSocketsLayer
flag requires that Active Directory requires that a certificate server is installed before you can use this flag. You might want to pass the username in a different format.Finally, this MDSN page says that without any authentication flags, the username and password is sent cleartext. You should add the
Secure
flag.