在另一台机器上模拟本地用户

Posted

技术标签:

【中文标题】在另一台机器上模拟本地用户【英文标题】:Impersonate local user on another machine 【发布时间】:2017-05-01 15:55:59 【问题描述】:

我需要将我的控制器登录到另一台机器并在上面复制一个文件;我必须在远程机器上使用本地用户。

目前我正在使用此代码:

    private Impersonate(bool active, string domain, string username, string password, LogonType logonType)
    
        if (active)
        
            IntPtr handle;
            var ok = NativeMethods.LogonUser(username, domain, password, (int)logonType, 0, out handle);
            if (!ok)
            
                var errorCode = Marshal.GetLastWin32Error();
                throw new ApplicationException(string.Format("Could not impersonate the elevated user.  LogonUser returned error code 0.", errorCode));
            

            _handle = new SafeTokenHandle(handle);
            _context = WindowsIdentity.Impersonate(_handle.DangerousGetHandle());
        
    

传递这些参数:

    using (Impersonate.LogonUser(true,
        ".",
        "todev1.domain.com\admin",
        "Test123_",
        LogonType.Interactive))
    

      

还有这个 win API:

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

我检查了此 Q/A Using advapi32.dll:LogonUserA() to impersonate a remote machine's local user,但提供的解决方案不起作用。

我尝试将多个值作为域、用户等传递给方法,但我找不到正确的解决方案。我尝试使用 NewCredentials,但即使没有记录,它也总是返回正常。

【问题讨论】:

【参考方案1】:

我终于解决了这个问题,无需将用户添加到将模拟远程机器的每台机器。

使用 NewCredential 是正确的,但使用 WINNT50 LogonProvider。

所以我现在的模拟方法是这样的:

 private Impersonate(bool active, string domain, string username, string password, LogonType logonType, LogonProvider logonProvider)
        
            if (active)
            
                IntPtr handle;
                var ok = NativeMethods.LogonUser(username, domain, password, (int)logonType, (int)logonProvider, out handle);
                if (!ok)
                
                    var errorCode = Marshal.GetLastWin32Error();
                    throw new ApplicationException(string.Format("Could not impersonate the elevated user.  LogonUser returned error code 0.", errorCode));
                

                _handle = new SafeTokenHandle(handle);
                _context = WindowsIdentity.Impersonate(_handle.DangerousGetHandle());
            
        

然后我使用代码调用Impersonate方法:

using (Impersonate.LogonUser(true,
    "todev1.domain.com",
    "admin",
    "Test123_",
    LogonType.NewCredentials,
    LogonProvider.WinNT50))



【讨论】:

LOGON32_PROVIDER_WINNT50 单独对我不起作用。我什至尝试了几种登录类型。尝试使用远程计算机上的本地用户访问远程文件夹时,我仍然收到“用户或密码不正确”。如果传递了域(根据文档),LOGON32_PROVIDER_WINNT50 与 LOGON32_PROVIDER_DEFAULT 的作用相同。如果您的代码确实有效,那么您共享的代码中肯定有其他内容不可见。您能否分享整个代码和调用? @JürgenBayer 添加了使用模拟方法的代码,该代码运行良好【参考方案2】:

您可以尝试在本地计算机上使用与远程服务器上的本地用户相同的用户名和密码来创建本地用户。

【讨论】:

谢谢,但我无法将用户复制到场中的每台机器上;如果您查看我的答案,我会找到避免它的解决方案。

以上是关于在另一台机器上模拟本地用户的主要内容,如果未能解决你的问题,请参考以下文章

Pyinstaller 一切都在本地机器上运行,但在另一台机器上失败

iCloud:如果在本地打开时在另一台机器上修改文件,则会失去写入文件的权限

通过DB Link在另一台服务器上创建用户的语法

linux 从一台机器复制文件到另一台linux机器上去

执行 Select-AzureRmSubscription 可以从我的一台(客户端)机器上运行,但不能在另一台机器上运行

如何在另一台远程服务器上使用我的 SSH 密钥进行 Git?