Beispiel #1
0
        [System.Security.SecurityCritical]  // auto-generated
        private static IdentityReferenceCollection TranslateToSids( IdentityReferenceCollection sourceAccounts, out bool someFailed )
        {
            if ( sourceAccounts == null )
            {
                throw new ArgumentNullException( "sourceAccounts" );
            }

            if ( sourceAccounts.Count == 0 )
            {
                throw new ArgumentException( Environment.GetResourceString( "Arg_EmptyCollection" ), "sourceAccounts" );
            }
            Contract.EndContractBlock();

            SafeLsaPolicyHandle LsaHandle = SafeLsaPolicyHandle.InvalidHandle;
            SafeLsaMemoryHandle ReferencedDomainsPtr = SafeLsaMemoryHandle.InvalidHandle;
            SafeLsaMemoryHandle SidsPtr = SafeLsaMemoryHandle.InvalidHandle;

            try
            {
                //
                // Construct an array of unicode strings
                //

                Win32Native.UNICODE_STRING[] Names = new Win32Native.UNICODE_STRING[ sourceAccounts.Count ];

                int currentName = 0;
                foreach ( IdentityReference id in sourceAccounts )
                {
                    NTAccount nta = id as NTAccount;

                    if ( nta == null )
                    {
                        throw new ArgumentException(  Environment.GetResourceString( "Argument_ImproperType" ), "sourceAccounts" );
                    }

                    Names[currentName].Buffer = nta.ToString();

                    if (Names[currentName].Buffer.Length * 2 + 2 > ushort.MaxValue)
                    {
                        // this should never happen since we are already validating account name length in constructor and 
                        // it is less than this limit
                        Contract.Assert(false, "NTAccount::TranslateToSids - source account name is too long.");
                        throw new SystemException();
                    }

                    Names[currentName].Length = (ushort)(Names[currentName].Buffer.Length * 2);
                    Names[currentName].MaximumLength = (ushort)(Names[currentName].Length + 2);
                    currentName++;
                }

                //
                // Open LSA policy (for lookup requires it)
                //

                LsaHandle = Win32.LsaOpenPolicy( null, PolicyRights.POLICY_LOOKUP_NAMES );

                //
                // Now perform the actual lookup
                //

                someFailed = false;
                uint ReturnCode;

                if ( Win32.LsaLookupNames2Supported )
                {
                    ReturnCode = Win32Native.LsaLookupNames2( LsaHandle, 0, sourceAccounts.Count, Names, ref ReferencedDomainsPtr, ref SidsPtr );
                }
                else
                {
                    ReturnCode = Win32Native.LsaLookupNames( LsaHandle, sourceAccounts.Count, Names, ref ReferencedDomainsPtr, ref SidsPtr );
                }

                //
                // Make a decision regarding whether it makes sense to proceed
                // based on the return code and the value of the forceSuccess argument
                //

                if ( ReturnCode == Win32Native.STATUS_NO_MEMORY ||
                    ReturnCode == Win32Native.STATUS_INSUFFICIENT_RESOURCES )
                {
                    throw new OutOfMemoryException();
                }
                else if ( ReturnCode == Win32Native.STATUS_ACCESS_DENIED )
                {
                    throw new UnauthorizedAccessException();
                }
                else if ( ReturnCode == Win32Native.STATUS_NONE_MAPPED ||
                    ReturnCode == Win32Native.STATUS_SOME_NOT_MAPPED )
                {
                    someFailed = true;
                }
                else if ( ReturnCode != 0 )
                {
                    int win32ErrorCode = Win32Native.LsaNtStatusToWinError(unchecked((int)ReturnCode));

                    if (win32ErrorCode != Win32Native.ERROR_TRUSTED_RELATIONSHIP_FAILURE)
                    {
                        Contract.Assert( false, string.Format( CultureInfo.InvariantCulture, "Win32Native.LsaLookupNames(2) returned unrecognized error {0}", win32ErrorCode ));
                    }
                    
                    throw new SystemException(Win32Native.GetMessage(win32ErrorCode));
                }

                //
                // Interpret the results and generate SID objects
                //

                IdentityReferenceCollection Result = new IdentityReferenceCollection( sourceAccounts.Count );

                if ( ReturnCode == 0 || ReturnCode == Win32Native.STATUS_SOME_NOT_MAPPED )
                {
                    if ( Win32.LsaLookupNames2Supported )
                    {
                        SidsPtr.Initialize((uint)sourceAccounts.Count, (uint)Marshal.SizeOf(typeof(Win32Native.LSA_TRANSLATED_SID2)));
                        Win32.InitializeReferencedDomainsPointer(ReferencedDomainsPtr);
                        Win32Native.LSA_TRANSLATED_SID2[] translatedSids = new Win32Native.LSA_TRANSLATED_SID2[sourceAccounts.Count];
                        SidsPtr.ReadArray(0, translatedSids, 0, translatedSids.Length);

                        for (int i = 0; i < sourceAccounts.Count; i++)
                        {
                            Win32Native.LSA_TRANSLATED_SID2 Lts = translatedSids[i];

                            //
                            // Only some names are recognized as NTAccount objects
                            //

                            switch ((SidNameUse)Lts.Use)
                            {
                                case SidNameUse.User:
                                case SidNameUse.Group:
                                case SidNameUse.Alias:
                                case SidNameUse.Computer:
                                case SidNameUse.WellKnownGroup:
                                    Result.Add( new SecurityIdentifier( Lts.Sid, true ));
                                    break;

                                default:
                                    someFailed = true;                         
                                    Result.Add( sourceAccounts[i] );
                                    break;
                            }
                        }
                    }
                    else
                    {
                        SidsPtr.Initialize((uint)sourceAccounts.Count, (uint)Marshal.SizeOf(typeof(Win32Native.LSA_TRANSLATED_SID)));
                        Win32.InitializeReferencedDomainsPointer(ReferencedDomainsPtr);
                        Win32Native.LSA_REFERENCED_DOMAIN_LIST rdl = ReferencedDomainsPtr.Read<Win32Native.LSA_REFERENCED_DOMAIN_LIST>(0);
                        SecurityIdentifier[] ReferencedDomains = new SecurityIdentifier[ rdl.Entries ];

                        for (int i = 0; i < rdl.Entries; i++)
                        {
                            Win32Native.LSA_TRUST_INFORMATION ti = ( Win32Native.LSA_TRUST_INFORMATION )Marshal.PtrToStructure( new IntPtr(( long )rdl.Domains + i * Marshal.SizeOf( typeof( Win32Native.LSA_TRUST_INFORMATION ))), typeof( Win32Native.LSA_TRUST_INFORMATION ));
                    
                            ReferencedDomains[i] = new SecurityIdentifier( ti.Sid, true );
                        }

                        Win32Native.LSA_TRANSLATED_SID[] translatedSids = new Win32Native.LSA_TRANSLATED_SID[sourceAccounts.Count];
                        SidsPtr.ReadArray(0, translatedSids, 0, translatedSids.Length);

                        for (int i = 0; i < sourceAccounts.Count; i++)
                        {
                            Win32Native.LSA_TRANSLATED_SID Lts = translatedSids[i];

                            switch ((SidNameUse)Lts.Use)
                            {
                                case SidNameUse.User:
                                case SidNameUse.Group:
                                case SidNameUse.Alias:
                                case SidNameUse.Computer:
                                case SidNameUse.WellKnownGroup:
                                    Result.Add( new SecurityIdentifier( ReferencedDomains[ Lts.DomainIndex ], Lts.Rid ));
                                    break;

                                default:
                                   someFailed = true;
                                   Result.Add( sourceAccounts[i] );
                                   break;
                            }
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < sourceAccounts.Count; i++)
                    {
                        Result.Add( sourceAccounts[i] );
                    }
                }

                return Result;
            }
            finally
            {
                LsaHandle.Dispose();
                ReferencedDomainsPtr.Dispose();
                SidsPtr.Dispose();
            }
        }
        private static IdentityReferenceCollection TranslateToSids(IdentityReferenceCollection sourceAccounts, out bool someFailed)
        {
            IdentityReferenceCollection references2;
            if (sourceAccounts == null)
            {
                throw new ArgumentNullException("sourceAccounts");
            }
            if (sourceAccounts.Count == 0)
            {
                throw new ArgumentException(Environment.GetResourceString("Arg_EmptyCollection"), "sourceAccounts");
            }
            SafeLsaPolicyHandle invalidHandle = SafeLsaPolicyHandle.InvalidHandle;
            SafeLsaMemoryHandle referencedDomains = SafeLsaMemoryHandle.InvalidHandle;
            SafeLsaMemoryHandle sids = SafeLsaMemoryHandle.InvalidHandle;
            try
            {
                uint num2;
                Win32Native.UNICODE_STRING[] names = new Win32Native.UNICODE_STRING[sourceAccounts.Count];
                int index = 0;
                foreach (IdentityReference reference in sourceAccounts)
                {
                    NTAccount account = reference as NTAccount;
                    if (account == null)
                    {
                        throw new ArgumentException(Environment.GetResourceString("Argument_ImproperType"), "sourceAccounts");
                    }
                    names[index].Buffer = account.ToString();
                    if (((names[index].Buffer.Length * 2) + 2) > 0xffff)
                    {
                        throw new SystemException();
                    }
                    names[index].Length = (ushort) (names[index].Buffer.Length * 2);
                    names[index].MaximumLength = (ushort) (names[index].Length + 2);
                    index++;
                }
                invalidHandle = Win32.LsaOpenPolicy(null, PolicyRights.POLICY_LOOKUP_NAMES);
                someFailed = false;
                if (Win32.LsaLookupNames2Supported)
                {
                    num2 = Win32Native.LsaLookupNames2(invalidHandle, 0, sourceAccounts.Count, names, ref referencedDomains, ref sids);
                }
                else
                {
                    num2 = Win32Native.LsaLookupNames(invalidHandle, sourceAccounts.Count, names, ref referencedDomains, ref sids);
                }
                if ((num2 == 0xc0000017) || (num2 == 0xc000009a))
                {
                    throw new OutOfMemoryException();
                }
                if (num2 == 0xc0000022)
                {
                    throw new UnauthorizedAccessException();
                }
                if ((num2 == 0xc0000073) || (num2 == 0x107))
                {
                    someFailed = true;
                }
                else if (num2 != 0)
                {
                    int errorCode = Win32Native.LsaNtStatusToWinError((int) num2);
                    throw new SystemException(Win32Native.GetMessage(errorCode));
                }
                IdentityReferenceCollection references = new IdentityReferenceCollection(sourceAccounts.Count);
                switch (num2)
                {
                    case 0:
                    case 0x107:
                        if (Win32.LsaLookupNames2Supported)
                        {
                            sids.Initialize((uint) sourceAccounts.Count, (uint) Marshal.SizeOf(typeof(Win32Native.LSA_TRANSLATED_SID2)));
                            Win32.InitializeReferencedDomainsPointer(referencedDomains);
                            Win32Native.LSA_TRANSLATED_SID2[] array = new Win32Native.LSA_TRANSLATED_SID2[sourceAccounts.Count];
                            sids.ReadArray<Win32Native.LSA_TRANSLATED_SID2>(0L, array, 0, array.Length);
                            for (int i = 0; i < sourceAccounts.Count; i++)
                            {
                                Win32Native.LSA_TRANSLATED_SID2 lsa_translated_sid = array[i];
                                switch (lsa_translated_sid.Use)
                                {
                                    case 1:
                                    case 2:
                                    case 4:
                                    case 5:
                                    case 9:
                                    {
                                        references.Add(new SecurityIdentifier(lsa_translated_sid.Sid, true));
                                        continue;
                                    }
                                }
                                someFailed = true;
                                references.Add(sourceAccounts[i]);
                            }
                        }
                        else
                        {
                            sids.Initialize((uint) sourceAccounts.Count, (uint) Marshal.SizeOf(typeof(Win32Native.LSA_TRANSLATED_SID)));
                            Win32.InitializeReferencedDomainsPointer(referencedDomains);
                            Win32Native.LSA_REFERENCED_DOMAIN_LIST lsa_referenced_domain_list = referencedDomains.Read<Win32Native.LSA_REFERENCED_DOMAIN_LIST>(0L);
                            SecurityIdentifier[] identifierArray = new SecurityIdentifier[lsa_referenced_domain_list.Entries];
                            for (int j = 0; j < lsa_referenced_domain_list.Entries; j++)
                            {
                                Win32Native.LSA_TRUST_INFORMATION lsa_trust_information = (Win32Native.LSA_TRUST_INFORMATION) Marshal.PtrToStructure(new IntPtr(((long) lsa_referenced_domain_list.Domains) + (j * Marshal.SizeOf(typeof(Win32Native.LSA_TRUST_INFORMATION)))), typeof(Win32Native.LSA_TRUST_INFORMATION));
                                identifierArray[j] = new SecurityIdentifier(lsa_trust_information.Sid, true);
                            }
                            Win32Native.LSA_TRANSLATED_SID[] lsa_translated_sidArray2 = new Win32Native.LSA_TRANSLATED_SID[sourceAccounts.Count];
                            sids.ReadArray<Win32Native.LSA_TRANSLATED_SID>(0L, lsa_translated_sidArray2, 0, lsa_translated_sidArray2.Length);
                            for (int k = 0; k < sourceAccounts.Count; k++)
                            {
                                Win32Native.LSA_TRANSLATED_SID lsa_translated_sid2 = lsa_translated_sidArray2[k];
                                switch (lsa_translated_sid2.Use)
                                {
                                    case 1:
                                    case 2:
                                    case 4:
                                    case 5:
                                    case 9:
                                    {
                                        references.Add(new SecurityIdentifier(identifierArray[lsa_translated_sid2.DomainIndex], lsa_translated_sid2.Rid));
                                        continue;
                                    }
                                }
                                someFailed = true;
                                references.Add(sourceAccounts[k]);
                            }
                        }
                        break;

                    default:
                        for (int m = 0; m < sourceAccounts.Count; m++)
                        {
                            references.Add(sourceAccounts[m]);
                        }
                        break;
                }
                references2 = references;
            }
            finally
            {
                invalidHandle.Dispose();
                referencedDomains.Dispose();
                sids.Dispose();
            }
            return references2;
        }