繁体   English   中英

更改命名管道访问权限

[英]Change Named Pipe Access Permissions

我已经使用System.IO.Pipes创建了一个命名管道。 在我不得不以管理员模式运行该程序之前,它运行良好。 提升后,客户端将无法连接(客户端未在提升状态下运行)。 如果我以管理员身份运行客户端,则连接正常,因此看起来像是权限问题。 我一直在研究如何解决此问题,但一直没有成功(我发现处理Windows安全性令人感到困惑)。 我的目标是允许任何客户端(无论是否提升)都可以连接到管道。

我更改的第一件事是使用访问权限打开管道:

pipeServer = new NamedPipeServerStream(pipeName,
                                       PipeDirection.InOut,
                                       1,
                                       PipeTransmissionMode.Message,
                                       PipeOptions.Asynchronous,
                                       0x4000,
                                       0x400,
                                       null,
                                       HandleInheritability.Inheritable,
                                       PipeAccessRights.ChangePermissions | PipeAccessRights.AccessSystemSecurity);

然后我将这段代码拼凑在一起。 一切正常,直到SetEntriesInAcl调用失败为止:

错误:0x534
“在帐户名和安全性ID之间未完成映射。”

IntPtr ownerSid = IntPtr.Zero;
IntPtr groupSid = IntPtr.Zero;
IntPtr dacl = IntPtr.Zero, newDacl = IntPtr.Zero;
IntPtr sacl = IntPtr.Zero;
IntPtr securityDescriptor = IntPtr.Zero;
if (SUCCEEDED(GetSecurityInfo(pipeServer.SafePipeHandle.handle.DangerousGetHandle(),                                                  
                              SE_OBJECT_TYPE.SE_KERNEL_OBJECT,
                              SECURITY_INFORMATION.DACL_SECURITY_INFORMATION,
                              out ownerSid,
                              out groupSid,
                              out dacl,
                              out sacl,
                              out securityDescriptor))) {
    EXPLICIT_ACCESS ea = new EXPLICIT_ACCESS();
    BuildExplicitAccessWithName(ref ea, "Everyone", GENERIC_ALL, ACCESS_MODE.GRANT_ACCESS, NO_INHERITANCE);
    // Next line fails
    if (SUCCEEDED(SetEntriesInAcl(1, ref ea, dacl, out newDacl))) {
        uint retval = SetSecurityInfo(handle,
                             SE_OBJECT_TYPE.SE_KERNEL_OBJECT,
                             SECURITY_INFORMATION.DACL_SECURITY_INFORMATION,
                             IntPtr.Zero,
                             IntPtr.Zero,
                             newDacl,
                             IntPtr.Zero);
                        // Haven't reached this point yet
    }
}

BuildExplicitAccessWithName函数不返回值,但似乎可以成功。 通话后的样子如下: 在此处输入图片说明

在这里,我将不胜感激。

(所有Win32函数和数据类型都在pinvoke.net上找到。此外,我使用的是Windows10。)

我最终不必使用任何本地电话。 PipeSecurity类起作用。 诀窍是我必须将其传递给构造函数:

// Creates a PipeSecurity that allows users read/write access
PipeSecurity CreateSystemIOPipeSecurity()
{
    PipeSecurity pipeSecurity = new PipeSecurity();

    var id = new SecurityIdentifier(WellKnownSidType.AuthenticatedUserSid, null);

    // Allow Everyone read and write access to the pipe. 
    pipeSecurity.SetAccessRule(new PipeAccessRule(id, PipeAccessRights.ReadWrite, AccessControlType.Allow));

    return pipeSecurity;
} 

创建管道时使用该函数:

PipeSecurity pipeSecurity = CreateSystemIOPipeSecurity();
pipeServer = new NamedPipeServerStream(pipeName,
                                       PipeDirection.InOut,
                                       1,
                                       PipeTransmissionMode.Message,
                                       PipeOptions.Asynchronous,
                                       0x4000,
                                       0x400,
                                       pipeSecurity,
                                       HandleInheritability.Inheritable);

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM