【问题标题】:NamedPipeClientStream throws UnauthorizedAccessException: Access to the path is deniedNamedPipeClientStream 抛出 UnauthorizedAccessException:对路径的访问被拒绝
【发布时间】:2022-01-21 10:55:58
【问题描述】:

我已经查看了很多类似的问题,但似乎没有一个涵盖这个案例。所以在假设它是重复的之前请检查详细信息。

场景: 我有一个用 C# 编写的面向 .NET Framework 4.7.2 的客户端和服务器应用程序,分别使用 NamedPipeClientStream 和 NamedPipeServerStream 进行通信。

服务器以本地管理员帐户运行,并像这样创建 NamedPipeServerStream:

PipeSecurity ps = new PipeSecurity();
ps.AddAccessRule(new PipeAccessRule(WindowsIdentity.GetCurrent().Owner, PipeAccessRights.FullControl, AccessControlType.Allow));
ps.AddAccessRule(new PipeAccessRule(new SecurityIdentifier("S-1-5-32-544"), PipeAccessRights.ReadWrite, AccessControlType.Allow));
NamedPipeServerStream mypipe = new NamedPipeServerStream("mypipe", PipeDirection.Out, 1, 0, PipeOptions.WriteThrough, 0, 0, ps);
mypipe.WaitForConnection();

在服务器上,我创建了一个名为“testuser”的本地帐户,它是本地管理员组的成员。当通过网络连接到命名管道时,此帐户用于在客户端进行身份验证。

客户端程序以本地用户身份在通过网络连接的另一台计算机上运行,​​并创建如下连接:

NamedPipeClientStream mypipe = new NamedPipeClientStream("<ip of server>", "mypipe", PipeDirection.In, PipeOptions.None);
mypipe.Connect();

在 Windows Server 2012 上运行服务器软件时,它可以正常工作。但是在 Windows Server 2016 和 Windows Server 2019 上,我得到了 UnauthorizedAccessException。如果不是我的本地用户“testuser”,而是通过网络使用内置管理员帐户进行身份验证,它在所有三个版本的 windows 服务器上都可以正常工作。

如果我更改管道安全性以使用例如 S-1-5-11 的 SID 以允许“经过身份验证的用户”,它也适用于所有三个版本,但要求是只允许来自本地管理员组的成员通过网络连接到服务器。理想情况下,该帐户是本地帐户还是域帐户应该无关紧要,但我只使用本地帐户进行了测试。

我在服务器上使用事件查看器进行了一些调试,当我的测试用户访问管道时,我可以看到事件 5145(详细文件共享)审核成功,但客户端仍然报告 UnauthorizedAccessException。

有什么方法可以限制只有 Windows Server 2016 和 2019 上本地管理员组成员的访问权限?

【问题讨论】:

  • 客户端的testuser和服务端的testuser有什么关系?这只有在他们都具有相同的密码并且使用 NTLM(本地帐户、非域身份验证)时才有效。为什么不为此使用适当的域帐户?
  • @Charlieface testuser 仅作为本地帐户存在于服务器上。在客户端上运行代码时,我必须对服务器进行身份验证才能打开到 SMB 共享“IPC$”的连接以访问命名管道。因此,在客户端上打开一个对话框以输入网络凭据,我在其中提供服务器的本地管理员帐户或我的 testuser 凭据。我希望我的程序能够灵活地在我只能访问本地帐户的凭据的情况下工作。重要的是帐户(本地或域)应该是本地管理员
  • 在为远程机器的本地用户输入凭据时,您必须输入RemoteMachineName\Username。域用户会容易得多,因为两者都会自动识别它。您可以将域用户添加到服务器上的本地管理员。
  • 请不要关注域用户部分。我认为这与问题无关,而且我知道我可以提供RemoteMachineName,但对于例如.\Username 来说并不严格要求。 Windows 为我处理它。正如我所说,事件查看器中的日志确认我的身份验证正确。

标签: c# window named-pipes


【解决方案1】:

如果其他人遇到这个问题,我找到了原因。 问题是“UAC 远程限制”。更多信息可以在 Microsoft 的 KB 951016 中找到

如果本地帐户是 Builtin\Administrators 组的成员并通过网络进行身份验证,例如对 SMB 共享(如 \\remotecomputer\C$ 或命名管道)进行身份验证,则该帐户将不会作为“完整”管理员进行身份验证,因此无权访问管理资源。必须从 RDP 等交互式登录中提升此类帐户才能获得完全的管理权限。因此,由于此安全功能,我的内置帐户方案不起作用。

似乎有三种方法可以处理这个问题。

  1. 在注册表中禁用此安全措施(可能不推荐)。
  2. 使用域帐户并将其添加为本地管理员。此安全限制似乎只影响SAM(本地)帐户。
  3. 仅使用内置管理员帐户,因为这也不受安全限制的影响。

注意,如果注册表编辑不正确,可能会造成严重后果。因此,在执行任何更改之前备份注册表。以下说明基于 Microsoft 关于该主题的文章:

要禁用注册表中的限制:

  1. 使用regedit打开注册表并选择以下键: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Policies\System
  2. 如果不存在,则创建以下键(键入 DWORD),否则只需将其编辑为值为 1:LocalAccountTokenFilterPolicy

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2019-05-26
    • 1970-01-01
    • 2021-04-02
    • 1970-01-01
    • 2017-01-24
    相关资源
    最近更新 更多