【问题标题】:File access check on remote location远程位置的文件访问检查
【发布时间】:2019-06-06 10:25:57
【问题描述】:

我正在使用类似于下面的代码来检查对文件夹/文件的访问。 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 不匹配。 然后他提到,也许,为了实现这样的事情,我们必须正确创建某种登录令牌,然后模拟它以获得正确的访问权限。

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

任何帮助将不胜感激。

【问题讨论】:

  • 不确定,您为什么要这样做。只需访问该资源,操作系统就会让您知道您是否可以访问它。也没有 TOCTTOU 比赛。

标签: windows winapi samba dacl


【解决方案1】:

AccessCheck 并不总是返回 true,如果安全描述符不允许访问令牌所标识的客户端所请求的访问权限,则返回 false。

如果要模拟网络文件管理器允许的域用户,使用LogonUser函数(不适合远程计算机)获取该域用户的令牌,然后ImpersonateLoggedOnUser,让调用线程模拟安全上下文此域用户的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2018-12-24
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多