locked
Check if User is member of Indirect group RRS feed

  • Question

  • User-73514677 posted

    Hi,

    I am checking if user is part of a group. But the user is not a direct member of the group.

    User member of "Group 1".

    "Group 1" is part of "Group 2"

    "Group 2" is part of "Group 3"

    I am checking, if user is part of "Group 3".

    I have used the below code, which works for group under a group, but not on "group under group under group"

      public bool CheckUserpartofGroup(string strUserName, string strGroupToCheck)
            {
                try
                {
                  PrincipalContext pc = new PrincipalContext(ContextType.Domain, "Company.com","DC=Company,DC=COM",ContextOptions.Negotiate,LDAPusername,LDAPPassword );
    
                    // get the user of that domain by his username, within the context
                    UserPrincipal up = UserPrincipal.FindByIdentity(pc, IdentityType.SamAccountName, strUserName);
    
                    if (up != null)
                    {
                        // fetch the group list
                        PrincipalSearchResult<Principal> groups = up.GetAuthorizationGroups();
                        var iterGroup = groups.GetEnumerator();
                        using (iterGroup)
                        {
                            while (iterGroup.MoveNext())
                            {
                                try
                                {
                                    Principal p = iterGroup.Current;
                                    if (p.Name.ToLower() == strGroupToCheck.ToLower())
                                    {
                                        return true;
                                    }
                                }
                                catch (NoMatchingPrincipalException pex)
                                {
                                    continue;
                                }
                            }
                        }
                    }
                    else
                    {
    
                    }
    
                    return false;
    
                }
                catch (Exception ex)
                {
                    throw ex;
                }
    
            }

    How to check this?

    Thanks

     

    Monday, July 28, 2014 9:33 AM

Answers

  • User1508394307 posted

    Your code does not work because you use GetAuthorizationGroups() which will not return 

    venkatzeus

    "Group A" is a "distribution group".

    P.S.

    I went through all posts again and found that you said 

    HI,

    I believe "GetAuthorizationGroups" is the correct one.

    It is returning true for Group 2.

    Thanks

    Which can't be true if you have DL->Group 2->Group 3 because GetAuthorizationGroups() does not return DLs.

    So I think you need to check it again and maybe with your sysadmin to make sure that you have correct requirements.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, August 1, 2014 8:25 AM

