[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; }