命名管道客户端在调用SetAccessControl时抛出UnauthorizedAccessException

时间:2015-01-19 07:41:12

标签: c# .net named-pipes

我正在尝试用c#编写命名管道客户端,但是在调用UnauthorizedAccessException时我得到SetAccessControl()

{System.UnauthorizedAccessException: Attempted to perform an unauthorized operation.
   at System.Security.AccessControl.Win32.SetSecurityInfo(ResourceType type, String name, SafeHandle handle, SecurityInfos securityInformation, SecurityIdentifier owner, SecurityIdentifier group, GenericAcl sacl, GenericAcl dacl)
   at System.Security.AccessControl.NativeObjectSecurity.Persist(String name, SafeHandle handle, AccessControlSections includeSections, Object exceptionContext)
   at System.Security.AccessControl.NativeObjectSecurity.Persist(SafeHandle handle, AccessControlSections includeSections)
   at System.IO.Pipes.PipeSecurity.Persist(SafeHandle handle)
   at NamePipeEx.Program.Main(String[] args) in c:\Users\zangw\Documents\Visual Studio 2013\Projects\NamePipeEx\NamePipeEx\Program.cs:line 27
   at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
   at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
   at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
   at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.ThreadHelper.ThreadStart()}

这是我的代码

    PipeAccessRule pr = new PipeAccessRule("Everyone", PipeAccessRights.ReadWrite, System.Security.AccessControl.AccessControlType.Allow);
    PipeSecurity ps = new PipeSecurity();
    ps.AddAccessRule(pr);
    var client = new NamedPipeClientStream(".", "logpipe", PipeDirection.In, PipeOptions.WriteThrough);
    // connect to the server
    client.Connect();
    client.SetAccessControl(ps);
    client.ReadMode = PipeTransmissionMode.Message;

请帮我弄清楚我的代码的失败原因。

编辑在C ++中添加命名管道服务器代码

HANDLE hPipe;
LPTSTR lpPipeName = TEXT("\\\\.\\pipe\\logpipe");

// try to open a named pipe
hPipe = CreateNamedPipe(lpPipeName, PIPE_ACCESS_DUPLEX, PIPE_TYPE_MESSAGE|PIPE_READMODE_MESSAGE|PIPE_WAIT, 
                        PIPE_UNLIMITED_INSTANCES, 2048, 2048, NMPWAIT_USE_DEFAULT_WAIT, NULL);

if (hPipe == INVALID_HANDLE_VALUE){
    printf("Pipe handler error");
    //return -1;
}

if (!ConnectNamedPipe(hPipe, NULL)){
    if (GetLastError() != ERROR_PIPE_CONNECTED){
        printf("FAILED to connect ");
    }
}

printf("Client named pipe connected...");
// send message to named pipe

LPTSTR msg = TEXT("Default message from server...\r\n");
DWORD cbToWrite = lstrlen(msg) + 1;

while (true){
    DWORD cbWritten = 0;
    bool fSuccess = WriteFile(hPipe, msg, cbToWrite, &cbWritten, NULL);
    if (!fSuccess)
        printf("Failed to writefile pipe");
}

3 个答案:

答案 0 :(得分:0)

因为使用默认安全描述符,只有管理员或系统用户可以连接到管道。

  

命名管道的默认安全描述符中的ACL授予对LocalSystem帐户,管理员和创建者所有者的完全控制权。他们还授予Everyone组成员和匿名帐户的读取权限。换句话说,如果使用NULL作为安全属性,则命名管道不能通过网络与作为较低完整性级别运行的本地客户端的WRITE权限连接。

要授予每个人对服务器的所有访问权限(不仅仅是连接访问权限),您需要fill the security attributes

答案 1 :(得分:0)

我在使用NamedPipeClientStream PipeAccessRights的另一个构造函数时解决了这个问题。

    var client = new NamedPipeClientStream(".", "logpipe", PipeAccessRights.FullControl, 
        PipeOptions.WriteThrough, System.Security.Principal.TokenImpersonationLevel.None, HandleInheritability.None);

答案 2 :(得分:0)

我有类似的问题:

System.UnauthorizedAccessException: Attempted to perform an unauthorized operation.

当我的服务器将管道方向定义为PipeDirection.In时,我的客户端也将其定义为PipeDirection.In(一个必须为PipeDirection.Out,或者如果两者都需要读取,请使用PipeDirection.InOut /写)。

我在这里回答是因为UnauthorizedAccessException并不总是出于安全问题,也许可以帮助其他人。