7

I have some code (below) that runs every 15 minutes. Sometimes it will fail to query AD with the following error:

System.DirectoryServices.Protocols.DirectoryOperationException: The server does not support the control. The control is critical.
   at System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request, TimeSpan requestTimeout)
  • When it runs successfully, the entire process takes about one minute to run with the AD query taking about 30 seconds with 32 pages.
  • When it does fail, it's always on the first page.
  • It doesn't seem to fail in a pattern (always different times of the day) as far as I can tell.

After googling that error, I found two SO questions (one, two) that point to using AuthType.Ntlm to fix the issue. This hasn't solved it for me though. Another says to check if the server supports paging (it does).

Any ideas as to why this might be happening?

var attributesToReturn = new[] {
    "givenName",
    "sn",
    "middleName",
    "extensionAttribute8",
    "department",
    "sAMAccountName",
    "userAccountControl"
};
var filter = "(&(objectclass=user)(!(objectclass=computer))(sn=*)(givenName=*)(extensionAttribute8=*)(|(sn=a*)(sn=b*)(sn=c*)(sn=d*)(sn=e*)(sn=f*)(sn=g*)(sn=h*)(sn=i*)(sn=j*)(sn=k*)(sn=l*)(sn=m*)(sn=n*)(sn=o*)(sn=p*)(sn=q*)(sn=r*)(sn=s*)(sn=t*)(sn=u*)(sn=v*)(sn=w*)(sn=x*)(sn=y*)(sn=z*)))";
var currentBatch = 1;
var searchRequest = new SearchRequest("DC=foo,DC=bar,DC=baz", filter, SearchScope.Subtree, attributesToReturn);
var pageRequestControl = new PageResultRequestControl(500);
searchRequest.Controls.Add(pageRequestControl);

using (var ldapConnection = new LdapConnection("server.foo.bar.baz"))
{
    ldapConnection.Credential = new NetworkCredential("user", "pass", "domain");
    ldapConnection.Timeout = new TimeSpan(0, 4, 0);
    ldapConnection.AuthType = AuthType.Ntlm; // https://stackoverflow.com/a/14255413

    while (true)
    {
        log.Debug("Fetching batch {0} from AD", currentBatch);
        var searchResponse = (SearchResponse)ldapConnection.SendRequest(searchRequest);
        var pageResultResponse = (PageResultResponseControl)searchResponse.Controls[0];

        log.Debug("Parsing AD response for batch {0}", currentBatch);
        ParseResponse(_return, searchResponse, includeDisabled);
        if (pageResultResponse.Cookie.Length == 0)
            break;
        pageRequestControl.Cookie = pageResultResponse.Cookie;
        currentBatch++;
    }
}
Community
  • 1
  • 1
Chris
  • 4,393
  • 1
  • 27
  • 33
  • Have you tried disposing the objects you are creating? – Shago Jun 24 '16 at 01:54
  • @Shago `LdapConnection` is the only disposable object I'm using and that's handled via the `using` statement. – Chris Jun 24 '16 at 19:59
  • At what statement is that exception thrown? – Sujeet Sinha Jun 28 '16 at 15:15
  • @SujeetSinha `at System.DirectoryServices.Protocols.LdapConnection.SendRequest(DirectoryRequest request, TimeSpan requestTimeout)` – Chris Jun 28 '16 at 15:24
  • @Rfvgyhn I might be missing something here but in the code snippet you shared, I don't see two parameters passed to the `sendRequest()`.. Is that error shown with this code itself? – Sujeet Sinha Jun 28 '16 at 16:13
  • @SujeetSinha The `SendRequest(DirectoryRequest)` method is just a wrapper around `SendRequest(DirectoryRequest, TimeSpan)` that uses the `LdapConnection`'s `Timeout` property as the second parameter. Technically you're right in that I'm not calling that method, but the line `var searchResponse = (SearchResponse)ldapConnection.SendRequest(searchRequest);` is where the exception comes from. – Chris Jun 28 '16 at 16:57
  • 1
    This sounds suspiciously like some kind of timeout. – RBarryYoung Jun 28 '16 at 17:57
  • Not an answer but you could workaround random errors like this (i.e. give up) and use [Polly.NET to do retries](https://github.com/App-vNext/Polly) a few times until you succeed. You could also try playing with the LdapSessionOptions documented in [MSDN](https://msdn.microsoft.com/en-us/library/system.directoryservices.protocols.ldapsessionoptions(v=vs.110).aspx) like TCP Keep-Alive. It kind of just sounds like random network issues causing problems or maybe TCP connections on the domain controller. LDAP sucks :) In the end better to sync to a stable datastore and query from there ;) – kamranicus Jul 21 '16 at 20:08
  • Did you ever figure out the solution to this problem? I'm having the exact same issue, and I've tried all sorts of solutions without any resolution. It seems to happen on random domain controllers, at random times. I cant reliably reproduce it, but it's definitely happening. – CptJesus Jun 11 '19 at 17:41
  • @CptJesus I didn't. :( It wasn't ever a big priority since this was a process that synced to SQL server. I'm also now long gone from that project. – Chris Jun 11 '19 at 18:18

1 Answers1

0

This may not be the issue since it only fails for you sometimes, but I had this error every time and had to set

ldapConnection.SessionOptions.ProtocolVersion=3

for it to work at all.

Draken
  • 3,134
  • 13
  • 34
  • 54