4

I am using the API System.DirectoryServices.AccountManagement to bind to an AD-LDS instance. I am using simple bind with a user that exists locally in the AD-LDS instance. It works when I run the client on the server that hosts AD-LDS but it doesn't work when I run the client on a remote computer.

This is the code I use to bind and search for a user:

var c = new PrincipalContext(ContextType.ApplicationDirectory, "fullhostname:50001", "CN=Users,DC=app,DC=local", ContextOptions.SimpleBind, "CN=joe,CN=Users,DC=app,DC=local", "abc");
var u = UserPrincipal.FindByIdentity(c, IdentityType.Name, "john");

This is the exception that is thrown when I run it on a remote computer:

System.DirectoryServices.AccountManagement.PrincipalServerDownException: The server is not operational.
---> System.Runtime.InteropServices.COMException: The server is not operational.
   at System.DirectoryServices.DirectoryEntry.Bind(Boolean throwIfFail)
   at System.DirectoryServices.DirectoryEntry.Bind()
   at System.DirectoryServices.DirectoryEntry.get_AdsObject()
   at System.DirectoryServices.DirectoryEntry.get_Options()
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInit()
   --- End of inner exception stack trace ---
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoLDAPDirectoryInit()
   at System.DirectoryServices.AccountManagement.PrincipalContext.DoApplicationDirectoryInit()
   at System.DirectoryServices.AccountManagement.PrincipalContext.Initialize()
   at System.DirectoryServices.AccountManagement.PrincipalContext.get_ConnectedServer()
   at MyApplication.DiagnosticsController.TryAdLdsSettings(AdLdsData data) in C:\code\MyApplication\DiagnosticsController.cs:line 166

If I instead use the System.DirectoryServices API it works also from remote computer:

var obj = new DirectoryEntry("LDAP://fullhostname:50001/CN=Users,DC=app,DC=local", "CN=joe,CN=Users,DC=app,DC=local",
                "abc", AuthenticationTypes.None);
obj.RefreshCache();

This works, but I need to use System.DirectoryServices.AccountManagement API instead.

Anyone knows what is wrong?

pettys
  • 2,293
  • 26
  • 38
kls
  • 591
  • 3
  • 13
  • kls, any progress or resolution? I feel like I'm experiencing the same issue here. – pettys Feb 26 '16 at 22:43
  • @petty - can you edit the question with the full exception, or post a non-answer answer with more details? There should be an LdapException inside the PrincipleServerDownException with more information about the nature of the failure. – antiduh Feb 29 '16 at 16:10
  • @antiduh I edited the question with more info (presently under peer review). Unfortunately I'm not seeing the LdapException - just a COMException. – pettys Feb 29 '16 at 16:32

2 Answers2

0

I was able to get this to work on a domain, with a few minor changes, I hope these tips help.

  1. Your 2nd-to-last parameter when creating PrincipalContext, "CN=joe,CN=Users,DC=app,DC=local", should be the fully qualified username, not the LDAP path; this will normally look like COMPUTER-NAME\\joe (whatever your computer is named) or if you are on a domain as I am, DOMAIN-NAME\\joe. (If fullhostname is not your local workstation, then you may be on a domain, or you may need to specify fullhostname\joe to request authentication against the host server rather than your local, since your local's credentials probably won't work on the host server).

  2. For testing this on a Domain, I had to change the first parameter from ContextType.ApplicationDirectory to ContextType.Domain; it sounds like you are not on a domain, so you will probably need ContextType.ApplicationDirectory, but the error message makes me think that Active Directory Services aren't running.

  3. Since :50001 is high enough to be blocked, make sure you don't have firewall software that is blocking the request, either outgoing from your machine, or incoming to the "fullhostname" machine; and, of course, make sure your active directory services are actually available on 50001, and not some other authentication protocol.

Mogsdad
  • 44,709
  • 21
  • 151
  • 275
Matt Jordan
  • 2,133
  • 9
  • 10
  • Re 1: the distinguished-name-style user name works with the development setup. The user name styles you propose would be appropriate for `ContextType.Domain` and `ContextType.Machine`. Re 2: We are connecting to ADLDS, not a regular AD, so `ContextType.ApplicationDirectory` is certainly correct in our scenario. Re 3: We've tried with standard 389 (non-SSL) and 636 (SSL) with the same result. Furthermore, we can successfully bind to AD LDS from the web server using ADSI Edit with the parameters as shown. – pettys Feb 29 '16 at 16:37
0

I ended up rewriting my usages of PrincipalContext and UserIdentity to use DirectoryEntry directly instead. It took me a few hours to find appropriate reimplementations for the convenient UserIdentity functions I needed, but after doing so everything worked fine.

It's quite a mystery to me why the problem occurred in the first place. My only guess is that with my particular version of AD LDS in my particular configuration, there's a bug somewhere in the underlying libraries. Rewriting everything directly in DirectoryEntry, getting everything as exactly similar as I know how to do, fixed the problem.

pettys
  • 2,293
  • 26
  • 38