远程位置的文件访问检查

File access check on remote location

我正在使用类似于下面的代码来检查对 folders/files 的访问。 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 的网络共享的用户返回错误答案。

我们内部的一位 Windows 专家评论说,也许在上述情况下,网络文件管理器返回的用户 SID 与在 AccessCheck 函数中查询权限的 SID 不匹配。 然后他提到,也许要实现这样的目标,我们必须正确地创建某种登录令牌,然后模拟它以获得正确的访问权限。

如何模拟域用户(或网络文件管理器允许的某些用户)以便网络文件管理器允许我的代码获得正确的访问信息?

任何帮助将不胜感激。

AccessCheck 并不总是 returns 正确,如果安全描述符不允许对访问令牌标识的客户端请求的访问权限,则它 returns 错误。

如果您想模拟网络文件管理器允许的域用户,请使用 LogonUser function(not suitable for remote computer) to get the token of this domain user, then ImpersonateLoggedOnUser,让调用线程模拟此域用户的安全上下文。