Ошибка GroupPrincipal.GetMembers, когда группа (или дочерняя группа, если рекурсивная) содержит ForeignSecurityPrincipal

Это не столько вопрос, сколько информация для тех, кто испытывает ту же проблему.

Возникает следующая ошибка:

System.DirectoryServices.AccountManagement.PrincipalOperationException: An error (87) occurred while enumerating the groups. The group's SID could not be resolved. 
at System.DirectoryServices.AccountManagement.SidList.TranslateSids(String target, IntPtr[] pSids) 
at System.DirectoryServices.AccountManagement.SidList.ctor(List`1 sidListByteFormat, String target, NetCred credentials) 
at System.DirectoryServices.AccountManagement.ADDNLinkedAttrSet.TranslateForeignMembers()

Когда выполняется следующий код, и группа или дочерняя группа содержит ForeignSecurityPrincipal:

private static void GetUsersFromGroup()
{
    var groupDistinguishedName = "CN=IIS_IUSRS,CN=Builtin,DC=Domain,DC=com";
    //NB: Exception thrown during iteration of members rather than call to GetMembers.    
    using (PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "Domain", "Username", "Password"))
    {
        using (GroupPrincipal groupPrincipal = GroupPrincipal.FindByIdentity(ctx, IdentityType.DistinguishedName, groupDistinguishedName))
        {                    
            using (var searchResults = groupPrincipal.GetMembers(true))//Occurs when false also.
            {
                foreach (UserPrincipal item in searchResults.OfType())
                {
                    Console.WriteLine("Found user: {0}", item.SamAccountName)
                }
            }
        }
    }
}

Я позвонил в службу поддержки Microsoft, и они подтвердили, что это проблема. фиксированный.

Microsoft предложила следующий обходной код, но он плохо работает в группах с большим количеством пользователей из-за повторяющихся вызовов UserPrincipal.FindByIdentity.

class Program
{
    //"CN=IIS_IUSRS,CN=Builtin,DC=dev-sp-sandbox,DC=local"; //TODO MODIFY THIS LINE ACCORDING TO YOUR DC CONFIGURATION

    static void Main(string[] args)
    {
        if (args.Length != 1)
        {
            Console.WriteLine("Usage: ListGroupMembers \"group's DistinguishedName\"");
            Console.WriteLine("Example: ListGroupMembers \"CN=IIS_IUSRS,CN=Builtin,DC=MyDomain,DC=local\"");
            return;
        }

        string groupDistinguishedName = args[0];

        PrincipalContext ctx = new PrincipalContext(ContextType.Domain, "dev-sp-dc", "Administrator", "Corp123!");
        List users = new List();
        listGroupMembers(groupDistinguishedName, ctx, users);

        foreach (UserPrincipal u in users)
        {
            Console.WriteLine(u.DistinguishedName);
        }
    }

    //Recursively list the group's members which are not Foreign Security Principals
    private static void listGroupMembers(string groupDistinguishedName, PrincipalContext ctx, List users)
    {
        DirectoryEntry group = new DirectoryEntry("LDAP://" + groupDistinguishedName);
        foreach (string dn in group.Properties["member"])
        {

            DirectoryEntry gpMemberEntry = new DirectoryEntry("LDAP://" + dn);
            System.DirectoryServices.PropertyCollection userProps = gpMemberEntry.Properties;

            object[] objCls = (userProps["objectClass"].Value) as object[];

            if (objCls.Contains("group"))
                listGroupMembers(userProps["distinguishedName"].Value as string, ctx, users);

            if (!objCls.Contains("foreignSecurityPrincipal"))
            {                    
                UserPrincipal u = UserPrincipal.FindByIdentity(ctx, IdentityType.DistinguishedName, dn);
                if(u!=null)  // u==null for any other types except users
                    users.Add(u);
            }
        }                 
    }
}

Вышеприведенный код можно изменить, чтобы найти внешние участники безопасности, вызывающие проблемы в группах.

Microsoft предоставила следующую информацию о внешних участниках безопасности:

Это класс объектов в AD, который представляет участника безопасности из внешнего источника (например, другого леса/домена или одной из «специальных» учетных записей ниже). . Класс задокументирован здесь: http://msdn.microsoft.com/en-us/library/cc221858(v=PROT.10).aspx Контейнер задокументирован здесь: http://msdn.microsoft.com/en-us/library/cc200915(v=PROT.10).aspx FSP — это не настоящий объект в AD, а скорее заполнитель (указатель) на объект, который находится в другом доверенном домене/лесу. Это также может быть один из «особых идентификаторов», представляющих собой группу известных учетных записей, которые также классифицируются как FSP, поскольку их SID отличаются от SID домена. Например, анонимный, авторизованный пользователь, пакет и несколько других учетных записей, как описано здесь: http://technet.microsoft.com/en-us/library/cc779144(v=WS.10).aspx

12
задан Peter 1 June 2012 в 17:43
поделиться