Question

I am having issues getting the groups from Active Directory via System.DirectoryServices

Originally I started my application on a computer that was registered on the domain, but as it was a live domain I did not want to do any writes to AD what so ever, so I set up a machine with Windows XP as the host operating system, and installed windows server 2003 on a VM.

I've added another Ethernet port in the machine and set up a switch, the 1 Ethernet port is dedicated to the VM and the other port is used for the host.

After configuring the IP addresses to get them communicating I transferred my application onto the host machine and fired it up, but I was getting an DirectoryServicesCOMException.

With the message that the user name and password was invalid :( just to check that it was not active directory I created a 3rd virtual machine and installed Windows XP, which i added to the domain with the credentials tested in the APP, works a treat.

So I thought it must be because the machine where the application is running is not part of the domain.

Heres the block of code that was causing the issue:

public CredentialValidation(String Domain, String Username, String Password, Boolean Secure)
{
     //Validate the Domain!
     try
     {
         PrincipalContext Context = new PrincipalContext(ContextType.Domain, Domain); //Throws Exception
         _IsValidDomain = true;

         //Test the user login
         _IsValidLogin = Context.ValidateCredentials(Username, Password);

         //Check the Group Admin is within this user
         //******HERE
         var Results = UserPrincipal.FindByIdentity(Context, Username).GetGroups(Context);

         foreach(Principal Result in Results)
         {
             if (Result.SamAccountName == "Domain Admins")
             {
                 _IsAdminGroup = true;
                 break;
             }
         }
         Results.Dispose();
         Context.Dispose();
     }
     catch (PrincipalServerDownException)
     {
         _IsValidDomain = false;
     }
 }

The information in the login dialogue is being entered like so:

Domain: test.internal
Username: testaccount
Password: Password01

Hope someone can shed some light in this error.


Update:

After checking the Security Logs on the server i can see that my log in attempts was successful, but this is down to:

_IsValidLogin = Context.ValidateCredentials(Username, Password);

The line after where im checking the groups is causing the error, so the main issue is that the lines of code below are not working correctly from a machine thats not joined to the network:

var Results = UserPrincipal.FindByIdentity(Context, Username).GetGroups(Context);
Was it helpful?

Solution

According to your code snippet, you're failing when you attempt to create the PrincipalContext, before calling ValidateCredentials. At that point the thread running your code is still working under either a local identity (if you're in a web process) or the identity you signed onto your machine with (for a windows process). Either of these won't exist on the test.internal domain.

You might want to try the overload of PrincipalContext that includes the username and password in the constructor. See http://msdn.microsoft.com/en-us/library/bb341016.aspx

OTHER TIPS

I used to do quite a bit of user management via C# .NET. I just dug up some methods you can try.

The following two methods will get a DirectoryEntry object for a given SAM account name. It takes a DirectoryEntry that is the root of the OU you want to start searching for the account at.

The other will give you a list of distinguished names of the groups the user is a member of. You can then use those DN's to search AD and get a DirectoryEntry object.

public List<string> GetMemberOf(DirectoryEntry de)
{
  List<string> memberof = new List<string>();

  foreach (object oMember in de.Properties["memberOf"])
  {
    memberof.Add(oMember.ToString());
  }

  return memberof;
}

public DirectoryEntry GetObjectBySAM(string sam, DirectoryEntry root)
{
  using (DirectorySearcher searcher = new DirectorySearcher(root, string.Format("(sAMAccountName={0})", sam)))
  {
    SearchResult sr = searcher.FindOne();

    if (!(sr == null)) return sr.GetDirectoryEntry();
    else
      return null;
  }
}
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top