Asked by:
AccessCheck() doesn't work with network mapped driver

Question
-
Hi
We have a NAS installed locally and mapped a folder as local driver letter, such W .
In order to establish the mapping driver, the credential of NAS must be input, and Windows 10 knows about it, any operation from Explorer works as usual.
By using AccessChk tools, it prints the SID starts with S-1-5-21, it means SECURITY_NT_NON_UNIQUE
Accesschk v6.12 - Reports effective permissions for securable objects Copyright (C) 2006-2017 Mark Russinovich Sysinternals - www.sysinternals.com W:\temp RW S-1-5-21-825604914-2373088077-4039564966-1203 RW S-1-5-21-825604914-2373088077-4039564966-3052 RW S-1-5-21-825604914-2373088077-4039564966-3048
Print current user's SID
USER INFORMATION ---------------- User Name SID ========= ============================================= 3fasd6sf\user S-1-5-21-3089250728-987539432-1982516474-1001
Now we have a program needs to check if current process has permission to read/write/execute a file under an existed folder such as W:\temp, by API AccessCheck() always return 5 = ACCESS_DENIED,
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;
}int main(int argc, char *argv[])
{
bool can = CanAccessFolder(argv[1], FILE_GENERIC_WRITE);
if (can) {
printf("OK");
} else {
printf("BAD");
}return 0;
}
Any idea on this ? Thanks a lot !
- Edited by Bo Schwarzstein Wednesday, August 26, 2020 6:39 AM
- Moved by Jeanine ZhangMicrosoft contingent staff Friday, August 28, 2020 6:15 AM
Wednesday, August 26, 2020 4:43 AM
All replies
-
Hi,
Thank you for posting here.
According to the issue, it is more related to the winapi. I suggest you should ask it in Winapi-General forum for better help.
Best Regards,
Jeanine Zhang
"Visual c++" forum will be migrating to a new home on Microsoft Q&A !
We invite you to post new questions in the "Developing Universal Windows apps" forum’s new home on Microsoft Q&A !
For more information, please refer to the sticky post.Wednesday, August 26, 2020 7:20 AM -
I suggest you read this MS blog article - Be careful when interpreting security descriptors across machine boundaries
I think the best advice is the last paragraph --"The moral of the story is that trying to determine whether you have access to an object without actually accessing it is harder than it looks. You’re usually much better off just trying to access it. No point trying to emulate what another computer is going to do if you can just have it do it!"
Wednesday, August 26, 2020 9:42 AM