Windows 使用线程模拟检查客户端的安全描述符
我正在尝试检查客户端文件的访问权限,以便用线程模拟它。 我在MicrosoftDevCenter上查看了这个示例,但它似乎有很多问题 我还有一段代码,但它总是返回falseWindows 使用线程模拟检查客户端的安全描述符,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,
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
代替ANSIgetnamedsecuritynfoa
。ANSI API几乎已被弃用(应该如此)。找出如何最好地使用Unicode满足您的需求。有时候,在Windows开发中,最好在任何地方都使用WCHAR
(UTF-16)。但您可能有UTF-8互操作要求,这使得仅为WinAPI调用使用UTF-8并将字符串参数转换为UTF-16更为全面。@RbMm因为accesscheck失败,错误是“当前未模拟客户端的线程试图对模拟令牌进行操作”