更改命名管道访问权限
Change Named Pipe Access Permissions
我使用 System.IO.Pipes
创建了一个命名管道。在我不得不 运行 管理员模式下的程序之前,它工作正常。提升后,客户端无法再连接(客户端未 运行ning 提升)。如果我 运行 客户端作为管理员,它连接正常所以它看起来像一个权限问题。我一直在研究如何解决这个问题,但没有成功(我发现处理 Windows 安全问题令人难以置信)。我的目标是允许任何客户端——无论是否提升——能够连接到管道。
我改变的第一件事是打开具有访问权限的管道:
pipeServer = new NamedPipeServerStream(pipeName,
PipeDirection.InOut,
1,
PipeTransmissionMode.Message,
PipeOptions.Asynchronous,
0x4000,
0x400,
null,
HandleInheritability.Inheritable,
PipeAccessRights.ChangePermissions | PipeAccessRights.AccessSystemSecurity);
然后我把这段代码拼凑在一起。一切正常,直到 SetEntriesInAcl
调用失败:
Error: 0x534
"No mapping between account names and security IDs was done."
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
函数没有 return 值,但似乎成功了。这是调用后的样子:
如有任何帮助,我将不胜感激。
(所有 Win32 函数和数据类型都在 pinvoke.net 上找到。另外,我使用的是 Windows 10。)
我最终不必使用任何本机调用。 PipeSecurity
class 有效。诀窍是我必须将它传递给构造函数:
// 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);
我使用 System.IO.Pipes
创建了一个命名管道。在我不得不 运行 管理员模式下的程序之前,它工作正常。提升后,客户端无法再连接(客户端未 运行ning 提升)。如果我 运行 客户端作为管理员,它连接正常所以它看起来像一个权限问题。我一直在研究如何解决这个问题,但没有成功(我发现处理 Windows 安全问题令人难以置信)。我的目标是允许任何客户端——无论是否提升——能够连接到管道。
我改变的第一件事是打开具有访问权限的管道:
pipeServer = new NamedPipeServerStream(pipeName,
PipeDirection.InOut,
1,
PipeTransmissionMode.Message,
PipeOptions.Asynchronous,
0x4000,
0x400,
null,
HandleInheritability.Inheritable,
PipeAccessRights.ChangePermissions | PipeAccessRights.AccessSystemSecurity);
然后我把这段代码拼凑在一起。一切正常,直到 SetEntriesInAcl
调用失败:
Error: 0x534
"No mapping between account names and security IDs was done."
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
函数没有 return 值,但似乎成功了。这是调用后的样子:
如有任何帮助,我将不胜感激。
(所有 Win32 函数和数据类型都在 pinvoke.net 上找到。另外,我使用的是 Windows 10。)
我最终不必使用任何本机调用。 PipeSecurity
class 有效。诀窍是我必须将它传递给构造函数:
// 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);