Страницы

Поиск по вопросам

четверг, 20 июня 2019 г.

Как подключиться к именованному каналу без прав администратора?

Привет. Есть два приложения на C# - служба (windows service, для службы был указан Account LocalSystem) и клиентское приложение(обычное windows приложение, в данном случае консольное), которые обмениваются информацией по именованным каналам (Named Pipes). Проблема в том, что клиентское приложение может подключиться к службе по именованному каналу только с правами администратора.
Нашёл в сети решение, в котором предлагается назначить серверному именованному каналу PipeSecurity, содержащий один или более PipeAccessRule. После применения этого подхода серверное приложение падает с исключением System.UnauthorizedAccessException. Подскажите, как по именованному каналу осуществить подключение к службе клиентского приложения, которое запущено без прав админа? Делаю так:
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(); }
Клиент:
using (var pipe = new NamedPipeClientStream(".", "test", PipeDirection.InOut)) { pipe.Connect(); pipe.WriteByte(100); int x = pipe.ReadByte(); Console.WriteLine(x); }
Пробовал также в коде службы WindowsIdentity.GetCurrent().Name менять на "Everyone", но в этом случае исключение System.Security.Principal.IdentityNotMappedException.


Ответ

Попробуйте такую реализацию:
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();

Комментариев нет:

Отправить комментарий