Windows Олицетворение завершается с ошибкой без ошибок и завершает выполнение

Я использую ниже для олицетворения пользователей в Windows 7. Этот код скомпилирован в DLL и вызывается из Python. Обычно это работает, но в последнее время мы видим сбой основного выполнения и прослеживаем его до "WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle());"метод. Когда вызывается этот метод, он не подражает пользователю, не выдается никакой ошибки, и выполнение немедленно останавливается (Console.WriteLine() сразу после не вызывается).

Есть идеи? Пожалуйста? Я не хочу признать, сколько времени я потратил, пытаясь решить эту проблему.

Спасибо!

using System;
using System.Runtime.InteropServices;
using System.Security.Principal;
using System.Security.Permissions;
using Microsoft.Win32.SafeHandles;
using System.Runtime.ConstrainedExecution;
using System.Security;

namespace PEServ.DataIntegration.Utilities
{
    public class WindowsCredentialHelper
    {

        [DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        public static extern bool LogonUser(String lpszUsername, String lpszDomain, String lpszPassword,
            int dwLogonType, int dwLogonProvider, out SafeTokenHandle phToken);

        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public extern static bool CloseHandle(IntPtr handle);



        public WindowsCredentialHelper()
        {
            Console.WriteLine("CS: WindowsCredentialHelper instance created successfully");
        }

        [PermissionSetAttribute(SecurityAction.Demand, Name = "FullTrust")]
        public WindowsImpersonationContext LogonAsUser(string username, string password, string domain)
        {
            SafeTokenHandle safeTokenHandle;

            const int LOGON32_PROVIDER_DEFAULT = 0;
            //This parameter causes LogonUser to create a primary token. 
            const int LOGON32_LOGON_INTERACTIVE = 2;

            Console.WriteLine("DotNet: Attempting to Logon user: {0}", username);
            // Call LogonUser to obtain a handle to an access token. 
            bool returnValue = LogonUser(username, domain, password,
                LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT,
                out safeTokenHandle);

            if (returnValue)
            {
                Console.WriteLine("DotNet: Successfully logged on as user: {0}", username);
            }
            else
            {
                Console.WriteLine("DotNet: Failed to create a user");

                int err = Marshal.GetLastWin32Error();
                if (err == 1909 || err == 1331)
                {
                    Console.WriteLine("Logon user failed because account is currently locked/disabled");
                }
                else
                {
                    Console.WriteLine("Logon user failed with error code: {0}", err);
                }

                throw new System.ComponentModel.Win32Exception(err);
            }


            //Console.WriteLine("DotNet: About to create a windows identity");
            //WindowsIdentity newId = new WindowsIdentity(safeTokenHandle.DangerousGetHandle());
            //Console.WriteLine("New windows identity is: {0}", newId.Name);

            //Console.WriteLine("Attempting to imperonate user: {0}", newId.Name);
            //WindowsImpersonationContext impersonatedUser = newId.Impersonate();
            //Console.WriteLine("DotNet: Impersonation of user: {0} was successful", newId.Name);

            Console.WriteLine("DotNet: Attempting to impersonate the user");
            WindowsImpersonationContext impersonatedUser = WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle());
            Console.WriteLine("DotNet: Impersonated the user");

            return impersonatedUser;

        }

        public void Undo(WindowsImpersonationContext impersonatedUser)
        {
            impersonatedUser.Undo();
        }

        public string GetCurrentUser()
        {
            return WindowsIdentity.GetCurrent().Name;

        }

        public string GetCurrentUserNameOnly()
        {
            return this.GetCurrentUser().Split(new char[] { '\\' })[1];

        }  
    }

    public sealed class SafeTokenHandle : SafeHandleZeroOrMinusOneIsInvalid
    {
        private SafeTokenHandle()
            : base(true)
        {
        }

        [DllImport("kernel32.dll")]
        [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
        [SuppressUnmanagedCodeSecurity]
        [return: MarshalAs(UnmanagedType.Bool)]
        private static extern bool CloseHandle(IntPtr handle);

        protected override bool ReleaseHandle()
        {
            return CloseHandle(handle);
        }
    }
}

Изменено на python по рекомендации Бена:

    def impersonate_user(self, user_name, password, domain):
        handel=win32security.LogonUser(user_name, domain, password, win32con.LOGON32_LOGON_INTERACTIVE,win32con.LOGON32_PROVIDER_DEFAULT)
        win32security.ImpersonateLoggedOnUser(handel)
    print "Hello"

    return True

2 ответа

Поздно отвечаю, но только сталкивался с этой проблемой. + Изменить LOGON32_LOGON_INTERACTIVE в LOGON32_LOGON_BATCH (4)

Вы можете сделать это прямо из Python, используя LogonUser, ImpersonateLoggedOnUser а также RevertToSelf,

Просто сделайте это и вырежьте C#, что только усложняет ситуацию.

Отправная точка:

Другие вопросы по тегам