Exemple #1
0
        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);
                }
            }
        }
Exemple #2
0
 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;
     }
 }
Exemple #3
0
		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;
			}
		}
Exemple #4
0
        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);
            }
        }