我如何使用模拟功能通过UNC在远程计算机上操纵文件/目录?

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我如何使用模拟功能通过UNC在远程计算机上操纵文件/目录?相关的知识,希望对你有一定的参考价值。

我需要将文件从服务器下载到共享驱动器目录,如果该目录不存在,则创建该目录。有几件事使事情变得更加复杂:

  1. 我没有对共享驱动器目录的写访问权限(也不会在UAT / Prod中运行该作业的帐户)。
  2. 具有写访问权的服务帐户在共享驱动器目录中没有任何特权。
  3. 我试图模仿,因此:

class Impersonation
{
    const int LOGON32_LOGON_NETWORK = 3;
    const int LOGON_TYPE_NEW_CREDENTIALS = 9;
    const int LOGON32_PROVIDER_WINNT50 = 3;

    [DllImport("advapi32.dll", SetLastError = true)]
    public static extern bool LogonUser(string pszUsername, string pszDomain, string pszPassword, int dwLogonType, int dwLogonProvider, ref IntPtr phToken);

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

    public static void Impersonate(string domain, string user, string password, Action act)
    {
        //if no user specified, don't impersonate
        if (user.Trim() == "")
        {
            act();
            return;
        }
        WindowsImpersonationContext impersonationContext = null;
        IntPtr token = IntPtr.Zero;
        try
        {
            //if no domain specified, default it to current machine
            if (domain.Trim() == "")
            {
                domain = System.Environment.MachineName;
            }
            bool result = LogonUser(user, domain, password, LOGON_TYPE_NEW_CREDENTIALS, LOGON32_PROVIDER_WINNT50, ref token);
            WindowsIdentity wi = new WindowsIdentity(token);
            impersonationContext = WindowsIdentity.Impersonate(token);
            act();
        }
        catch (Exception ex)
        {
            if (impersonationContext != null)
            {
                impersonationContext.Undo();
                impersonationContext = null;
            }
            //if something went wrong, try it as the running user just in case
            act();
        }
        finally
        {
            if (impersonationContext != null)
            {
                impersonationContext.Undo();
                impersonationContext = null;
            }
            if (token != IntPtr.Zero)
            {
                CloseHandle(token);
                token = IntPtr.Zero;
            }
        }
    }
}

并且其中一个实际的调用代码是(在另一个类中:

private static void CreateDirectoryIfNotExist(string directory, string domain, string username, string password)
{
    Impersonation.Impersonate(domain, username, password, () => CreateIfNotExist(directory));
}

private static void CreateIfNotExist(string dir)
{
    if (!Directory.Exists(dir))
    {
        Directory.CreateDirectory(dir);
    }
}

如果使用服务帐户的正确登录信息运行它,则在Directory.CreateDirectory(string)调用上会收到异常:

{{System.IO.IOException:不允许该用户登录此计算机。}

我猜这意味着不允许该服务帐户登录到我已经知道的执行计算机。但实际上,没有理由需要登录到执行计算机。有没有一种方法可以使用模拟登录到远程计算机并从那里执行命令?

我需要将文件从服务器下载到共享驱动器目录,如果该目录不存在,则创建该目录。有几件事使事情变得更复杂:我没有写访问权限(也不...

答案

如果帐户无法登录,您将无法进行模拟。模拟要求线程在用户凭据下运行。这就是LogonUser失败的原因。

以上是关于我如何使用模拟功能通过UNC在远程计算机上操纵文件/目录?的主要内容,如果未能解决你的问题,请参考以下文章

通过 UNC 路径使用 fs 读取/写入节点中的文件

通过SSIS将文件导出到sharepoint(UNC) - 拒绝访问

在远程计算机上模拟用户时 WMI 的访问被拒绝

如何在 Eclipse 中的远程计算机上构建 c++ 项目?

尝试使用模拟在远程计算机上运行 PowerShell 脚本时“不允许请求的注册表访问”

无法访问 Powershell 远程会话中的 UNC 路径