Amit Barkai
Amit Barkai

Reputation: 51

unexpected behavior using the DirectorySearcher "server is not operational"

I'm experiencing a very weird issue using the DirectorySearcher class when trying to query groups over LDAP.

using(var directoryEntry = new DirectoryEntry(thePath,theUserName,ThePassword)
{
var ONLY_GROUPS = "(objectClass=group)"
var filter = string.format("(&{0}({1}=*{2}*))",ONLY_GROUPS,"Name","theGroupName");
using(var searcher = new DirectorySearcher(directoryEntry,filter))
{
...
 searcher.FindAll();
...
}

In some cases on our production code when calling the FindAll function some customers are getting a ComException "server is not operational". which means that the machine trying to connect to the LDAP server has no connection to it.

but as part of our code flow we are calling on the same LDAP a different query for retrieving Domain Controllers, which always works. When calling the LDAP query for retrieving groups we get the ComException.

another notes

We have C++ code that runs the groups query over the same LDAP which works.

In addition I've created an executable that runs the same production code and it works for the failing customers (so I guess we've excluded the option this is connectivity issue)

I am running out with ideas when can cause this issue.

Upvotes: 0

Views: 1155

Answers (4)

Amit Barkai
Amit Barkai

Reputation: 51

i now have another step with understanding my issue

after calling the code mentioned above i could see after running netstat on the ldap machine

netstat -nat | findstr my_ip_address | findstr :389 i could see the connection stays established even when the using section is done

TCP ldap_ip_address:389 my_ip_address:24730 ESTABLISHED InHost

i could see there is another parameter authentication type , by default Secure when using my code this way the connection is disposed after the using section


            using (var directoryEntry = new DirectoryEntry(
                directoryPath,
                ConfigurationManager.AppSettings["ldapUsername"],
                ConfigurationManager.AppSettings["ldapPassword"],
                AuthenticationTypes.Anonymous))
            {

            }

Upvotes: 0

Amit Barkai
Amit Barkai

Reputation: 51

would like to add another important update about this issue. it is seems that the first attempt to run the ldap query works ! .

meaning after iisrest , the ldap group query works but then i wait for 120 seconds things stop working and ldap query is stuck/hand on the Bind stage after another iisrest , again ldap group is working , wait for 120 seconds same result

Upvotes: 0

Amit Barkai
Amit Barkai

Reputation: 51

here is the code for getting ldap groups

using (DirectoryEntry entry = new DirectoryEntry("LDAP://thedomain.com:636/dc=thedomain,dc=com", directory.LdapBindUser, directory.LdapBindPassword))
                {
                    string filter = "(&(objectClass=group))";
                    using (DirectorySearcher searcher = new DirectorySearcher(entry, filter))
                    {
                        searcher.FindAll();
                    }
                }

here is the code for getting ldap domain controllers


using (DirectoryEntry entry = new DirectoryEntry("LDAP://thedomain.com:636/dc=thedomain,dc=com", directory.LdapBindUser, directory.LdapBindPassword))
                {
                    string filter = "(&(objectCategory=computer)(|(primaryGroupID=516)(primaryGroupID=521)))";
                    using (DirectorySearcher searcher = new DirectorySearcher(entry, filter))
                    {
                        searcher.FindAll();
                    }
                }

Upvotes: 0

Gabriel Luci
Gabriel Luci

Reputation: 40988

Since you're using LDAPS, it's likely a problem with the SSL certificate. If the cert is not trusted on the computer that is initiating the connection, the exception you get is exactly the same as if the server could not be contacted at all.

On a problem computer, download the certificate from the server using this PowerShell script:

$webRequest = [Net.WebRequest]::Create("https://example.com:636")
try { $webRequest.GetResponse() } catch {}
$cert = $webRequest.ServicePoint.Certificate
$bytes = $cert.Export([Security.Cryptography.X509Certificates.X509ContentType]::Cert)
set-content -value $bytes -encoding byte -path "certificate.cer"

Replace example.com in the first line with your domain name. Leave the https:// and the :636 (unless you're running LDAPS from a non-standard port).

After running that script, there will be a certificate.cer file in the current directory. Open it to view it. You will see a warning if the certificate is not trusted. If it's not, then the root certificate needs to be added to the Trusted Root Certificates on the current computer.

Upvotes: 0

Related Questions