Пример #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);
                }
            }
        }
Пример #2
0
        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)
                {
                    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)
                {
                    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
            {
                if (domainsHandle != null)
                {
                    domainsHandle.Dispose();
                }

                if (namesHandle != null)
                {
                    namesHandle.Dispose();
                }

                if (policyHandle != null)
                {
                    policyHandle.Dispose();
                }
            }
        }
Пример #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;
			}
		}
Пример #4
0
        private bool MoveNextForeign(ref bool outerNeedToRetry)
        {
            bool      flag;
            Principal principal;
            StoreCtx  queryCtx;
            bool      hasValue;

            outerNeedToRetry = false;
            do
            {
                flag = false;
                if (this.foreignMembersCurrentGroup.Count > 0)
                {
                    this.TranslateForeignMembers();
                }
                if (this.fakePrincipalMembers.Count <= 0)
                {
                    if (this.foreignMembersToReturn == null || this.foreignMembersToReturn.Length <= 0)
                    {
                        if (this.foreignGroups.Count <= 0)
                        {
                            return(false);
                        }
                        else
                        {
                            outerNeedToRetry = true;
                            if (this.foreignGroups[0].Context.ServerInformation.OsVersion != DomainControllerMode.Win2k)
                            {
                                GroupScope?groupScope = this.foreignGroups[0].GroupScope;
                                if (groupScope.GetValueOrDefault() != GroupScope.Global)
                                {
                                    hasValue = true;
                                }
                                else
                                {
                                    hasValue = !groupScope.HasValue;
                                }
                                if (!hasValue)
                                {
                                    this.expansionMode = ExpansionMode.ASQ;
                                    return(this.ExpandForeignGroupSearcher());
                                }
                            }
                            this.expansionMode = ExpansionMode.Enum;
                            return(this.ExpandForeignGroupEnumerator());
                        }
                    }
                    else
                    {
                        SidListEntry item    = this.foreignMembersToReturn[0];
                        SidType      sidType = Utils.ClassifySID(item.pSid);
                        if (sidType != SidType.RealObjectFakeDomain)
                        {
                            ContextOptions   aDDefaultContextOption = DefaultContextOptions.ADDefaultContextOption;
                            PrincipalContext context = SDSCache.Domain.GetContext(item.sidIssuerName, this.storeCtx.Credentials, aDDefaultContextOption);
                            queryCtx = context.QueryCtx;
                        }
                        else
                        {
                            queryCtx = this.storeCtx;
                        }
                        principal = queryCtx.FindPrincipalByIdentRef(typeof(Principal), "ms-sid", (new SecurityIdentifier(Utils.ConvertNativeSidToByteArray(this.foreignMembersToReturn[0].pSid), 0)).ToString(), DateTime.UtcNow);
                        if (principal != null)
                        {
                            this.foreignMembersToReturn.RemoveAt(0);
                        }
                        else
                        {
                            throw new PrincipalOperationException(StringResources.ADStoreCtxFailedFindCrossStoreTarget);
                        }
                    }
                }
                else
                {
                    principal = this.storeCtx.ConstructFakePrincipalFromSID((byte[])this.fakePrincipalMembers[0].Properties["objectSid"].Value);
                    this.fakePrincipalMembers[0].Dispose();
                    this.fakePrincipalMembers.RemoveAt(0);
                }
                if (principal as GroupPrincipal == null)
                {
                    DirectoryEntry underlyingObject = (DirectoryEntry)principal.GetUnderlyingObject();
                    this.storeCtx.LoadDirectoryEntryAttributes(underlyingObject);
                    if (this.usersVisited.ContainsKey(underlyingObject.Properties["distinguishedName"][0].ToString()))
                    {
                        principal.Dispose();
                        flag = true;
                    }
                    else
                    {
                        this.usersVisited.Add(underlyingObject.Properties["distinguishedName"][0].ToString(), true);
                        this.current                 = null;
                        this.currentForeignDE        = null;
                        this.currentForeignPrincipal = principal;
                        return(true);
                    }
                }
                else
                {
                    if (!principal.fakePrincipal)
                    {
                        string value = (string)((DirectoryEntry)principal.UnderlyingObject).Properties["distinguishedName"].Value;
                        if (this.groupsVisited.Contains(value) || this.groupsToVisit.Contains(value))
                        {
                            principal.Dispose();
                        }
                        else
                        {
                            this.foreignGroups.Add((GroupPrincipal)principal);
                        }
                    }
                    flag = true;
                }
            }while (flag);
            return(false);
        }
Пример #5
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;
     }
 }
Пример #6
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);
            }
        }