2012-07-17 5 views
-1

Windows 7에서 사용자를 가장하기 위해 아래를 사용하고 있습니다.이 코드는 dll로 컴파일되고 python에서 호출됩니다. 일반적으로 작동하지만 최근에 주 실행이 실패한 것을보고 "WindowsIdentity.Impersonate(safeTokenHandle.DangerousGetHandle());"메소드로 추적했습니다. 호출 될 때 사용자를 가장하지 않고 오류가 발생하지 않고 즉시 실행이 중지됩니다 (바로 다음에 Console.WriteLine()이 호출되지 않습니다).Windows 가장은 오류없이 자동으로 실패하고 실행을 종료합니다.

아이디어가 있으십니까? 부디? 이 문제를 해결하는 데 얼마나 많은 시간을 할애했는지 인정하고 싶지 않습니다.

감사합니다.

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); 
     } 
    } 
} 

벤의 추천에 따라 파이썬에 변경 :

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 
+1

왜 Python에서 C#을 사용하여 Win32 API를 호출합니까? 그냥 Python에서 저주 API를 호출하십시오. – Ben

+0

누구든지 내 질문에 찬성표를 던진 사람은 누구인지 이해하고 싶습니다 ... – dashstar

+0

오류 코드를 받아야합니다. 예외를 잡아서 관련 메시지를 살펴보십시오. 디버그 출력에 어떤 오류 메시지가 나타 납니까? 디버그 출력을 볼 수 없으면 IDE에 해당 창을 표시해야합니다. 방법을 모른다면 IDE와 도구 세트의 이름을 지정해야합니다. – Ben

답변

0

당신은 LogonUser, ImpersonateLoggedOnUserRevertToSelf를 사용하여, 파이썬에서이 직접 할 수 있습니다.

그냥 그렇게하고 문제를 복잡하게 만드는 C#을 잘라냅니다.

시작 지점 :

+0

조언과 링크 벤에 감사드립니다. 우리는 원래 .net에서 몇 가지 작업을 수행했는데, 그 이유는 우리가 거기에 있었기 때문입니다.하지만 주석에 대해 더 생각하고 파이썬으로 옮기는 것이 좋다고 결정했습니다 ... 그러나 여전히 조용히 실패합니다. ImpersonateLoggedOnUser' 메소드를 호출합니다. – dashstar

+0

'BOOL ImpersonateLoggedOnUser'는 false를 반환하고 실패 할 경우 스레드 마지막 오류를 설정합니다. 이는'GetLastError'로 확인할 수 있습니다. – Ben

+0

안녕하세요 @ 벤 내가 가지고있는 문서에 따르면'ImpersoanteLoggedOnUser'는 값을 반환하지 않습니다 : [win32security] (http://docs.activestate.com/activepython/2.4/pywin32/win32security__ImpersonateLoggedOnUser_meth.html) – dashstar

0

에 답변을 늦게하지만, 그냥이 문제를 건너 왔어요. 변경 LOGON32_LOGON_INTERACTIVELOGON32_LOGON_BATCH (4)