private static IdentityReferenceCollection TranslateToSids(IdentityReferenceCollection sourceAccounts, out bool someFailed) { if (sourceAccounts == null) { throw new ArgumentNullException(nameof(sourceAccounts)); } if (sourceAccounts.Count == 0) { throw new ArgumentException(SR.Arg_EmptyCollection, nameof(sourceAccounts)); } SafeLsaPolicyHandle LsaHandle = null; SafeLsaMemoryHandle ReferencedDomainsPtr = null; SafeLsaMemoryHandle SidsPtr = null; try { // // Construct an array of unicode strings // Interop.Advapi32.MARSHALLED_UNICODE_STRING[] Names = new Interop.Advapi32.MARSHALLED_UNICODE_STRING[sourceAccounts.Count]; int currentName = 0; foreach (IdentityReference id in sourceAccounts) { NTAccount nta = id as NTAccount; if (nta == null) { throw new ArgumentException(SR.Argument_ImproperType, nameof(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 Debug.Fail("NTAccount::TranslateToSids - source account name is too long."); throw new InvalidOperationException(); } 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; ReturnCode = Interop.Advapi32.LsaLookupNames2(LsaHandle, 0, sourceAccounts.Count, Names, out ReferencedDomainsPtr, out 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 == Interop.StatusOptions.STATUS_NO_MEMORY || ReturnCode == Interop.StatusOptions.STATUS_INSUFFICIENT_RESOURCES) { throw new OutOfMemoryException(); } else if (ReturnCode == Interop.StatusOptions.STATUS_ACCESS_DENIED) { throw new UnauthorizedAccessException(); } else if (ReturnCode == Interop.StatusOptions.STATUS_NONE_MAPPED || ReturnCode == Interop.StatusOptions.STATUS_SOME_NOT_MAPPED) { someFailed = true; } else if (ReturnCode != 0) { uint win32ErrorCode = Interop.Advapi32.LsaNtStatusToWinError(ReturnCode); if (unchecked ((int)win32ErrorCode) != Interop.Errors.ERROR_TRUSTED_RELATIONSHIP_FAILURE) { Debug.Fail($"Interop.LsaLookupNames(2) returned unrecognized error {win32ErrorCode}"); } throw new Win32Exception(unchecked ((int)win32ErrorCode)); } // // Interpret the results and generate SID objects // IdentityReferenceCollection Result = new IdentityReferenceCollection(sourceAccounts.Count); if (ReturnCode == 0 || ReturnCode == Interop.StatusOptions.STATUS_SOME_NOT_MAPPED) { SidsPtr.Initialize((uint)sourceAccounts.Count, (uint)Marshal.SizeOf <Interop.LSA_TRANSLATED_SID2>()); Win32.InitializeReferencedDomainsPointer(ReferencedDomainsPtr); Interop.LSA_TRANSLATED_SID2[] translatedSids = new Interop.LSA_TRANSLATED_SID2[sourceAccounts.Count]; SidsPtr.ReadArray(0, translatedSids, 0, translatedSids.Length); for (int i = 0; i < sourceAccounts.Count; i++) { Interop.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 { for (int i = 0; i < sourceAccounts.Count; i++) { Result.Add(sourceAccounts[i]); } } return(Result); } finally { LsaHandle?.Dispose(); ReferencedDomainsPtr?.Dispose(); SidsPtr?.Dispose(); } }
private static unsafe IdentityReferenceCollection TranslateToNTAccounts(IdentityReferenceCollection sourceSids, out bool someFailed) { ArgumentNullException.ThrowIfNull(sourceSids); if (sourceSids.Count == 0) { throw new ArgumentException(SR.Arg_EmptyCollection, nameof(sourceSids)); } IntPtr[] SidArrayPtr = new IntPtr[sourceSids.Count]; GCHandle[] HandleArray = new GCHandle[sourceSids.Count]; SafeLsaPolicyHandle?LsaHandle = null; SafeLsaMemoryHandle?ReferencedDomainsPtr = null; SafeLsaMemoryHandle?NamesPtr = null; try { // // Pin all elements in the array of SIDs // int currentSid = 0; foreach (IdentityReference id in sourceSids) { if (!(id is SecurityIdentifier sid)) { throw new ArgumentException(SR.Argument_ImproperType, nameof(sourceSids)); } HandleArray[currentSid] = GCHandle.Alloc(sid.BinaryForm, GCHandleType.Pinned); SidArrayPtr[currentSid] = HandleArray[currentSid].AddrOfPinnedObject(); currentSid++; } // // Open LSA policy (for lookup requires it) // LsaHandle = Win32.LsaOpenPolicy(null, Interop.Advapi32.PolicyRights.POLICY_LOOKUP_NAMES); // // Perform the actual lookup // someFailed = false; uint ReturnCode; ReturnCode = Interop.Advapi32.LsaLookupSids(LsaHandle, sourceSids.Count, SidArrayPtr, out ReferencedDomainsPtr, out NamesPtr); // // Make a decision regarding whether it makes sense to proceed // based on the return code and the value of the forceSuccess argument // if (ReturnCode == Interop.StatusOptions.STATUS_NO_MEMORY || ReturnCode == Interop.StatusOptions.STATUS_INSUFFICIENT_RESOURCES) { throw new OutOfMemoryException(); } else if (ReturnCode == Interop.StatusOptions.STATUS_ACCESS_DENIED) { throw new UnauthorizedAccessException(); } else if (ReturnCode == Interop.StatusOptions.STATUS_NONE_MAPPED || ReturnCode == Interop.StatusOptions.STATUS_SOME_NOT_MAPPED) { someFailed = true; } else if (ReturnCode != 0) { uint win32ErrorCode = Interop.Advapi32.LsaNtStatusToWinError(ReturnCode); Debug.Fail($"Interop.LsaLookupSids returned {win32ErrorCode}"); throw new Win32Exception(unchecked ((int)win32ErrorCode)); } NamesPtr.Initialize((uint)sourceSids.Count, (uint)sizeof(Interop.LSA_TRANSLATED_NAME)); ReferencedDomainsPtr.InitializeReferencedDomainsList(); // // Interpret the results and generate NTAccount objects // IdentityReferenceCollection Result = new IdentityReferenceCollection(sourceSids.Count); if (ReturnCode == 0 || ReturnCode == Interop.StatusOptions.STATUS_SOME_NOT_MAPPED) { // // Interpret the results and generate NT Account objects // Interop.LSA_REFERENCED_DOMAIN_LIST rdl = ReferencedDomainsPtr.Read <Interop.LSA_REFERENCED_DOMAIN_LIST>(0); string[] ReferencedDomains = new string[rdl.Entries]; for (int i = 0; i < rdl.Entries; i++) { Interop.LSA_TRUST_INFORMATION ti = (Interop.LSA_TRUST_INFORMATION)Marshal.PtrToStructure <Interop.LSA_TRUST_INFORMATION>(new IntPtr((long)rdl.Domains + i * Marshal.SizeOf <Interop.LSA_TRUST_INFORMATION>())); ReferencedDomains[i] = Marshal.PtrToStringUni(ti.Name.Buffer, ti.Name.Length / sizeof(char)); } Interop.LSA_TRANSLATED_NAME[] translatedNames = new Interop.LSA_TRANSLATED_NAME[sourceSids.Count]; NamesPtr.ReadArray(0, translatedNames, 0, translatedNames.Length); for (int i = 0; i < sourceSids.Count; i++) { Interop.LSA_TRANSLATED_NAME Ltn = translatedNames[i]; switch ((SidNameUse)Ltn.Use) { case SidNameUse.User: case SidNameUse.Group: case SidNameUse.Alias: case SidNameUse.Computer: case SidNameUse.WellKnownGroup: string account = Marshal.PtrToStringUni(Ltn.Name.Buffer, Ltn.Name.Length / sizeof(char)); string domain = ReferencedDomains[Ltn.DomainIndex]; Result.Add(new NTAccount(domain, account)); break; default: someFailed = true; Result.Add(sourceSids[i]); break; } } } else { for (int i = 0; i < sourceSids.Count; i++) { Result.Add(sourceSids[i]); } } return(Result); } finally { for (int i = 0; i < sourceSids.Count; i++) { if (HandleArray[i].IsAllocated) { HandleArray[i].Free(); } } LsaHandle?.Dispose(); ReferencedDomainsPtr?.Dispose(); NamesPtr?.Dispose(); } }
[System.Security.SecurityCritical] // auto-generated private static IdentityReferenceCollection TranslateToNTAccounts(IdentityReferenceCollection sourceSids, out bool someFailed) { if (sourceSids == null) { throw new ArgumentNullException("sourceSids"); } if (sourceSids.Count == 0) { throw new ArgumentException(Environment.GetResourceString("Arg_EmptyCollection"), "sourceSids"); } Contract.EndContractBlock(); IntPtr[] SidArrayPtr = new IntPtr[sourceSids.Count]; GCHandle[] HandleArray = new GCHandle[sourceSids.Count]; SafeLsaPolicyHandle LsaHandle = SafeLsaPolicyHandle.InvalidHandle; SafeLsaMemoryHandle ReferencedDomainsPtr = SafeLsaMemoryHandle.InvalidHandle; SafeLsaMemoryHandle NamesPtr = SafeLsaMemoryHandle.InvalidHandle; try { // // Pin all elements in the array of SIDs // int currentSid = 0; foreach (IdentityReference id in sourceSids) { SecurityIdentifier sid = id as SecurityIdentifier; if (sid == null) { throw new ArgumentException(Environment.GetResourceString("Argument_ImproperType"), "sourceSids"); } HandleArray[currentSid] = GCHandle.Alloc(sid.BinaryForm, GCHandleType.Pinned); SidArrayPtr[currentSid] = HandleArray[currentSid].AddrOfPinnedObject(); currentSid++; } // // Open LSA policy (for lookup requires it) // LsaHandle = Win32.LsaOpenPolicy(null, PolicyRights.POLICY_LOOKUP_NAMES); // // Perform the actual lookup // someFailed = false; uint ReturnCode; ReturnCode = Win32Native.LsaLookupSids(LsaHandle, sourceSids.Count, SidArrayPtr, ref ReferencedDomainsPtr, ref NamesPtr); // // 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)); Contract.Assert(false, string.Format(CultureInfo.InvariantCulture, "Win32Native.LsaLookupSids returned {0}", win32ErrorCode)); throw new SystemException(Win32Native.GetMessage(win32ErrorCode)); } NamesPtr.Initialize((uint)sourceSids.Count, (uint)Marshal.SizeOf(typeof(Win32Native.LSA_TRANSLATED_NAME))); Win32.InitializeReferencedDomainsPointer(ReferencedDomainsPtr); // // Interpret the results and generate NTAccount objects // IdentityReferenceCollection Result = new IdentityReferenceCollection(sourceSids.Count); if (ReturnCode == 0 || ReturnCode == Win32Native.STATUS_SOME_NOT_MAPPED) { // // Interpret the results and generate NT Account objects // Win32Native.LSA_REFERENCED_DOMAIN_LIST rdl = ReferencedDomainsPtr.Read <Win32Native.LSA_REFERENCED_DOMAIN_LIST>(0); string[] ReferencedDomains = new string[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] = Marshal.PtrToStringUni(ti.Name.Buffer, ti.Name.Length / sizeof(char)); } Win32Native.LSA_TRANSLATED_NAME[] translatedNames = new Win32Native.LSA_TRANSLATED_NAME[sourceSids.Count]; NamesPtr.ReadArray(0, translatedNames, 0, translatedNames.Length); for (int i = 0; i < sourceSids.Count; i++) { Win32Native.LSA_TRANSLATED_NAME Ltn = translatedNames[i]; switch ((SidNameUse)Ltn.Use) { case SidNameUse.User: case SidNameUse.Group: case SidNameUse.Alias: case SidNameUse.Computer: case SidNameUse.WellKnownGroup: string account = Marshal.PtrToStringUni(Ltn.Name.Buffer, Ltn.Name.Length / sizeof(char));; string domain = ReferencedDomains[Ltn.DomainIndex]; Result.Add(new NTAccount(domain, account)); break; default: someFailed = true; Result.Add(sourceSids[i]); break; } } } else { for (int i = 0; i < sourceSids.Count; i++) { Result.Add(sourceSids[i]); } } return(Result); } finally { for (int i = 0; i < sourceSids.Count; i++) { if (HandleArray[i].IsAllocated) { HandleArray[i].Free(); } } LsaHandle.Dispose(); ReferencedDomainsPtr.Dispose(); NamesPtr.Dispose(); } }
private void TranslateSids(string target, IntPtr[] pSids) { GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "SidList: processing {0} SIDs", pSids.Length); // if there are no SIDs to translate return if (pSids.Length == 0) { return; } // Build the list of SIDs to resolve int sidCount = pSids.Length; // Translate the SIDs in bulk SafeLsaPolicyHandle policyHandle = null; SafeLsaMemoryHandle domainsHandle = null; SafeLsaMemoryHandle namesHandle = null; try { // // Get the policy handle // Interop.OBJECT_ATTRIBUTES oa = default; uint err = Interop.Advapi32.LsaOpenPolicy( target, ref oa, (int)Interop.Advapi32.PolicyRights.POLICY_LOOKUP_NAMES, out policyHandle); if (err != 0) { policyHandle.Dispose(); GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "SidList: couldn't get policy handle, err={0}", err); throw new PrincipalOperationException(SR.Format( SR.AuthZErrorEnumeratingGroups, Interop.Advapi32.LsaNtStatusToWinError(err))); } Debug.Assert(!policyHandle.IsInvalid); // // Translate the SIDs // err = Interop.Advapi32.LsaLookupSids( policyHandle, sidCount, pSids, out domainsHandle, out namesHandle); // Ignore error STATUS_SOME_NOT_MAPPED and STATUS_NONE_MAPPED if (err != Interop.StatusOptions.STATUS_SUCCESS && err != Interop.StatusOptions.STATUS_SOME_NOT_MAPPED && err != Interop.StatusOptions.STATUS_NONE_MAPPED) { domainsHandle.Dispose(); namesHandle.Dispose(); GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "SidList: LsaLookupSids failed, err={0}", err); throw new PrincipalOperationException(SR.Format( SR.AuthZErrorEnumeratingGroups, Interop.Advapi32.LsaNtStatusToWinError(err))); } // // Get the group names in managed form // namesHandle.Initialize((uint)sidCount, (uint)Marshal.SizeOf <Interop.LSA_TRANSLATED_NAME>()); Interop.LSA_TRANSLATED_NAME[] names = new Interop.LSA_TRANSLATED_NAME[sidCount]; namesHandle.ReadArray(0, names, 0, names.Length); // // Get the domain names in managed form // domainsHandle.InitializeReferencedDomainsList(); Interop.LSA_REFERENCED_DOMAIN_LIST domainList = domainsHandle.Read <Interop.LSA_REFERENCED_DOMAIN_LIST>(0); // Extract LSA_REFERENCED_DOMAIN_LIST.Entries int domainCount = domainList.Entries; // Extract LSA_REFERENCED_DOMAIN_LIST.Domains, by iterating over the array and marshalling // each native LSA_TRUST_INFORMATION into a managed LSA_TRUST_INFORMATION. Interop.LSA_TRUST_INFORMATION[] domains = new Interop.LSA_TRUST_INFORMATION[domainCount]; IntPtr pCurrentDomain = domainList.Domains; for (int i = 0; i < domainCount; i++) { domains[i] = (Interop.LSA_TRUST_INFORMATION)Marshal.PtrToStructure(pCurrentDomain, typeof(Interop.LSA_TRUST_INFORMATION)); pCurrentDomain = new IntPtr(pCurrentDomain.ToInt64() + Marshal.SizeOf(typeof(Interop.LSA_TRUST_INFORMATION))); } GlobalDebug.WriteLineIf(GlobalDebug.Info, "AuthZSet", "SidList: got {0} groups in {1} domains", sidCount, domainCount); // // Build the list of entries // Debug.Assert(names.Length == sidCount); for (int i = 0; i < names.Length; i++) { Interop.LSA_TRANSLATED_NAME name = names[i]; // Build an entry. Note that LSA_UNICODE_STRING.length is in bytes, // while PtrToStringUni expects a length in characters. SidListEntry entry = new SidListEntry(); Debug.Assert(name.Name.Length % 2 == 0); entry.name = Marshal.PtrToStringUni(name.Name.Buffer, name.Name.Length / 2); // Get the domain associated with this name Debug.Assert(name.DomainIndex < domains.Length); if (name.DomainIndex >= 0) { Interop.LSA_TRUST_INFORMATION domain = domains[name.DomainIndex]; Debug.Assert(domain.Name.Length % 2 == 0); entry.sidIssuerName = Marshal.PtrToStringUni(domain.Name.Buffer, domain.Name.Length / 2); } entry.pSid = pSids[i]; _entries.Add(entry); } // Sort the list so they are oriented by the issuer name. // this.entries.Sort( new SidListComparer()); } finally { domainsHandle?.Dispose(); namesHandle?.Dispose(); policyHandle?.Dispose(); } }
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"); } SafeLsaPolicyHandle safeLsaPolicyHandle = SafeLsaPolicyHandle.InvalidHandle; SafeLsaMemoryHandle invalidHandle = SafeLsaMemoryHandle.InvalidHandle; SafeLsaMemoryHandle invalidHandle2 = SafeLsaMemoryHandle.InvalidHandle; IdentityReferenceCollection result; try { Win32Native.UNICODE_STRING[] array = new Win32Native.UNICODE_STRING[sourceAccounts.Count]; int num = 0; foreach (IdentityReference identityReference in sourceAccounts) { NTAccount ntaccount = identityReference as NTAccount; if (ntaccount == null) { throw new ArgumentException(Environment.GetResourceString("Argument_ImproperType"), "sourceAccounts"); } array[num].Buffer = ntaccount.ToString(); if (array[num].Buffer.Length * 2 + 2 > 65535) { throw new SystemException(); } array[num].Length = (ushort)(array[num].Buffer.Length * 2); array[num].MaximumLength = array[num].Length + 2; num++; } safeLsaPolicyHandle = Win32.LsaOpenPolicy(null, PolicyRights.POLICY_LOOKUP_NAMES); someFailed = false; uint num2; if (Win32.LsaLookupNames2Supported) { num2 = Win32Native.LsaLookupNames2(safeLsaPolicyHandle, 0, sourceAccounts.Count, array, ref invalidHandle, ref invalidHandle2); } else { num2 = Win32Native.LsaLookupNames(safeLsaPolicyHandle, sourceAccounts.Count, array, ref invalidHandle, ref invalidHandle2); } if (num2 == 3221225495U || num2 == 3221225626U) { throw new OutOfMemoryException(); } if (num2 == 3221225506U) { throw new UnauthorizedAccessException(); } if (num2 == 3221225587U || num2 == 263U) { someFailed = true; } else if (num2 != 0U) { int errorCode = Win32Native.LsaNtStatusToWinError((int)num2); throw new SystemException(Win32Native.GetMessage(errorCode)); } IdentityReferenceCollection identityReferenceCollection = new IdentityReferenceCollection(sourceAccounts.Count); if (num2 == 0U || num2 == 263U) { if (Win32.LsaLookupNames2Supported) { invalidHandle2.Initialize((uint)sourceAccounts.Count, (uint)Marshal.SizeOf(typeof(Win32Native.LSA_TRANSLATED_SID2))); Win32.InitializeReferencedDomainsPointer(invalidHandle); Win32Native.LSA_TRANSLATED_SID2[] array2 = new Win32Native.LSA_TRANSLATED_SID2[sourceAccounts.Count]; invalidHandle2.ReadArray <Win32Native.LSA_TRANSLATED_SID2>(0UL, array2, 0, array2.Length); int i = 0; while (i < sourceAccounts.Count) { Win32Native.LSA_TRANSLATED_SID2 lsa_TRANSLATED_SID = array2[i]; switch (lsa_TRANSLATED_SID.Use) { case 1: case 2: case 4: case 5: case 9: identityReferenceCollection.Add(new SecurityIdentifier(lsa_TRANSLATED_SID.Sid, true)); break; case 3: case 6: case 7: case 8: goto IL_282; default: goto IL_282; } IL_294: i++; continue; IL_282: someFailed = true; identityReferenceCollection.Add(sourceAccounts[i]); goto IL_294; } } else { invalidHandle2.Initialize((uint)sourceAccounts.Count, (uint)Marshal.SizeOf(typeof(Win32Native.LSA_TRANSLATED_SID))); Win32.InitializeReferencedDomainsPointer(invalidHandle); Win32Native.LSA_REFERENCED_DOMAIN_LIST lsa_REFERENCED_DOMAIN_LIST = invalidHandle.Read <Win32Native.LSA_REFERENCED_DOMAIN_LIST>(0UL); SecurityIdentifier[] array3 = 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 + (long)(j * Marshal.SizeOf(typeof(Win32Native.LSA_TRUST_INFORMATION)))), typeof(Win32Native.LSA_TRUST_INFORMATION)); array3[j] = new SecurityIdentifier(lsa_TRUST_INFORMATION.Sid, true); } Win32Native.LSA_TRANSLATED_SID[] array4 = new Win32Native.LSA_TRANSLATED_SID[sourceAccounts.Count]; invalidHandle2.ReadArray <Win32Native.LSA_TRANSLATED_SID>(0UL, array4, 0, array4.Length); int k = 0; while (k < sourceAccounts.Count) { Win32Native.LSA_TRANSLATED_SID lsa_TRANSLATED_SID2 = array4[k]; switch (lsa_TRANSLATED_SID2.Use) { case 1: case 2: case 4: case 5: case 9: identityReferenceCollection.Add(new SecurityIdentifier(array3[lsa_TRANSLATED_SID2.DomainIndex], lsa_TRANSLATED_SID2.Rid)); break; case 3: case 6: case 7: case 8: goto IL_3C8; default: goto IL_3C8; } IL_3DA: k++; continue; IL_3C8: someFailed = true; identityReferenceCollection.Add(sourceAccounts[k]); goto IL_3DA; } } } else { for (int l = 0; l < sourceAccounts.Count; l++) { identityReferenceCollection.Add(sourceAccounts[l]); } } result = identityReferenceCollection; } finally { safeLsaPolicyHandle.Dispose(); invalidHandle.Dispose(); invalidHandle2.Dispose(); } return(result); }
[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(); } }