cyanfish / grpc-dotnet-namedpipes

Named pipe transport for gRPC in C#/.NET
Apache License 2.0
190 stars 48 forks source link

[Question] How to deal with elevation on the server-side? #64

Closed nicolaihenriksen closed 4 months ago

nicolaihenriksen commented 4 months ago

Hi

I have attached a small sample client/server app to illustrate what I am trying to achieve.

Basically, I would like the client application to be able to communicate with the server regardless of which elevation (normal user vs. admin user) the server was started with. I cannot seem to get this configured correctly, and perhaps it is not even possible.

If the server is not running elevated, then it does not matter if the client is elevated or not; both cases work. But it is a different story when the server is elevated. In the latter case it only works if the client is also elevated.

I assume I need to - somehow - use the PipeSecurity type to control this, but I cannot seem to figure out exactly how. Any help/guidance would be appreciated.

The (typical) use case for this, is some devs in my team running their IDE as admin, and will be debugging a "server" application while simply starting a (non-elevated) client application on the side to communicate with it.

I am getting the following exception:

System.UnauthorizedAccessException: Access to the path is denied.
   at System.IO.Pipes.NamedPipeClientStream.TryConnect(Int32 timeout, CancellationToken cancellationToken)
   at System.IO.Pipes.NamedPipeClientStream.ConnectInternal(Int32 timeout, CancellationToken cancellationToken, Int32 startTime)
   at System.IO.Pipes.NamedPipeClientStream.<>c__DisplayClass20_0.<ConnectAsync>b__0()
   at System.Threading.Tasks.Task.InnerInvoke()
   at System.Threading.Tasks.Task.<>c.<.cctor>b__272_0(Object obj)
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
--- End of stack trace from previous location ---
   at System.Threading.ExecutionContext.RunFromThreadPoolDispatchLoop(Thread threadPoolThread, ExecutionContext executionContext, ContextCallback callback, Object state)
   at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot, Thread threadPoolThread)
--- End of stack trace from previous location ---
   at GrpcDotNetNamedPipes.Internal.ClientConnectionContext.ConnectPipeWithRetries()
   at GrpcDotNetNamedPipes.Internal.ClientConnectionContext.ConnectPipeWithRetries()
   at GrpcDotNetNamedPipes.Internal.ClientConnectionContext.<>c__DisplayClass23_0`2.<<InitCall>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at GrpcDotNetNamedPipes.Internal.MessageReader`1.MoveNext(CancellationToken cancellationToken)
   at GrpcDotNetNamedPipes.Internal.MessageReader`1.<>c__DisplayClass9_0.<<ReadNextMessage>b__0>d.MoveNext()
--- End of stack trace from previous location ---
   at Program.<Main>$(String[] args) in C:\Users\nih\source\repos\GrpcNamedPipesIssue\Client\Program.cs:line 22

GrpcNamedPipesIssue.zip

cyanfish commented 4 months ago

Have a look here: https://stackoverflow.com/questions/51546328/change-named-pipe-access-permissions

And then you can pass PipeSecurity into the NamedPipeServerOptions.

nicolaihenriksen commented 4 months ago

Have a look here....

Worked like a charm! Thank you very much.

And apparently I need to work on my "googling skills" 🤣