protected 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 IntPtr pOA = IntPtr.Zero; IntPtr pPolicyHandle = IntPtr.Zero; IntPtr pDomains = IntPtr.Zero; UnsafeNativeMethods.LSA_TRUST_INFORMATION[] domains; IntPtr pNames = IntPtr.Zero; UnsafeNativeMethods.LSA_TRANSLATED_NAME[] names; try { // // Get the policy handle // UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES oa = new UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES(); pOA = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES))); Marshal.StructureToPtr(oa, pOA, false); int err = 0; if (target == null) { err = UnsafeNativeMethods.LsaOpenPolicy( IntPtr.Zero, pOA, 0x800, // POLICY_LOOKUP_NAMES ref pPolicyHandle); } else { // Build an entry. Note that LSA_UNICODE_STRING.length is in bytes, // while PtrToStringUni expects a length in characters. UnsafeNativeMethods.LSA_UNICODE_STRING_Managed lsaTargetString = new UnsafeNativeMethods.LSA_UNICODE_STRING_Managed(); lsaTargetString.buffer = target; lsaTargetString.length = (ushort)(target.Length * 2); lsaTargetString.maximumLength = lsaTargetString.length; IntPtr lsaTargetPr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_UNICODE_STRING))); try { Marshal.StructureToPtr(lsaTargetString, lsaTargetPr, false); err = UnsafeNativeMethods.LsaOpenPolicy( lsaTargetPr, pOA, 0x800, // POLICY_LOOKUP_NAMES ref pPolicyHandle); } finally { if (lsaTargetPr != IntPtr.Zero) { UnsafeNativeMethods.LSA_UNICODE_STRING lsaTargetUnmanagedPtr = (UnsafeNativeMethods.LSA_UNICODE_STRING)Marshal.PtrToStructure(lsaTargetPr, typeof(UnsafeNativeMethods.LSA_UNICODE_STRING)); if (lsaTargetUnmanagedPtr.buffer != IntPtr.Zero) { Marshal.FreeHGlobal(lsaTargetUnmanagedPtr.buffer); lsaTargetUnmanagedPtr.buffer = IntPtr.Zero; } Marshal.FreeHGlobal(lsaTargetPr); } } } if (err != 0) { GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "SidList: couldn't get policy handle, err={0}", err); throw new PrincipalOperationException(String.Format(CultureInfo.CurrentCulture, StringResources.AuthZErrorEnumeratingGroups, SafeNativeMethods.LsaNtStatusToWinError(err))); } Debug.Assert(pPolicyHandle != IntPtr.Zero); // // Translate the SIDs // err = UnsafeNativeMethods.LsaLookupSids( pPolicyHandle, sidCount, pSids, out pDomains, out pNames); // ignore error STATUS_SOME_NOT_MAPPED = 0x00000107 and // STATUS_NONE_MAPPED = 0xC0000073 if (err != 0 && err != 263 && err != -1073741709) { GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "SidList: LsaLookupSids failed, err={0}", err); throw new PrincipalOperationException(String.Format(CultureInfo.CurrentCulture, StringResources.AuthZErrorEnumeratingGroups, SafeNativeMethods.LsaNtStatusToWinError(err))); } // // Get the group names in managed form // names = new UnsafeNativeMethods.LSA_TRANSLATED_NAME[sidCount]; IntPtr pCurrentName = pNames; for (int i = 0; i < sidCount; i++) { names[i] = (UnsafeNativeMethods.LSA_TRANSLATED_NAME) Marshal.PtrToStructure(pCurrentName, typeof(UnsafeNativeMethods.LSA_TRANSLATED_NAME)); pCurrentName = new IntPtr(pCurrentName.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_TRANSLATED_NAME))); } // // Get the domain names in managed form // // Extract LSA_REFERENCED_DOMAIN_LIST.Entries UnsafeNativeMethods.LSA_REFERENCED_DOMAIN_LIST referencedDomains = (UnsafeNativeMethods.LSA_REFERENCED_DOMAIN_LIST)Marshal.PtrToStructure(pDomains, typeof(UnsafeNativeMethods.LSA_REFERENCED_DOMAIN_LIST)); int domainCount = referencedDomains.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. domains = new UnsafeNativeMethods.LSA_TRUST_INFORMATION[domainCount]; IntPtr pCurrentDomain = referencedDomains.domains; for (int i = 0; i < domainCount; i++) { domains[i] = (UnsafeNativeMethods.LSA_TRUST_INFORMATION)Marshal.PtrToStructure(pCurrentDomain, typeof(UnsafeNativeMethods.LSA_TRUST_INFORMATION)); pCurrentDomain = new IntPtr(pCurrentDomain.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.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++) { UnsafeNativeMethods.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) { UnsafeNativeMethods.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 { if (pDomains != IntPtr.Zero) { UnsafeNativeMethods.LsaFreeMemory(pDomains); } if (pNames != IntPtr.Zero) { UnsafeNativeMethods.LsaFreeMemory(pNames); } if (pPolicyHandle != IntPtr.Zero) { UnsafeNativeMethods.LsaClose(pPolicyHandle); } if (pOA != IntPtr.Zero) { Marshal.FreeHGlobal(pOA); } } }
protected void TranslateSids(string target, IntPtr[] pSids) { if ((int)pSids.Length != 0) { int length = (int)pSids.Length; IntPtr zero = IntPtr.Zero; IntPtr intPtr = IntPtr.Zero; IntPtr zero1 = IntPtr.Zero; IntPtr intPtr1 = IntPtr.Zero; try { UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES lSAOBJECTATTRIBUTE = new UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES(); zero = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES))); Marshal.StructureToPtr(lSAOBJECTATTRIBUTE, zero, false); int num = 0; if (target != null) { UnsafeNativeMethods.LSA_UNICODE_STRING_Managed lSAUNICODESTRINGManaged = new UnsafeNativeMethods.LSA_UNICODE_STRING_Managed(); lSAUNICODESTRINGManaged.buffer = target; lSAUNICODESTRINGManaged.length = (ushort)(target.Length * 2); lSAUNICODESTRINGManaged.maximumLength = lSAUNICODESTRINGManaged.length; IntPtr intPtr2 = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_UNICODE_STRING))); try { Marshal.StructureToPtr(lSAUNICODESTRINGManaged, intPtr2, false); num = UnsafeNativeMethods.LsaOpenPolicy(intPtr2, zero, 0x800, ref intPtr); } finally { if (intPtr2 != IntPtr.Zero) { UnsafeNativeMethods.LSA_UNICODE_STRING structure = (UnsafeNativeMethods.LSA_UNICODE_STRING)Marshal.PtrToStructure(intPtr2, typeof(UnsafeNativeMethods.LSA_UNICODE_STRING)); if (structure.buffer != IntPtr.Zero) { Marshal.FreeHGlobal(structure.buffer); structure.buffer = IntPtr.Zero; } Marshal.FreeHGlobal(intPtr2); } } } else { num = UnsafeNativeMethods.LsaOpenPolicy(IntPtr.Zero, zero, 0x800, ref intPtr); } if (num == 0) { num = UnsafeNativeMethods.LsaLookupSids(intPtr, length, pSids, out zero1, out intPtr1); if (num == 0) { UnsafeNativeMethods.LSA_TRANSLATED_NAME[] lSATRANSLATEDNAMEArray = new UnsafeNativeMethods.LSA_TRANSLATED_NAME[length]; IntPtr intPtr3 = intPtr1; for (int i = 0; i < length; i++) { lSATRANSLATEDNAMEArray[i] = (UnsafeNativeMethods.LSA_TRANSLATED_NAME)Marshal.PtrToStructure(intPtr3, typeof(UnsafeNativeMethods.LSA_TRANSLATED_NAME)); intPtr3 = new IntPtr(intPtr3.ToInt64() + (long)Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_TRANSLATED_NAME))); } UnsafeNativeMethods.LSA_REFERENCED_DOMAIN_LIST lSAREFERENCEDDOMAINLIST = (UnsafeNativeMethods.LSA_REFERENCED_DOMAIN_LIST)Marshal.PtrToStructure(zero1, typeof(UnsafeNativeMethods.LSA_REFERENCED_DOMAIN_LIST)); int num1 = lSAREFERENCEDDOMAINLIST.entries; UnsafeNativeMethods.LSA_TRUST_INFORMATION[] lSATRUSTINFORMATIONArray = new UnsafeNativeMethods.LSA_TRUST_INFORMATION[num1]; IntPtr intPtr4 = lSAREFERENCEDDOMAINLIST.domains; for (int j = 0; j < num1; j++) { lSATRUSTINFORMATIONArray[j] = (UnsafeNativeMethods.LSA_TRUST_INFORMATION)Marshal.PtrToStructure(intPtr4, typeof(UnsafeNativeMethods.LSA_TRUST_INFORMATION)); intPtr4 = new IntPtr(intPtr4.ToInt64() + (long)Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_TRUST_INFORMATION))); } for (int k = 0; k < (int)lSATRANSLATEDNAMEArray.Length; k++) { UnsafeNativeMethods.LSA_TRANSLATED_NAME lSATRANSLATEDNAME = lSATRANSLATEDNAMEArray[k]; UnsafeNativeMethods.LSA_TRUST_INFORMATION lSATRUSTINFORMATION = lSATRUSTINFORMATIONArray[lSATRANSLATEDNAME.domainIndex]; SidListEntry sidListEntry = new SidListEntry(); sidListEntry.name = Marshal.PtrToStringUni(lSATRANSLATEDNAME.name.buffer, lSATRANSLATEDNAME.name.length / 2); sidListEntry.sidIssuerName = Marshal.PtrToStringUni(lSATRUSTINFORMATION.name.buffer, lSATRUSTINFORMATION.name.length / 2); sidListEntry.pSid = pSids[k]; this.entries.Add(sidListEntry); } } else { object[] winError = new object[1]; winError[0] = SafeNativeMethods.LsaNtStatusToWinError(num); throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.AuthZErrorEnumeratingGroups, winError)); } } else { object[] objArray = new object[1]; objArray[0] = SafeNativeMethods.LsaNtStatusToWinError(num); throw new PrincipalOperationException(string.Format(CultureInfo.CurrentCulture, StringResources.AuthZErrorEnumeratingGroups, objArray)); } } finally { if (zero1 != IntPtr.Zero) { UnsafeNativeMethods.LsaFreeMemory(zero1); } if (intPtr1 != IntPtr.Zero) { UnsafeNativeMethods.LsaFreeMemory(intPtr1); } if (intPtr != IntPtr.Zero) { UnsafeNativeMethods.LsaClose(intPtr); } if (zero != IntPtr.Zero) { Marshal.FreeHGlobal(zero); } } return; } else { return; } }
protected 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 IntPtr pOA = IntPtr.Zero; IntPtr pPolicyHandle = IntPtr.Zero; IntPtr pDomains = IntPtr.Zero; UnsafeNativeMethods.LSA_TRUST_INFORMATION[] domains; IntPtr pNames = IntPtr.Zero; UnsafeNativeMethods.LSA_TRANSLATED_NAME[] names; try { // // Get the policy handle // UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES oa = new UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES(); pOA = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_OBJECT_ATTRIBUTES))); Marshal.StructureToPtr(oa, pOA, false); int err = 0; if (target == null) { err = UnsafeNativeMethods.LsaOpenPolicy( IntPtr.Zero, pOA, 0x800, // POLICY_LOOKUP_NAMES ref pPolicyHandle); } else { // Build an entry. Note that LSA_UNICODE_STRING.length is in bytes, // while PtrToStringUni expects a length in characters. UnsafeNativeMethods.LSA_UNICODE_STRING_Managed lsaTargetString = new UnsafeNativeMethods.LSA_UNICODE_STRING_Managed(); lsaTargetString.buffer = target; lsaTargetString.length = (ushort)(target.Length * 2); lsaTargetString.maximumLength = lsaTargetString.length; IntPtr lsaTargetPr = Marshal.AllocHGlobal(Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_UNICODE_STRING))); try { Marshal.StructureToPtr(lsaTargetString, lsaTargetPr, false); err = UnsafeNativeMethods.LsaOpenPolicy( lsaTargetPr, pOA, 0x800, // POLICY_LOOKUP_NAMES ref pPolicyHandle); } finally { if (lsaTargetPr != IntPtr.Zero) { UnsafeNativeMethods.LSA_UNICODE_STRING lsaTargetUnmanagedPtr = (UnsafeNativeMethods.LSA_UNICODE_STRING)Marshal.PtrToStructure(lsaTargetPr, typeof(UnsafeNativeMethods.LSA_UNICODE_STRING)); if (lsaTargetUnmanagedPtr.buffer != IntPtr.Zero) { Marshal.FreeHGlobal(lsaTargetUnmanagedPtr.buffer); lsaTargetUnmanagedPtr.buffer = IntPtr.Zero; } Marshal.FreeHGlobal(lsaTargetPr); } } } if (err != 0) { GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "SidList: couldn't get policy handle, err={0}", err); throw new PrincipalOperationException(String.Format(CultureInfo.CurrentCulture, StringResources.AuthZErrorEnumeratingGroups, SafeNativeMethods.LsaNtStatusToWinError(err))); } Debug.Assert(pPolicyHandle != IntPtr.Zero); // // Translate the SIDs // err = UnsafeNativeMethods.LsaLookupSids( pPolicyHandle, sidCount, pSids, out pDomains, out pNames); // ignore error STATUS_SOME_NOT_MAPPED = 0x00000107 and // STATUS_NONE_MAPPED = 0xC0000073 if (err != 0 && err != 263 && err != -1073741709) { GlobalDebug.WriteLineIf(GlobalDebug.Warn, "AuthZSet", "SidList: LsaLookupSids failed, err={0}", err); throw new PrincipalOperationException(String.Format(CultureInfo.CurrentCulture, StringResources.AuthZErrorEnumeratingGroups, SafeNativeMethods.LsaNtStatusToWinError(err))); } // // Get the group names in managed form // names = new UnsafeNativeMethods.LSA_TRANSLATED_NAME[sidCount]; IntPtr pCurrentName = pNames; for (int i = 0; i < sidCount; i++) { names[i] = (UnsafeNativeMethods.LSA_TRANSLATED_NAME) Marshal.PtrToStructure(pCurrentName, typeof(UnsafeNativeMethods.LSA_TRANSLATED_NAME)); pCurrentName = new IntPtr(pCurrentName.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.LSA_TRANSLATED_NAME))); } // // Get the domain names in managed form // // Extract LSA_REFERENCED_DOMAIN_LIST.Entries UnsafeNativeMethods.LSA_REFERENCED_DOMAIN_LIST referencedDomains = (UnsafeNativeMethods.LSA_REFERENCED_DOMAIN_LIST)Marshal.PtrToStructure(pDomains, typeof(UnsafeNativeMethods.LSA_REFERENCED_DOMAIN_LIST)); int domainCount = referencedDomains.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. domains = new UnsafeNativeMethods.LSA_TRUST_INFORMATION[domainCount]; IntPtr pCurrentDomain = referencedDomains.domains; for (int i = 0; i < domainCount; i++) { domains[i] = (UnsafeNativeMethods.LSA_TRUST_INFORMATION)Marshal.PtrToStructure(pCurrentDomain, typeof(UnsafeNativeMethods.LSA_TRUST_INFORMATION)); pCurrentDomain = new IntPtr(pCurrentDomain.ToInt64() + Marshal.SizeOf(typeof(UnsafeNativeMethods.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++) { UnsafeNativeMethods.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) { UnsafeNativeMethods.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 { if (pDomains != IntPtr.Zero) UnsafeNativeMethods.LsaFreeMemory(pDomains); if (pNames != IntPtr.Zero) UnsafeNativeMethods.LsaFreeMemory(pNames); if (pPolicyHandle != IntPtr.Zero) UnsafeNativeMethods.LsaClose(pPolicyHandle); if (pOA != IntPtr.Zero) Marshal.FreeHGlobal(pOA); } }