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

3

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

目前,我正在使用以下代码:

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

我查看了这个问题和答案 Using advapi32.dll:LogonUserA() to impersonate a remote machine's local user,但所提供的解决方案并没有起作用。
我尝试将多个值作为域、用户等传递给该方法,但我找不到正确的解决方案。我尝试使用NewCredentials,但即使未登录,它也总是返回ok。
2个回答

7

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

使用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ürgen Bayer
@JürgenBayer添加了使用模拟方法的代码,使用该代码工作正常。 - Irvin Dominin

0

你可以在本地机器上创建一个本地用户,用户名和密码与远程服务器上的本地用户相同。


谢谢,但我无法将用户复制到农场中的每台机器上;如果您看一下我的答案,我找到了一个避免这种情况的解决方案。 - Irvin Dominin

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接