All replies

  • User1508394307 posted

    Try

    bool found; 
    string groupName = "...";
    
    using (PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups())
    {
        found = groups.OfType<GroupPrincipal>().Any(g => g.Name.Equals(groupName, String.Comparison.OrdinalIgnoreCase));
    }

    or

    PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups();
    var ig = groups.GetEnumerator();
    while (ig.MoveNext())
    {
       Principal p = ig.Current;
       if (p.Name = "...")
            ...
    }

    Hope this helps.

    Monday, July 28, 2014 11:07 AM
  • User-73514677 posted

    Hi,

    Thanks for the reply.

    I tried the first option, but still getting false.

    The second option has the same code, which I have already used, and is giving result as false

    Wednesday, July 30, 2014 8:02 AM
  • User1508394307 posted

    Are you checking the security groups (.GetAuthorizationGroups) or distribution lists? Maybe you can try .GetGroups instead of .GetAuthorizationGroups

    Also maybe you can try to test if it return true for "Group 2"

    Wednesday, July 30, 2014 8:14 AM
  • User-73514677 posted

    HI,

    I believe "GetAuthorizationGroups" is the correct one.

    It is returning true for Group 2.

    Thanks

    Wednesday, July 30, 2014 8:35 AM
  • User-1454326058 posted

    Hi venkatzeus,

    For that code, it just return the current authorized groups, the parent groups won’t returned.

    For your requirement, you need to check the parent group by using IsMemberOf method.

    For example:

    PrincipalSearchResult<Principal> groups = up.GetAuthorizationGroups();
                    var iterGroup = groups.GetEnumerator();
                    GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, strGroupToCheck); 
                    //other parent group
                    //GroupPrincipal group2 = GroupPrincipal.FindByIdentity(pc, "Administrators");
                    Queue<GroupPrincipal> q = new Queue<GroupPrincipal>();   
                    q.Enqueue(group);
                    //q.Enqueue(group2);
                    bool isIntheGroup=false;
                    using (iterGroup)
                    {
                        while (iterGroup.MoveNext())
                        {
                            try
                            {
                                Principal p = iterGroup.Current;
                                GroupPrincipal[] gs = new GroupPrincipal[q.Count];
                                q.CopyTo(gs, 0);
                                bool b = IsMemberOf(new Queue<GroupPrincipal>(gs), p);
                                if(b)
                                  {
                                     isIntheGroup=b;
                                     breal;
                                  }
                             }                        }
                            catch (NoMatchingPrincipalException pex)
                            {
                                continue;
                            }
                        }
                    }
      static bool IsMemberOf(Queue<GroupPrincipal> q, Principal p)
            {
                if (q.Count == 0)
                    return true;
                else
                {
                    GroupPrincipal g = q.Dequeue();
                    if(p.IsMemberOf(g))
                    {
                       return IsMemberOf(q, p);
                    }
                    else
                    {
                        return false;
                    }
    
                }
            }

    Thanks

    Best Regards

    Wednesday, July 30, 2014 10:55 PM
  • User-73514677 posted

    Hi,

    I used the above code, but it did not work.

    The scenario is: User is not directly a member of the group, I am searching for.

    I did this in "Active directory, users and computers" window

    User is member of "Group A". On clicking the "member of" in Group A, shows "Group B".

    Clicking on "member of" in "Group B" shows "Group C".

    I am searching for Group C against that User.

    Update: Found this: "Group A" is a "distribution group".

    "Group B" is "Security group".

    "Group C is security group"

    Thanks

    Thursday, July 31, 2014 2:45 AM
  • User1508394307 posted

    For that code, it just return the current authorized groups, the parent groups won’t returned.

    Starain, I believe this is not true. 

    MSDN said: This method searches all groups recursively

    So it does return parent groups.

    I made a test with an account that is a direct member of G1

    G1 is memberOf=G2
    G2 is memberOf=G3

    All groups are security groups.

    Here's the result

    GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, "G1"); 
    up.IsMemberOf(group);

    returns true

    GroupPrincipal group = GroupPrincipal.FindByIdentity(pc, "G2"); 
    up.IsMemberOf(group);

    returns false 

    So the IsMemberOf() checks against "direct" groups only

    Using

    using (PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups())
    {
        found = groups.OfType<GroupPrincipal>().Any(g => g.Name.Equals("G3", String.Comparison.OrdinalIgnoreCase));
    }

    returns true 

    Can it be true? Just try enumerate all groups

    PrincipalSearchResult<Principal> groups = user.GetAuthorizationGroups();
    var ig = groups.GetEnumerator();
    while (ig.MoveNext())
    {
       Principal p = ig.Current;
       ...p.Name
    }

    It outputs 

    Domain Users
    Everyone
    G2
    G1
    G3

    So the GetAuthorizationGroups() returns parent groups.

    I also tested your code. It works but as I said it does no make any big difference with the code I provided before.

    @venkatzeus

    I believe you do something wrong or you are trying to check against DLs or your DC is not properly synced.

    Thursday, July 31, 2014 4:44 AM
  • User-1454326058 posted

    Hi,

    Starain, I believe this is not true. 

    MSDN said: This method searches all groups recursively

    So it does return parent groups.

    Yes, I tested again. I am wrong.

    So the IsMemberOf() checks against "direct" groups only

    Yes. But we could check the group by using a recursive way.

    @ venkatzeus

    The GetAuthorizationGroups method doesn’t return distribution groups.

    Thanks

    Best Regards

    Thursday, July 31, 2014 5:20 AM
  • User-73514677 posted

    Hi,

    Thanks for the reply.

    Is there a way to check for distribution groups and security groups ?

    User is part of Group A. Group A has Group B. Group B has Group C.

    "Group A" is a "distribution group".

    "Group B" is "Security group".

    "Group C" is "security group"

    Thanks

    Thursday, July 31, 2014 5:39 AM
  • User1508394307 posted

    There is no logic in doing it. If user is a part of Group C then my code above will find it, because it returns all groups where user belongs to.

    Thursday, July 31, 2014 10:34 AM
  • User-1454326058 posted

    Hi venkatzeus,

    For the distribution group, I think as smirnov said that you need to use GetGroups method.

    Thanks

    Best Regards

    Thursday, July 31, 2014 10:37 PM
  • User-73514677 posted

    Hi,

    I have tried the GetGroups, which return the Distribution group. But it is not checking inside the distribution group.

    Inside the Distribiution group is a Security group.

    Thanks

    Friday, August 1, 2014 1:40 AM
  • User-1454326058 posted

    Hi,

    How do you want to check the groups?

    Do you want check all the groups of specific user?

    What's your current code? Please provide it.

    Thanks

    Friday, August 1, 2014 1:52 AM
  • User1508394307 posted

    Hi,

    I have tried the GetGroups, which return the Distribution group. But it is not checking inside the distribution group.

    Inside the Distribiution group is a Security group.

    Thanks

    That's true - GetGroups will return "direct" DLs + "direct" security groups (which makes sense I think)

    If you want to do something recursiv - then do it recursively

    Way #1 

    Find user -> { get parent DLs + groups} <- repeat recursion for every item

    Way #2

    Find group -> { get members } <- repeat recursion for every item

    Friday, August 1, 2014 2:30 AM
  • User-73514677 posted

    Hi,

    Thanks for the reply.

    I have used the code, available in the first thread.

    If I give the userId (without domain) and a group name, I want to check if the user is a member of the group or not.

    Thanks

    Friday, August 1, 2014 6:42 AM
  • User1508394307 posted

    Your code does not work because you use GetAuthorizationGroups() which will not return 

    venkatzeus

    "Group A" is a "distribution group".

    P.S.

    I went through all posts again and found that you said 

    HI,

    I believe "GetAuthorizationGroups" is the correct one.

    It is returning true for Group 2.

    Thanks

    Which can't be true if you have DL->Group 2->Group 3 because GetAuthorizationGroups() does not return DLs.

    So I think you need to check it again and maybe with your sysadmin to make sure that you have correct requirements.

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Friday, August 1, 2014 8:25 AM