How to use LogonUser properly to impersonate domain user from workgroup client

前端 未结 6 1874
走了就别回头了
走了就别回头了 2020-12-02 09:44

ASP.NET: Impersonate against a domain on VMWare

This question is what I am asking, but the answer does not provide details on how the _token is derived. It seems to

相关标签:
6条回答
  • 2020-12-02 10:22

    I have been successfull at impersonating users in another domain, but only with a trust set up between the 2 domains.

    var token = IntPtr.Zero;
    var result = LogonUser(userID, domain, password, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token);
    if (result)
    {
        return WindowsIdentity.Impersonate(token);
    }
    
    0 讨论(0)
  • 2020-12-02 10:28

    Invalid login/password could be also related to issues in your DNS server - that's what happened to me and cost me good 5 hours of my life. See if you can specify ip address instead on domain name.

    0 讨论(0)
  • 2020-12-02 10:34

    this works for me, full working example (I wish more people would do this):

    //logon impersonation
    using System.Runtime.InteropServices; // DllImport
    using System.Security.Principal; // WindowsImpersonationContext
    using System.Security.Permissions; // PermissionSetAttribute
    
    ...
    
    class Program {
    
        // obtains user token
        [DllImport("advapi32.dll", SetLastError = true)]
        public static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword,
            int dwLogonType, int dwLogonProvider, ref IntPtr phToken);
    
        // closes open handes returned by LogonUser
        [DllImport("kernel32.dll", CharSet = CharSet.Auto)]
        public extern static bool CloseHandle(IntPtr handle);
    
        public void DoWorkUnderImpersonation() {
            //elevate privileges before doing file copy to handle domain security
            WindowsImpersonationContext impersonationContext = null;
            IntPtr userHandle = IntPtr.Zero;
            const int LOGON32_PROVIDER_DEFAULT = 0;
            const int LOGON32_LOGON_INTERACTIVE = 2;
            string domain = ConfigurationManager.AppSettings["ImpersonationDomain"];
            string user = ConfigurationManager.AppSettings["ImpersonationUser"];
            string password = ConfigurationManager.AppSettings["ImpersonationPassword"];
    
            try {
                Console.WriteLine("windows identify before impersonation: " + WindowsIdentity.GetCurrent().Name);
    
                // if domain name was blank, assume local machine
                if (domain == "")
                    domain = System.Environment.MachineName;
    
                // Call LogonUser to get a token for the user
                bool loggedOn = LogonUser(user,
                                            domain,
                                            password,
                                            LOGON32_LOGON_INTERACTIVE,
                                            LOGON32_PROVIDER_DEFAULT,
                                            ref userHandle);
    
                if (!loggedOn) {
                    Console.WriteLine("Exception impersonating user, error code: " + Marshal.GetLastWin32Error());
                    return;
                }
    
                // Begin impersonating the user
                impersonationContext = WindowsIdentity.Impersonate(userHandle);
    
                Console.WriteLine("Main() windows identify after impersonation: " + WindowsIdentity.GetCurrent().Name);
    
                //run the program with elevated privileges (like file copying from a domain server)
                DoWork();
    
            } catch (Exception ex) {
                Console.WriteLine("Exception impersonating user: " + ex.Message);
            } finally {
                // Clean up
                if (impersonationContext != null) {
                    impersonationContext.Undo();
                }
    
                if (userHandle != IntPtr.Zero) {
                    CloseHandle(userHandle);
                }
            }
        }
    
    
        private void DoWork() {
            //everything in here has elevated privileges
    
            //example access files on a network share through e$ 
            string[] files = System.IO.Directory.GetFiles(@"\\domainserver\e$\images", "*.jpg");
        }
    }
    
    0 讨论(0)
  • 2020-12-02 10:42

    Very few posts suggest using LOGON_TYPE_NEW_CREDENTIALS instead of LOGON_TYPE_NETWORK or LOGON_TYPE_INTERACTIVE. I had an impersonation issue with one machine connected to a domain and one not, and this fixed it. The last code snippet in this post suggests that impersonating across a forest does work, but it doesn't specifically say anything about trust being set up. So this may be worth trying:

    const int LOGON_TYPE_NEW_CREDENTIALS = 9;
    const int LOGON32_PROVIDER_WINNT50 = 3;
    bool returnValue = LogonUser(user, domain, password,
                LOGON_TYPE_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50,
                ref tokenHandle);
    

    MSDN says that LOGON_TYPE_NEW_CREDENTIALS only works when using LOGON32_PROVIDER_WINNT50.

    0 讨论(0)
  • 2020-12-02 10:44

    I was having the same problem. Don't know if you've solved this or not, but what I was really trying to do was access a network share with AD credentials. WNetAddConnection2() is what you need to use in that case.

    0 讨论(0)
  • 2020-12-02 10:44

    It's better to use a SecureString:

    var password = new SecureString();
    var phPassword phPassword = Marshal.SecureStringToGlobalAllocUnicode(password);
    IntPtr phUserToken;
    LogonUser(username, domain, phPassword, LOGON32_LOGON_INTERACTIVE,  LOGON32_PROVIDER_DEFAULT, out phUserToken);
    

    And:

    Marshal.ZeroFreeGlobalAllocUnicode(phPassword);
    password.Dispose();
    

    Function definition:

    private static extern bool LogonUser(
      string pszUserName,
      string pszDomain,
      IntPtr pszPassword,
      int dwLogonType,
      int dwLogonProvider,
      out IntPtr phToken);
    
    0 讨论(0)
提交回复
热议问题