0
votes

We have a AD Forest, there are two different domains. Lets say that we have domain A and Domain B. We have a group "Admins" in the domain A. In this group were added several groups from the domain B. How can I check, whether a user belongs to the "Admin" group or to the group that is in "Admin" group?

Scenario I considered:

  1. Find Admins group in domain A.
  2. Read all groups and users that belong to the "Admin" group
  3. Find all groups for the current UserPrincipal It could be that principal belongs to groups in Domain A and domain B.
  4. Compare the two lists with respective SIDs

Is it safe to compare the SID of a group object from domain A with the SID of the very same group that was added(linked) to the domain B? are the SIDs always unique in terms of one Forest?

Update: One can use the solution proposed by Ashigore. Or the solution I wrote:

public IEnumerable<SecurityIdentifier> ReadAllMemebersForRecursive(string groupName)
        {
            PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "domainname", "user to access", "password");
            var groupPrincipal = GroupPrincipal.FindByIdentity(ctx, groupName);

            if (groupPrincipal == null)
                return Enumerable.Empty<SecurityIdentifier>();

            return groupPrincipal.GetMembers(true).OfType<UserPrincipal>().Select(gp => gp.Sid);
      }


 IEnumerable<SecurityIdentifier> users = service.ReadAllMemebersForRecursive(groupName);
 var identity = WindowsIdentity.GetCurrent();
 var admin = users.Contains(identity.User);   
1

1 Answers

3
votes

Try using the System.DirectoryServices.AccountManagement namespace:

static GroupPrincipal[] GetUserAuthorisationGroups(string userPrincipalName)
{
    using (PrincipalContext context = new PrincipalContext(ContextType.Domain))
    using (UserPrincipal user = UserPrincipal.FindByIdentity(context, IdentityType.UserPrincipalName, userPrincipalName))
    {
        return user.GetAuthorizationGroups().OfType<GroupPrincipal>().ToArray();
    }
}

GetAuthorizationGroups returns ALL security groups the user is a member of either directly or because of nested groups. Then you can find groups by whatever way you want:

GroupPrincipal[] groups = GetUserAuthorisationGroups(szUPN);

bool searchBySid = groups.Any(g => g.Sid == groupSid);
bool searchByDN = groups.Any(g => g.DistinguishedName == groupDN);
bool searchByName = groups.Any(g => g.Name == groupName);