【问题标题】:Access denied when reading / writing to network location as a remote process作为远程进程读取/写入网络位置时访问被拒绝
【发布时间】:2015-03-17 00:04:18
【问题描述】:

我目前正在尝试使用 C# 中的 WMI 在远程计算机上启动一个进程。该进程读取和写入存储在单独服务器上的文件。

当我手动登录到远程机器时,我可以运行该进程并且一切正常。

但是,当我尝试使用 WMI 从本地计算机远程启动进程时,出现以下错误:

System.UnauthorizedAccessException: Access to the path '\\server\path\input.txt' is denied.

我尝试了多个连接选项,但不确定如何重新创建手动登录时似乎拥有的权限...我需要做什么?

本地机器码

static void LaunchRemoteProcess(string remoteMachine, string command)
{
    ConnectionOptions connectionOptions = new ConnectionOptions
    {
        Impersonation = ImpersonationLevel.Impersonate,
        EnablePrivileges = true
    };

    var managementScope = new ManagementScope(string.Format(@"\\{0}\root\cimv2", remoteMachine), connectionOptions);
    managementScope.Connect();
    var managementPath = new ManagementPath("Win32_Process");
    var objectGetOptions = new ObjectGetOptions();
    var managementClass = new ManagementClass(managementScope, managementPath, objectGetOptions);

    // Launch the command asynchronously
    var inParams = managementClass.GetMethodParameters("Create");
    inParams["CommandLine"] = command;
    var outParams = managementClass.InvokeMethod("Create", inParams, null);
}

远程机器码

string networkPath = @"\\server\path";
string inputFile = "input.txt";
string inputText = File.ReadAllText(Path.Combine(networkPath, inputFile));

string outputFile = "output.txt";
File.WriteAllText(Path.Combine(networkPath, outputFile), inputText);

编辑 1

如果我手动登录到远程计算机并且该过程仍然失败并出现相同的错误,我已经尝试使用该过程为其工作的用户的凭据:

    ConnectionOptions connectionOptions = new ConnectionOptions
    {
        Username = "username",
        Password = "password",
        Authority = "ntlmdomain:COMPANYNAME.CO.UK,
        EnablePrivileges = true
    };

我是否缺少关于 AuthorityAuthenticationImpersonation 属性的内容?

【问题讨论】:

    标签: c# wmi


    【解决方案1】:

    模拟与委派

    您的 WMI 代码使用模拟,因此服务器端在调用客户端代码的用户的安全上下文中运行。但这仅在服务器本身上有效,不适用于访问例如远程 CIFS 共享(如您的情况)。

    您必须使用委托。

    首先,改变

    Impersonation = ImpersonationLevel.Impersonate,
    

    Impersonation = ImpersonationLevel.Delegate,
    

    如果您遇到异常,则委派在您的环境中还不起作用。

    检查:

    • 调用用户帐户:不得在用户属性(Active Directory 用户和计算机)中选中“帐户敏感且无法委派”

    • 服务器计算机帐户:必须选中“信任此计算机以委托给任何服务...”

    • 服务器上的本地安全策略:“使计算机和用户帐户受信任以进行委派”必须包括调用用户。

    https://msdn.microsoft.com/en-us/library/aa389288%28VS.85%29.aspx

    有关此主题的更多信息。


    添加:(参见下面的 cmets):

    如果Delegate 在您的环境中不是一个选项(例如,组策略不允许这样做,并且您无权更改它们),您可以检查一些替代方法。

    您可能听说过 psexec。

    或者,我几年前所做的,并且在企业环境中在几台服务器上运行多年非常成功:

    我创建了一个计划任务,它启动一个程序并为此任务设置技术用户 + 密码。该任务被配置为“在 2200 年运行一次 :-)”。

    然后我在队列中编写命令(我使用了一个简单的命令文件)并从远程机器启动任务。

    这样做不需要委托,因为计划任务本身以技术用户帐户登录(需要“批量登录”权限)。

    【讨论】:

    • 这是了解权限的有用链接,谢谢 :) 不幸的是,ImpersonationLevel.Delegate“仅在 Windows 2000 下受支持”。 (见这里:msdn.microsoft.com/en-us/library/…
    • Upps,这句话似乎是从一个非常古老的文档中 1:1 提取的,我认为这必须被理解为“仅在 Windows 2000 及更高版本下,而不是 NT 4”。在我写答案之前,我成功地使用 Server 2008R2(AD 域控制器)和 Windows 7 测试了您的代码。至少在这种环境下,Delegate 工作,我什至测试了安全选项(如果不信任委派,它就不起作用......)。不过,可能有更好的选择,请参阅我编辑的答案。
    • 啊,奇怪的是他们还没有为较新的 .NET 版本更新文档嘿。是的,我已经开始使用 PsExec,但很高兴终于知道 WMI 可以用于此。
    【解决方案2】:

    正如原因所述,您在 PC 上使用的用户 ID 似乎无法访问另一台计算机的位置(尽管它是服务器,但它是其他计算机)。

    您可以获取您的用户 ID 的访问权限,或使用模拟来使用已有权访问该位置的用户 ID。

    在此处了解更多详情:https://msdn.microsoft.com/en-us/library/w070t6ka%28v=vs.110%29.aspx

    已编辑:也添加用户名密码。这可能会有所帮助。

    【讨论】:

    • 我已经尝试过这个(见我上面的编辑),但没有运气。我觉得我在连接选项方面遗漏了一些东西......
    猜你喜欢
    • 2010-09-22
    • 2017-10-25
    • 1970-01-01
    • 2011-12-09
    • 2011-03-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多