如果客户端和服务器在不同的机器上,则无法在 NamedPipes 中模拟权限

Posted

技术标签:

【中文标题】如果客户端和服务器在不同的机器上,则无法在 NamedPipes 中模拟权限【英文标题】:can not Impersonate the permission in the NamedPipes if client and server are in the different machines 【发布时间】:2013-04-07 17:34:44 【问题描述】:

我得到了 UnknownErrorException,命名管道的错误代码为 1346,代码如下 (注意:客户端和服务器在不同的机器上)

服务器代码:

public static void ReadFile()

    string contents = File.ReadAllText(@"d:\123.txt");   <-- exception


public static void Main()
    
    var pipe = new NamedPipeServerStream("testpipe", PipeDirection.InOut);
    while (true)
    
        pipe.WaitForConnection();
        pipe.RunAsClient(ReadFile);
    

客户端代码

 NamedPipeClientStream pipeClient =
                new NamedPipeClientStream("\\jachang-w1", "testpipe",
                    PipeDirection.InOut, PipeOptions.None,
                    TokenImpersonationLevel.Impersonation);
 pipeClient.Connect();

我从google搜索了信息,发现错误是“ERROR_BAD_IMPERSONATION_LEVEL,没有提供所需的模拟级别,或者提供的模拟级别无效”

但是我已经在客户端设置了 TokenImpersonationLevel.Impersonation,所以服务器应该可以访问它。有人能告诉我这是怎么回事吗?我该怎么办?

谢谢

【问题讨论】:

这是域用户还是两个本地用户(每台非域计算机上一个)具有相同的登录名和密码? 服务器和客户端都是域用户登录的。如果我登录服务器并直接打开,我可以读取 d:\123.txt。如果客户端也在 jachang-w1 上运行,代码确实可以工作。 客户端和服务器使用同一个域用户账号登录。 (对不起,忘了提...) 【参考方案1】:

为了让服务器进程模拟具有令牌模拟级别Impersonate的客户端,它自己的进程标识必须具有安全权限SeImpersonatePrivilege,并且必须启用此权限。

即使客户端和服务器帐户身份是同一个域帐户也是如此。

我猜您正在测试的域帐户没有此权限,或者没有启用它。当您调用RunAsClient 时,将创建一个线程令牌,但这不会被授予请求的模拟级别,因为该进程缺少所需的权限:该级别将“降级”到Identification。然后,当调用ReadAllText 时,在此方法的实现中,Windows 安全 API 将用于根据文件的访问控制列表检查线程令牌。会发现令牌不具备成功读取文件所需的模拟级别,并会引发您看到的错误。

要解决此问题,您必须找到某种方法来确保您的服务器进程以具有所需权限的身份运行。

【讨论】:

以上是关于如果客户端和服务器在不同的机器上,则无法在 NamedPipes 中模拟权限的主要内容,如果未能解决你的问题,请参考以下文章

Client-Server 在不同的机器和多个客户端上运行

在 SFML 上检测到多个按键,无法以任何其他方式解决,并且在不同机器上的工作方式不同

使用 Visual Studio 2010 在 C# 中的两台不同机器上运行的客户端和服务器之间的通信

一个大小写引起的SVN无法Commit的问题

GWT - 将客户端和服务器拆分到不同的机器

SVN:无法连接主机“localhost”:由于目标机器积极拒绝,无法连接