如何更改现有命名管道的安全性?

时间:2014-09-19 13:51:09

标签: c# c++ windows named-pipes hyper-v

我在Windows 8上使用Hyper V,并希望能够通过命名管道与虚拟串行端口通信。我给管道选择了一个名字,它可以很好地与虚拟操作系统(在我的情况下是XP)串口通信,但由于PipeSecurity设置,只能在Admin用户下进行。

现在我希望能够完全控制Hyper-V创建的命名管道上的每个人。以编程方式或可能具有某些Hyper V设置。我需要能够作为普通用户与虚拟操作系统进行通信。

我知道如何在命名管道上设置某个安全性,我使用NamedPipeServerStream和PipeSecurity对象自行创建。我主要使用C#,但我发现有C ++ API:就像SetSecurityInfo一样。但这些需要现有管道的手柄。

在伪代码中,我想做类似的事情:

SetSecurityInfo(“mypipe”,new PipeAccessRule(“Everyone”,PipeAccessRights.FullControl,AccessControlType.Allow));

任何人都知道如何做到这一点? (C ++或者更喜欢C#)

2 个答案:

答案 0 :(得分:3)

我设法获得了一个可行的C ++解决方案。对于在系统中不是永久性的命名管道,Harry可能需要将此代码嵌入到服务中。

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);

答案 1 :(得分:1)

我在MSDN上发现了这个。看起来很容易遵循:

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

如果您在用户组的PSID上设置了SetSecurityInfo,则阅读该文章,那么它应该是可行的。