// Non recursive group check (immediate membership only currently) private static bool IsUserInGroup(UserPrincipal user, GroupPrincipal group) { if (user == null || group == null) { return(false); } // This may seem a convoluted and strange way to check group membership. // Especially because I could just call user.IsMemberOf(group). // The reason for all of this is that IsMemberOf will throw an exception // if there is an unresolvable SID in the list of group members. Unfortunately, // even looping over the members with a standard foreach loop doesn't allow // for catching the exception and continuing. Therefore, we need to use the // IEnumerator object and iterate through the members carefully, catching the // exception if it is thrown. I throw in a sanity check because there's no // guarantee that MoveNext will actually move the enumerator forward when an // exception occurs, although it has done so in my tests. // // For additional details, see the following bug: // https://connect.microsoft.com/VisualStudio/feedback/details/453812/principaloperationexception-when-enumerating-the-collection-groupprincipal-members PrincipalCollection members = group.Members; bool ok = true; int errorCount = 0; // This is a sanity check in case the loop gets out of control IEnumerator <Principal> membersEnum = members.GetEnumerator(); while (ok) { try { ok = membersEnum.MoveNext(); } catch (PrincipalOperationException) { m_logger.ErrorFormat("PrincipalOperationException when checking group membership for user {0} in group {1}." + " This usually means that you have an unresolvable SID as a group member." + " I strongly recommend that you fix this problem as soon as possible by removing the SID from the group. " + " Ignoring the exception and continuing.", user.Name, group.Name); // Sanity check to avoid infinite loops errorCount++; if (errorCount > 1000) { return(false); } continue; } if (ok) { Principal principal = membersEnum.Current; if (principal is UserPrincipal && principal.Sid == user.Sid) { return(true); } } } return(false); }
static List <UserPrincipal> GetGroupMembers(PrincipalContext oPrincipalContext, String group) { GroupPrincipal oGroupPrincipal = GroupPrincipal.FindByIdentity(oPrincipalContext, group); List <UserPrincipal> ret = new List <UserPrincipal>(); if (oGroupPrincipal == null) { return(ret); } PrincipalCollection coll = oGroupPrincipal.Members; IEnumerator <Principal> principal = coll.GetEnumerator(); while (principal.MoveNext()) { try { if ("group".Equals(principal.Current.StructuralObjectClass.ToLower())) { ret.AddRange(GetGroupMembers(oPrincipalContext, principal.Current.SamAccountName)); } else { UserPrincipal user = UserPrincipal.FindByIdentity(oPrincipalContext, principal.Current.SamAccountName); if (user == null) { continue; } ret.Add(user); } } catch (MultipleMatchesException) { continue; } catch (PrincipalOperationException) { continue; } } return(ret); }