14

これは、同じ問題を経験しているすべての人への情報というよりは、あまり問題ではありません。

次のエラーが発生します。

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 はそれが問題であることを確認しました。内部でバグが報告されていますが、修正されるかどうかは確認されていません。

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<UserPrincipal> users = new List<UserPrincipal>();
        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<UserPrincipal> 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 内のオブジェクトのクラスです (つまり、別のフォレスト/ドメインまたは以下の「特別な」アカウントの 1 つ)。クラスはここに文書化されています: 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 の実際のオブジェクトではなく、別の信頼できるドメイン/フォレストにあるオブジェクトへのプレースホルダー (ポインター) です。また、SID がドメイン SID と異なるため、FSP としても分類される一連のよく知られたアカウントである「特別な ID」の 1 つになることもあります。たとえば、ここに記載されている匿名の認証済みユーザー、バッチ、およびその他のいくつかのアカウントです。 http://technet.microsoft.com/en-us/library/cc779144(v=WS.10).aspx

4

3 に答える 3

2

アカウント管理ライブラリには多くの悲しい欠陥があります。これは多くの欠陥の 1 つに過ぎません...

処理を少し速くするためにできることの 1 つは、LDAP クエリを調整して、グループ メンバーシップとオブジェクト タイプの両方を、ループではなくクエリの一部として同時にチェックするようにすることです。正直なところ、それが大きな違いをもたらすとは思えません。

クエリのインスピレーションのほとんどは、 ユーザーがグループのメンバーであるかどうかをテストするために LDAP クエリを作成する方法から得られました。.

クエリ: (&(!objectClass=foreignSecurityPrincipal)(memberof=CN=YourGroup,OU=Users,DC=YourDomain,DC=com))

注: これはテストされていないクエリです...

AccountManagement で LDAP クエリを実行する方法があれば (私のもう 1 つの不満です)、クエリを実行してそこから AccountManagement に取得させることができるので、これで問題は解決しますが、このオプションは存在しません...

個人的な経験に基づくと、AccountManagement に固執する場合、他に選択肢はありません。あなたができることは、AccountManagement をダンプし、DirectoryServices だけを使用することです。とにかく、内部で AccountManagement が行うことは、DirectoryEntry オブジェクトをラップすることだけです。いくつかのヘルパー クラスを記述して、同様のことを行うことができます。

于 2012-06-01T17:49:16.383 に答える