System.Security.Principal.NTAccount.TranslateToSids C# (CSharp) Method

TranslateToSids() private static method

private static TranslateToSids ( IdentityReferenceCollection sourceAccounts, bool &someFailed ) : IdentityReferenceCollection
sourceAccounts IdentityReferenceCollection
someFailed bool
return IdentityReferenceCollection
        private static IdentityReferenceCollection TranslateToSids(IdentityReferenceCollection sourceAccounts, out bool someFailed)
        {
            if (sourceAccounts == null)
            {
                throw new ArgumentNullException(nameof(sourceAccounts));
            }

            if (sourceAccounts.Count == 0)
            {
                throw new ArgumentException(SR.Arg_EmptyCollection, nameof(sourceAccounts));
            }
            Contract.EndContractBlock();

            SafeLsaPolicyHandle LsaHandle = SafeLsaPolicyHandle.InvalidHandle;
            SafeLsaMemoryHandle ReferencedDomainsPtr = SafeLsaMemoryHandle.InvalidHandle;
            SafeLsaMemoryHandle SidsPtr = SafeLsaMemoryHandle.InvalidHandle;

            try
            {
                //
                // Construct an array of unicode strings
                //

                Interop.UNICODE_STRING[] Names = new Interop.UNICODE_STRING[sourceAccounts.Count];

                int currentName = 0;
                foreach (IdentityReference id in sourceAccounts)
                {
                    NTAccount nta = id as NTAccount;

                    if (nta == null)
                    {
                        throw new ArgumentException(SR.Argument_ImproperType, nameof(sourceAccounts));
                    }

                    Names[currentName].Buffer = nta.ToString();

                    if (Names[currentName].Buffer.Length * 2 + 2 > ushort.MaxValue)
                    {
                        // this should never happen since we are already validating account name length in constructor and
                        // it is less than this limit
                        Debug.Assert(false, "NTAccount::TranslateToSids - source account name is too long.");
                        throw new InvalidOperationException();
                    }

                    Names[currentName].Length = (ushort)(Names[currentName].Buffer.Length * 2);
                    Names[currentName].MaximumLength = (ushort)(Names[currentName].Length + 2);
                    currentName++;
                }

                //
                // Open LSA policy (for lookup requires it)
                //

                LsaHandle = Win32.LsaOpenPolicy(null, PolicyRights.POLICY_LOOKUP_NAMES);

                //
                // Now perform the actual lookup
                //

                someFailed = false;
                uint ReturnCode;

                ReturnCode = Interop.Advapi32.LsaLookupNames2(LsaHandle, 0, sourceAccounts.Count, Names, ref ReferencedDomainsPtr, ref SidsPtr);

                //
                // Make a decision regarding whether it makes sense to proceed
                // based on the return code and the value of the forceSuccess argument
                //

                if (ReturnCode == Interop.StatusOptions.STATUS_NO_MEMORY ||
                    ReturnCode == Interop.StatusOptions.STATUS_INSUFFICIENT_RESOURCES)
                {
                    throw new OutOfMemoryException();
                }
                else if (ReturnCode == Interop.StatusOptions.STATUS_ACCESS_DENIED)
                {
                    throw new UnauthorizedAccessException();
                }
                else if (ReturnCode == Interop.StatusOptions.STATUS_NONE_MAPPED ||
                    ReturnCode == Interop.StatusOptions.STATUS_SOME_NOT_MAPPED)
                {
                    someFailed = true;
                }
                else if (ReturnCode != 0)
                {
                    int win32ErrorCode = Interop.NtDll.RtlNtStatusToDosError(unchecked((int)ReturnCode));

                    if (win32ErrorCode != Interop.Errors.ERROR_TRUSTED_RELATIONSHIP_FAILURE)
                    {
                        Debug.Assert(false, string.Format(CultureInfo.InvariantCulture, "Interop.LsaLookupNames(2) returned unrecognized error {0}", win32ErrorCode));
                    }

                    throw new Win32Exception(win32ErrorCode);
                }

                //
                // Interpret the results and generate SID objects
                //

                IdentityReferenceCollection Result = new IdentityReferenceCollection(sourceAccounts.Count);

                if (ReturnCode == 0 || ReturnCode == Interop.StatusOptions.STATUS_SOME_NOT_MAPPED)
                {
                    SidsPtr.Initialize((uint)sourceAccounts.Count, (uint)Marshal.SizeOf<Interop.LSA_TRANSLATED_SID2>());
                    Win32.InitializeReferencedDomainsPointer(ReferencedDomainsPtr);
                    Interop.LSA_TRANSLATED_SID2[] translatedSids = new Interop.LSA_TRANSLATED_SID2[sourceAccounts.Count];
                    SidsPtr.ReadArray(0, translatedSids, 0, translatedSids.Length);

                    for (int i = 0; i < sourceAccounts.Count; i++)
                    {
                        Interop.LSA_TRANSLATED_SID2 Lts = translatedSids[i];

                        //
                        // Only some names are recognized as NTAccount objects
                        //

                        switch ((SidNameUse)Lts.Use)
                        {
                            case SidNameUse.User:
                            case SidNameUse.Group:
                            case SidNameUse.Alias:
                            case SidNameUse.Computer:
                            case SidNameUse.WellKnownGroup:
                                Result.Add(new SecurityIdentifier(Lts.Sid, true));
                                break;

                            default:
                                someFailed = true;
                                Result.Add(sourceAccounts[i]);
                                break;
                        }
                    }
                }
                else
                {
                    for (int i = 0; i < sourceAccounts.Count; i++)
                    {
                        Result.Add(sourceAccounts[i]);
                    }
                }

                return Result;
            }
            finally
            {
                LsaHandle.Dispose();
                ReferencedDomainsPtr.Dispose();
                SidsPtr.Dispose();
            }
        }

Usage Example

Beispiel #1
0
 internal static IdentityReferenceCollection Translate(IdentityReferenceCollection sourceAccounts, Type targetType, out bool someFailed)
 {
     if (sourceAccounts == null)
     {
         throw new ArgumentNullException("sourceAccounts");
     }
     if (targetType == typeof(SecurityIdentifier))
     {
         return(NTAccount.TranslateToSids(sourceAccounts, out someFailed));
     }
     throw new ArgumentException(Environment.GetResourceString("IdentityReference_MustBeIdentityReference"), "targetType");
 }