Hey. There are two applications in C # - a service (windows service, for the service Account LocalSystem was specified) and a client application (normal windows application, in this case console), which exchange information on named pipes (Named Pipes). The problem is that the client application can connect to the service via a named pipe only with administrator rights.

Found a solution on the network proposing to assign a PipeSecurity server named pipe containing one or more PipeAccessRule. After applying this approach, the server application crashes with the exception System.UnauthorizedAccessException. Tell me, how can I connect to the service of a client application that is running without admin rights via a named pipe? I do this:

Windows service

protected override void OnStart(string[] args) { new Thread(() => { while (true) { using (var pipe = new NamedPipeServerStream("test", PipeDirection.InOut, 1, PipeTransmissionMode.Byte)) { var ps = new PipeSecurity(); ps.AddAccessRule(new PipeAccessRule(WindowsIdentity.GetCurrent().Name, PipeAccessRights.FullControl, AccessControlType.Allow)); pipe.SetAccessControl(ps); pipe.WaitForConnection(); int x = pipe.ReadByte(); pipe.WriteByte((byte)(x + 1)); } } }) { IsBackground = true }.Start(); } 

Customer:

 using (var pipe = new NamedPipeClientStream(".", "test", PipeDirection.InOut)) { pipe.Connect(); pipe.WriteByte(100); int x = pipe.ReadByte(); Console.WriteLine(x); } 

I also tried changing the code of the WindowsIdentity.GetCurrent (). Name service to “Everyone”, but in this case the exception is System.Security.Principal.IdentityNotMappedException.

  • Try to pass a new SecurityIdentifier(WellKnownSidType.WorldSid, null) expression to the PipeAccessRule instead of the first parameter new SecurityIdentifier(WellKnownSidType.WorldSid, null) - kmv
  • In this case, there is also a System.UnauthorizedAccessException exception when trying to assign a PipeSecurity channel. - VasiliyL

1 answer 1

Try this implementation:

 new Thread(() => { var ps = new PipeSecurity(); // себе разрешаем все ps.AddAccessRule( new PipeAccessRule( WindowsIdentity.GetCurrent().Owner, PipeAccessRights.FullControl, AccessControlType.Allow)); // остальным только чтение/запись в пайп ps.AddAccessRule( new PipeAccessRule( new SecurityIdentifier(WellKnownSidType.WorldSid, null), PipeAccessRights.ReadWrite, AccessControlType.Allow)); while (true) { // параметры безопасности передаем в конструктор, а не в SetAccessControl using (var pipe = new NamedPipeServerStream("test", PipeDirection.InOut, 1, PipeTransmissionMode.Byte, PipeOptions.None, 0, 0, ps)) { pipe.WaitForConnection(); int x = pipe.ReadByte(); pipe.WriteByte((byte)(x + 1)); } } }) { IsBackground = true }.Start(); 
  • Thank! It really works. - VasiliyL