我正在使用类似于下面的代码来检查对文件夹/文件的访问。 Source
bool CanAccessFolder( LPCTSTR folderName, DWORD genericAccessRights )
{
bool bRet = false;
DWORD length = 0;
if (!::GetFileSecurity( folderName, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION, NULL, NULL, &length ) &&
ERROR_INSUFFICIENT_BUFFER == ::GetLastError()) {
PSECURITY_DESCRIPTOR security = static_cast< PSECURITY_DESCRIPTOR >( ::malloc( length ) );
if (security && ::GetFileSecurity( folderName, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION
| DACL_SECURITY_INFORMATION, security, length, &length )) {
HANDLE hToken = NULL;
if (::OpenProcessToken( ::GetCurrentProcess(), TOKEN_IMPERSONATE | TOKEN_QUERY |
TOKEN_DUPLICATE | STANDARD_RIGHTS_READ, &hToken )) {
HANDLE hImpersonatedToken = NULL;
if (::DuplicateToken( hToken, SecurityImpersonation, &hImpersonatedToken )) {
GENERIC_MAPPING mapping = { 0xFFFFFFFF };
PRIVILEGE_SET privileges = { 0 };
DWORD grantedAccess = 0, privilegesLength = sizeof( privileges );
BOOL result = FALSE;
mapping.GenericRead = FILE_GENERIC_READ;
mapping.GenericWrite = FILE_GENERIC_WRITE;
mapping.GenericExecute = FILE_GENERIC_EXECUTE;
mapping.GenericAll = FILE_ALL_ACCESS;
::MapGenericMask( &genericAccessRights, &mapping );
if (::AccessCheck( security, hImpersonatedToken, genericAccessRights,
&mapping, &privileges, &privilegesLength, &grantedAccess, &result )) {
bRet = (result == TRUE);
}
::CloseHandle( hImpersonatedToken );
}
::CloseHandle( hToken );
}
::free( security );
}
}
return bRet;
}
此代码在客户计算机(运行我们的应用程序的计算机)上失败,并且对于不在Windows域中的本地用户以及具有基于Samba的网络共享的用户,返回的答案为false。
我们内部的一位Windows专家评论说,也许在上述情况下,网络文件管理器返回的用户SID与在AccessCheck函数中查询权限的SID不匹配。 然后他提到,也许要实现这一目标,我们必须正确创建某种登录令牌,然后模拟它以获得正确的访问权限。
如何模拟域用户(或网络文件管理器允许的某些用户),以便网络文件管理器可以允许我的代码获取正确的访问信息?
任何帮助将不胜感激。
答案 0 :(得分:1)
AccessCheck
并不总是返回true,如果安全描述符不允许访问令牌标识的客户端请求的访问权限,则返回false。
如果您要模拟网络文件管理器允许的域用户,请使用LogonUser
函数(不适用于远程计算机)获取该域用户的令牌,然后ImpersonateLoggedOnUser
允许调用线程模拟该域用户的安全上下文。