DaFunkyAlex
DaFunkyAlex

Reputation: 1969

Search AD only having SID

is there a way to search the Active Directory using UserPrincipal only having the SID? I have the SID in byte[] (previously queried with DirectorySearcher) and used a StringBuilder to convert it to "S-1-15-..." and "\01\05..".

I tried to handle it this way:

PrincipalContext pContext = new PrincipalContext(ContextType.Domain);
UserPrincipal pUser = new UserPrincipal(pContext);
pUser.Sid = stringBuilder.ToString();
PrincipalSearcher pSearcher = new PrincipalSearcher();
pSearcher.QueryFilter = pUser;
Console.WriteLine(pSearcher.FindOne().DistinguishedName.ToString());

Visual Studio tells me, that the Sid is write protected. Of course...

Thanks in advance & Cheers Alex

p.s.: I already tried to solve it the way described here: How can I convert from a SID to an account name in C#, but no success here.

Upvotes: 3

Views: 5484

Answers (2)

miesch1
miesch1

Reputation: 265

Better late than never. Your question helped me along, so I thought I would try to add completeness to this answer for posterity. Note that my context was Local Machine, for which FindByIdentity is too slow.

You were on the right trail. I found this answer particularly helpful to use LINQ to specify the search parameters in the collection returned by the PrincipalSearcher. These queries did the trick for me to quickly find the accounts via SID:

private static GroupPrincipal GetGroup(string accountSid)
{
  PrincipalContext oPrincipalContext = GetPrincipalContext();
  GroupPrincipal oGroupPrincipal = new GroupPrincipal(oPrincipalContext);
  return new PrincipalSearcher(oGroupPrincipal).FindAll().Cast<GroupPrincipal>()
  .FirstOrDefault(x => x.Sid.Value.Equals(accountSid, StringComparison.OrdinalIgnoreCase));
}

private static UserPrincipal GetUser(string accountSid)
{
  PrincipalContext oPrincipalContext = GetPrincipalContext();
  UserPrincipal oUserPrincipal = new UserPrincipal(oPrincipalContext);
  return new PrincipalSearcher(oUserPrincipal).FindAll().Cast<UserPrincipal>()
  .FirstOrDefault(x => x.Sid.Value.Equals(accountSid, StringComparison.OrdinalIgnoreCase));
}

private static PrincipalContext GetPrincipalContext()
{
  return new PrincipalContext(ContextType.Machine, Environment.MachineName);
}

For further details, see my post on this subject.

Upvotes: 5

Oliver Kane
Oliver Kane

Reputation: 898

You certainly can. I use the below method to find my users in an internal application called "Atlas". Please excuse the formatting.

using (var context = new PrincipalContext(ContextType.Domain, "DOMAIN_NAME_IMPORTANT"))
{
    var userIdentity = UserPrincipal.FindByIdentity(context, "USER GUID GOES HERE"));
}

Upvotes: 7

Related Questions