Please Help with File Access
-
I am trying to check if I have the proper access to a file. Here is my testing program
#include #include typedef int TBK_BOOL; typedef int TBK_PERMISSIONS; #define TBK_TRUE 1 #define TBK_FALSE 0 #define F_OK 0 /* exists */ #define X_OK 1 /* executable */ #define W_OK 2 /* writable */ #define R_OK 4 /* readable */ #define D_OK 8 /* deletable */ static TBK_BOOL win32_access( const char * os_path, TBK_PERMISSIONS permissions ) { DWORD dwDesiredAccess; /* Convert the permitions */ switch( permissions ) { case F_OK : return TBK_TRUE; // existance has been checked case R_OK : dwDesiredAccess = GENERIC_READ; break; case W_OK : dwDesiredAccess = GENERIC_WRITE; break; case X_OK : dwDesiredAccess = GENERIC_EXECUTE; break; case D_OK : dwDesiredAccess = DELETE; break; default : /* Should record an error for unknown access */ return TBK_FALSE; } // Declare here the local variables to avoid premature contructors GENERIC_MAPPING genericMapping = { READ_CONTROL | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA, FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_WRITE_DATA | FILE_APPEND_DATA, READ_CONTROL | FILE_READ_ATTRIBUTES | FILE_EXECUTE, FILE_ALL_ACCESS } ; LPCTSTR lpFilePath = LPCTSTR(os_path); PSECURITY_DESCRIPTOR pSD = NULL ; DWORD dwLenNeeded = 0; HANDLE hHeap = GetProcessHeap(); PRIVILEGE_SET privileges; DWORD dwGrandedAccess, dwPrivilegeLength; BOOL bSuccess, bAccessGranded; HANDLE hProcess, hToken; fprintf(stderr, "Start checking access for %s\n", os_path); // Get the length of the security structure GetFileSecurity( lpFilePath , OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, pSD, 0, &dwLenNeeded ); // Allocate memory for the structure pSD = HeapAlloc(hHeap, HEAP_GENERATE_EXCEPTIONS, dwLenNeeded); if( pSD == NULL ) { DWORD dwError = GetLastError(); LPVOID lpError; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM , NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpEr
-
I am trying to check if I have the proper access to a file. Here is my testing program
#include #include typedef int TBK_BOOL; typedef int TBK_PERMISSIONS; #define TBK_TRUE 1 #define TBK_FALSE 0 #define F_OK 0 /* exists */ #define X_OK 1 /* executable */ #define W_OK 2 /* writable */ #define R_OK 4 /* readable */ #define D_OK 8 /* deletable */ static TBK_BOOL win32_access( const char * os_path, TBK_PERMISSIONS permissions ) { DWORD dwDesiredAccess; /* Convert the permitions */ switch( permissions ) { case F_OK : return TBK_TRUE; // existance has been checked case R_OK : dwDesiredAccess = GENERIC_READ; break; case W_OK : dwDesiredAccess = GENERIC_WRITE; break; case X_OK : dwDesiredAccess = GENERIC_EXECUTE; break; case D_OK : dwDesiredAccess = DELETE; break; default : /* Should record an error for unknown access */ return TBK_FALSE; } // Declare here the local variables to avoid premature contructors GENERIC_MAPPING genericMapping = { READ_CONTROL | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA, FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_WRITE_DATA | FILE_APPEND_DATA, READ_CONTROL | FILE_READ_ATTRIBUTES | FILE_EXECUTE, FILE_ALL_ACCESS } ; LPCTSTR lpFilePath = LPCTSTR(os_path); PSECURITY_DESCRIPTOR pSD = NULL ; DWORD dwLenNeeded = 0; HANDLE hHeap = GetProcessHeap(); PRIVILEGE_SET privileges; DWORD dwGrandedAccess, dwPrivilegeLength; BOOL bSuccess, bAccessGranded; HANDLE hProcess, hToken; fprintf(stderr, "Start checking access for %s\n", os_path); // Get the length of the security structure GetFileSecurity( lpFilePath , OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, pSD, 0, &dwLenNeeded ); // Allocate memory for the structure pSD = HeapAlloc(hHeap, HEAP_GENERATE_EXCEPTIONS, dwLenNeeded); if( pSD == NULL ) { DWORD dwError = GetLastError(); LPVOID lpError; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM , NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpEr
You need to pass buffer to the AccessCheck for the privilege set. You need to pass in a thread token, not the process token. Here are some tips: For the
PRIVILEGE_SET privileges;
I changed it toPRIVILEGE_SET* lpPrivileges;
and malloced about 8192 bytes. Set the dwPrivilegeLength to 8192 Pass lpPrivileges (already a pointer) to AccessCheck instead of &privileges (which was your locla variable). Then I got error 1309 instead, meaning you need to open the thread token instead of the process token. Look at using OpenThread with GetCurentThradId followed by OpenThreadToken and maybe error 1309 will go away or be replaced by something else. -
I am trying to check if I have the proper access to a file. Here is my testing program
#include #include typedef int TBK_BOOL; typedef int TBK_PERMISSIONS; #define TBK_TRUE 1 #define TBK_FALSE 0 #define F_OK 0 /* exists */ #define X_OK 1 /* executable */ #define W_OK 2 /* writable */ #define R_OK 4 /* readable */ #define D_OK 8 /* deletable */ static TBK_BOOL win32_access( const char * os_path, TBK_PERMISSIONS permissions ) { DWORD dwDesiredAccess; /* Convert the permitions */ switch( permissions ) { case F_OK : return TBK_TRUE; // existance has been checked case R_OK : dwDesiredAccess = GENERIC_READ; break; case W_OK : dwDesiredAccess = GENERIC_WRITE; break; case X_OK : dwDesiredAccess = GENERIC_EXECUTE; break; case D_OK : dwDesiredAccess = DELETE; break; default : /* Should record an error for unknown access */ return TBK_FALSE; } // Declare here the local variables to avoid premature contructors GENERIC_MAPPING genericMapping = { READ_CONTROL | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA, FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_WRITE_DATA | FILE_APPEND_DATA, READ_CONTROL | FILE_READ_ATTRIBUTES | FILE_EXECUTE, FILE_ALL_ACCESS } ; LPCTSTR lpFilePath = LPCTSTR(os_path); PSECURITY_DESCRIPTOR pSD = NULL ; DWORD dwLenNeeded = 0; HANDLE hHeap = GetProcessHeap(); PRIVILEGE_SET privileges; DWORD dwGrandedAccess, dwPrivilegeLength; BOOL bSuccess, bAccessGranded; HANDLE hProcess, hToken; fprintf(stderr, "Start checking access for %s\n", os_path); // Get the length of the security structure GetFileSecurity( lpFilePath , OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION, pSD, 0, &dwLenNeeded ); // Allocate memory for the structure pSD = HeapAlloc(hHeap, HEAP_GENERATE_EXCEPTIONS, dwLenNeeded); if( pSD == NULL ) { DWORD dwError = GetLastError(); LPVOID lpError; FormatMessage( FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM , NULL, dwError, MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), (LPTSTR) &lpEr
I also forgot to mention you initialize the Generic Mappings incorrectly. It is a data structure with four 32-bit fields. Try
GENERIC_MAPPING genericMapping; genericMapping.GenericAll = READ_CONTROL | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA, FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_WRITE_DATA | FILE_APPEND_DATA, READ_CONTROL | FILE_READ_ATTRIBUTES | FILE_EXECUTE, FILE_ALL_ACCESS; genericMapping.GenericExecute = genericMapping.GenericAll; genericMapping.GenericRead = genericMapping.GenericAll; genericMapping.GenericWrite = genericMapping.GenericAll;
I am not suggesting these should all be the same value, only that this syntax is 'more corrct' than what you had before. -
I also forgot to mention you initialize the Generic Mappings incorrectly. It is a data structure with four 32-bit fields. Try
GENERIC_MAPPING genericMapping; genericMapping.GenericAll = READ_CONTROL | FILE_READ_DATA | FILE_READ_ATTRIBUTES | FILE_READ_EA, FILE_WRITE_ATTRIBUTES | FILE_WRITE_EA | FILE_WRITE_DATA | FILE_APPEND_DATA, READ_CONTROL | FILE_READ_ATTRIBUTES | FILE_EXECUTE, FILE_ALL_ACCESS; genericMapping.GenericExecute = genericMapping.GenericAll; genericMapping.GenericRead = genericMapping.GenericAll; genericMapping.GenericWrite = genericMapping.GenericAll;
I am not suggesting these should all be the same value, only that this syntax is 'more corrct' than what you had before.Thanks a lot for you help. Someone else sugested to use CreateFile which simplifies a lot the permission checking. Although sounds weird to 'create a file' for just checking the permissions, it looks like a simpler solution to go for. Ανέγνως αλλ' ουκ έγνων ή γαρ έγνως ουκ αν κατέγνων...Καβάφης