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

Я использую Hyper V в Windows 8 и хотел бы иметь возможность обмениваться данными с виртуальным последовательным портом через именованный канал. Я даю каналу имя по выбору, и он хорошо работает, взаимодействуя с последовательным портом виртуальной ОС (XP, в моем случае), но только под пользователем Admin из-за настроек PipeSecurity.

Теперь я хотел бы иметь возможность предоставить полный контроль для всех в именованном канале, созданном Hyper-V. Программно или, может быть, с какой-то настройкой Hyper V. Мне нужно иметь возможность общаться с виртуальной ОС как обычный пользователь.

Я знаю, как установить определенную безопасность для именованного канала, который я создаю сам, используя NamedPipeServerStream вместе с объектом PipeSecurity. В основном я использую C#, но вижу, что существуют API C++, такие как SetSecurityInfo. Но для этого требуется дескриптор существующей трубы.

В псевдокоде я хотел бы сделать что-то вроде:

SetSecurityInfo("mypipe", new PipeAccessRule("Все", PipeAccessRights.FullControl, AccessControlType.Allow));

Кто-нибудь знает, как это сделать? (С++ или предпочтительно С#)


person SolSken    schedule 19.09.2014    source источник
comment
Можно открыть клиентский конец канала с помощью CreateFile, а затем использовать этот дескриптор с SetSecurityInfo. Сначала я бы попробовал режим доступа WRITE_DAC, но вам, возможно, придется немного поэкспериментировать. Также может помочь включение SeBackupPrivilege и SeRestorePrivilege перед вызовом CreateFile. Попробуйте сначала на C, C# только усложнит ситуацию, если вы заработаете на C, вы всегда сможете портировать его позже. В противном случае напишите службу, которая открывает именованный канал от имени клиентского процесса. Вы можете использовать DuplicateHandle для копирования дескриптора в клиентский процесс.   -  person Harry Johnston    schedule 20.09.2014


Ответы (2)


Мне удалось получить рабочее решение на С++. Идея Гарри по внедрению этого кода в службу может понадобиться для именованных каналов, которые не являются постоянными в системе.

HANDLE hPipe = CreateFile(L"\\\\.\\pipe\\mypipe", GENERIC_WRITE | WRITE_DAC, 0, NULL, OPEN_EXISTING, NULL, NULL);  
if (hPipe != INVALID_HANDLE_VALUE)
{      

  PACL pOldDACL = NULL;  
  if(GetSecurityInfo(hPipe, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, &pOldDACL, NULL, NULL) == ERROR_SUCCESS)
  {
    TRUSTEE trustee[1];
    trustee[0].TrusteeForm = TRUSTEE_IS_NAME;
    trustee[0].TrusteeType = TRUSTEE_IS_GROUP;
    trustee[0].ptstrName = _T("Everyone");
    trustee[0].MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
    trustee[0].pMultipleTrustee = NULL;

    EXPLICIT_ACCESS explicit_access_list[1];
    ZeroMemory(&explicit_access_list[0], sizeof(EXPLICIT_ACCESS));

    explicit_access_list[0].grfAccessMode = GRANT_ACCESS;
    explicit_access_list[0].grfAccessPermissions = GENERIC_ALL;
    explicit_access_list[0].grfInheritance = NO_INHERITANCE;
    explicit_access_list[0].Trustee = trustee[0];

    PACL pNewDACL = NULL;
    if(SetEntriesInAcl(1, explicit_access_list, pOldDACL, &pNewDACL) == ERROR_SUCCESS)
    {
      if(SetSecurityInfo(hPipe, SE_KERNEL_OBJECT, DACL_SECURITY_INFORMATION, NULL, NULL, pNewDACL, NULL) != ERROR_SUCCESS)
      {
        //Error handling              
        DWORD dw = GetLastError();          
      }
      LocalFree(pNewDACL);
    }
    else
    {
      //Error handling        
      GetLastError();
    }
    LocalFree(pOldDACL);
  }
  else
  {
    //Error
    GetLastError();
  }
}
else
{
  //Error handling
  DWORD dw = GetLastError();       
}  
CloseHandle(hPipe);
person SolSken    schedule 22.09.2014

Я нашел это в MSDN. Выглядит достаточно легко, чтобы следовать:

http://msdn.microsoft.com/en-gb/library/windows/desktop/aa365600(v=vs.85).aspx

Читая статью, если вы SetSecurityInfo для PSID вашей группы пользователей, тогда это должно быть выполнимо.

person GlGuru    schedule 19.09.2014