Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/windows/15.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Windows 使用线程模拟检查客户端的安全描述符_Windows_Acl_Impersonation - Fatal编程技术网

Windows 使用线程模拟检查客户端的安全描述符

Windows 使用线程模拟检查客户端的安全描述符,windows,acl,impersonation,Windows,Acl,Impersonation,我正在尝试检查客户端文件的访问权限,以便用线程模拟它。 我在MicrosoftDevCenter上查看了这个示例,但它似乎有很多问题 我还有一段代码,但它总是返回false PACL file_dacl = NULL; AutoLocalFreeSDescriptor psd; DWORD dstatus = GetNamedSecurityInfoA(fname2.buf, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,

我正在尝试检查客户端文件的访问权限,以便用线程模拟它。 我在MicrosoftDevCenter上查看了这个示例,但它似乎有很多问题

我还有一段代码,但它总是返回false

      PACL file_dacl = NULL;
      AutoLocalFreeSDescriptor psd;
      DWORD dstatus = GetNamedSecurityInfoA(fname2.buf, SE_FILE_OBJECT, DACL_SECURITY_INFORMATION,
            NULL, NULL, &file_dacl, NULL, &psd.psd);
      if (ERROR_SUCCESS != dstatus) {
         return false;
      }
      AutoCloseHandle security_token;
      // Not sure if OpenAsSelf (3rd arg) should be true or false
      BOOL bstatus = OpenThreadToken(GetCurrentThread(), TOKEN_ALL_ACCESS, true, &security_token.stoken);
      if ((! bstatus) && (GetLastError() == ERROR_NO_TOKEN)) {
         bstatus = OpenProcessToken(GetCurrentProcess(), TOKEN_ALL_ACCESS, &security_token.stoken);
      }
      if (! bstatus) {
         return false;
      }
      GENERIC_MAPPING f_perms_map = {
         FILE_GENERIC_READ,
         FILE_GENERIC_WRITE,
         FILE_GENERIC_EXECUTE,
         FILE_ALL_ACCESS
      };
      DWORD file_exec_access;
      if (perm == 'r') {
         file_exec_access = FILE_GENERIC_READ;
      }
      else if (perm == 'w') {
         file_exec_access = FILE_GENERIC_WRITE;
      }
      else { // perm is 'x'
         file_exec_access = FILE_GENERIC_EXECUTE;
      }
      MapGenericMask(&file_exec_access, &f_perms_map);
      PRIVILEGE_SET priv_set;
      DWORD priv_set_size = sizeof(priv_set);
      DWORD granted_access = 0;
      BOOL have_access = false;
      bstatus = AccessCheck(psd.psd, security_token.stoken, file_exec_access, &f_perms_map,
            &priv_set, &priv_set_size, &granted_access, &have_access);

      DWORD d = GetLastError();
      LPSTR messageBuffer = nullptr;
      size_t size = FormatMessageA(FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM | FORMAT_MESSAGE_IGNORE_INSERTS,
          NULL, d, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPSTR)&messageBuffer, 0, NULL);

      std::string message(messageBuffer, size);

      //Free the buffer.
      LocalFree(messageBuffer);
      if (bstatus) {
         return (have_access != 0);
      }
      else {
         return false;
      }

问题是与客户端本身有关还是与代码有关?

返回false,因为
AccessCheck
失败(在本例中,这是错误代码?)还是因为
have\u access
false?访问检查需要模拟令牌,因此需要复制进程令牌。此外,如果安全描述符没有所有者和组安全标识符,则检查失败。所有者影响(隐式)所有者权限条目的评估。它还应该有标签信息,以防标签拒绝对完整性级别较低的受试者进行读、写或执行访问。此外,如果未授予读取访问权限,则必须在掩码中没有读取属性的情况下重试。如果成功,则如果父目录授予读取数据访问权限,则授予通用读取访问权限。此外,这不考虑使用启用SEBACKUPPRIVIEGE或SERESTOREPRIVIEGE的备份语义的打开。最终,最简单也是最好的文件访问检查方法是在模拟时调用
CreateFile
,让文件系统为您解决所有这些问题。此外,使用宽字符
getnamedsecuritynfow
代替ANSI
getnamedsecuritynfoa
。ANSI API几乎已被弃用(应该如此)。找出如何最好地使用Unicode满足您的需求。有时候,在Windows开发中,最好在任何地方都使用
WCHAR
(UTF-16)。但您可能有UTF-8互操作要求,这使得仅为WinAPI调用使用UTF-8并将字符串参数转换为UTF-16更为全面。@RbMm因为accesscheck失败,错误是“当前未模拟客户端的线程试图对模拟令牌进行操作”