AccessCheck() doesn't work with network mapped driver

  • Thread starter Thread starter Bo Schwarzstein
  • Start date Start date
B

Bo Schwarzstein

Guest
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-3058
RW S-1-5-21-825604914-2373088077-4039564966-3052
RW S-1-5-21-825604914-2373088077-4039564966-3048
RW S-1-5-21-825604914-2373088077-4039564966-3054
RW S-1-5-21-825604914-2373088077-4039564966-3066

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,

int ArchFileAccess(const char* path, int mode)
{
// Simple existence check is handled specially.
if (mode == F_OK) {
return (GetFileAttributes(path) != INVALID_FILE_ATTRIBUTES)
? 0 : Arch_FileAccessError();
}

const SECURITY_INFORMATION securityInfo = OWNER_SECURITY_INFORMATION |
GROUP_SECURITY_INFORMATION |
DACL_SECURITY_INFORMATION;

// Get the SECURITY_DESCRIPTOR size.
DWORD length = 0;
if (!GetFileSecurity(path, securityInfo, NULL, 0, &length)) {
if (GetLastError() != ERROR_INSUFFICIENT_BUFFER) {
return Arch_FileAccessError();
}
}

// Get the SECURITY_DESCRIPTOR.
std::unique_ptr<unsigned char[]> buffer(new unsigned char[length]);
PSECURITY_DESCRIPTOR security = (PSECURITY_DESCRIPTOR)buffer.get();
if (!GetFileSecurity(path, securityInfo, security, length, &length)) {
return Arch_FileAccessError();
}


HANDLE token;
DWORD desiredAccess = TOKEN_IMPERSONATE | TOKEN_QUERY |
TOKEN_DUPLICATE | STANDARD_RIGHTS_READ;
if (!OpenThreadToken(GetCurrentThread(), desiredAccess, TRUE, &token))
{
if (!OpenProcessToken(GetCurrentProcess(), desiredAccess, &token))
{
CloseHandle(token);
errno = EACCES;
return -1;
}
}

bool result = false;
HANDLE duplicateToken;
if (DuplicateToken(token, SecurityImpersonation, &duplicateToken))
{
PRIVILEGE_SET privileges = {0};
DWORD grantedAccess = 0;
DWORD privilegesLength = sizeof(privileges);
BOOL accessStatus = FALSE;

GENERIC_MAPPING mapping;
mapping.GenericRead = FILE_GENERIC_READ;
mapping.GenericWrite = FILE_GENERIC_WRITE;
mapping.GenericExecute = FILE_GENERIC_EXECUTE;
mapping.GenericAll = FILE_ALL_ACCESS;

DWORD accessMask = ArchModeToAccess(mode);
MapGenericMask(&accessMask, &mapping);

if (AccessCheck(security,
duplicateToken,
accessMask,
&mapping,
&privileges,
&privilegesLength,
&grantedAccess,
&accessStatus))
{
if (accessStatus) {
result = true;
}
else {
errno = EACCES;
}
}
CloseHandle(duplicateToken);
}
CloseHandle(token);

return result ? 0 : -1;
}

Any idea on this ? Thanks a lot !

Continue reading...
 
Back
Top