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

问题描述 投票:2回答:1

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

  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:不允许该用户登录此计算机。}

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

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

c# remote-access impersonation unc file-manipulation
1个回答
0
投票

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

© www.soinside.com 2019 - 2024. All rights reserved.