Example #1
0
        //
        // Wrapper around advapi32.LsaOpenPolicy
        //


        internal static SafeLsaPolicyHandle LsaOpenPolicy(
            string?systemName,
            Interop.Advapi32.PolicyRights rights)
        {
            Interop.OBJECT_ATTRIBUTES attributes = default;
            uint error = Interop.Advapi32.LsaOpenPolicy(systemName, ref attributes, (int)rights, out SafeLsaPolicyHandle policyHandle);

            if (error == 0)
            {
                return(policyHandle);
            }

            policyHandle.Dispose();

            if (error == Interop.StatusOptions.STATUS_ACCESS_DENIED)
            {
                throw new UnauthorizedAccessException();
            }
            else if (error == Interop.StatusOptions.STATUS_INSUFFICIENT_RESOURCES ||
                     error == Interop.StatusOptions.STATUS_NO_MEMORY)
            {
                throw new OutOfMemoryException();
            }
            else
            {
                uint win32ErrorCode = Interop.Advapi32.LsaNtStatusToWinError(error);

                throw new Win32Exception(unchecked ((int)win32ErrorCode));
            }
        }
Example #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();
                }
            }
        }