Привет. Есть два приложения на 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();
Комментариев нет:
Отправить комментарий