While trying to open a file on Samba from a Win32 application running on Windows Server the function CreateFiles returns an invalid handle and the error code is 0x522 (ERROR_PRIVILEGE_NOT_HELD) is there a way to inquiry the system on which provilege is missing for that particular file?
I've enabled some security privileges after impersonating the logged user (which should be the admin): SE_SECURITY_NAME, SE_BACKUP_NAME and SE_RESTORE_NAME, but that doesnt work.
I just need read privileged over the file and I'm submitting the following options to CreateFile:
hSrcFile = CreateFile (sourcePath, READ_CONTROL | ACCESS_SYSTEM_SECURITY, 0, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
Some other probably not very useful information:
Any suggestion? Thanks
EDIT 1
To configure the SE_SECURITY_NAME flag I'm taking the Process token with OpenProcessToken
, then using this function from MSDN to enable the privileges.
I've also attempted to use the token from LogonUser
while loggin as admin to set the privilege, but in this case the MSDN funtion seems to fail with error ACCESS_DENIED. Doing the same thing after duplicating the token with DuplicateToken (and SecurityDelegation flag) do not work either.
I've verified the return value of AdjustTokenPrivileges
while setting SE_SECURITY_NAME and the function do not fail. I can call CreateFile
to open the file without the flag ACCESS_SYSTEM_SECURITY, but then I can't use the file handle to call GetFileInformationByHandleEx
since the function fails with ACCESS DENIED, not sure if this is related to ACCESS_SYSTEM_SECURITY or not.
EDIT 2
I'm performing the following steps to enable SE_SECURITY_NAME and then use CreateFile:
Obtain the process token with OpenProcessToken
(flags TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY) and call AdjustTokenPrivileges
with SE_SECURITY_NAME,SE_BACKUP_NAME and SE_RESTORE_NAME. (After obtaining the proper LUID with LookupPrivilegeValue
). The error code returned by the function is 0x0.
Obtain the thread token with OpenThreadToken
(flags TOKEN_ADJUST_PRIVILEGES | TOKEN_QUERY) and call AdjustTokenPrivileges
with SE_SECURITY_NAME, SE_BACKUP_NAME and SE_RESTORE_NAME. (After obtaining the proper LUID with LookupPrivilegeValue
). The error code returned by the function is 0x0.
Call CreateFile with CreateFile(pathTofile, READ_CONTROL | ACCESS_SYSTEM_SECURITY, 0, NULL, OPEN_EXISTING, FILE_FLAG_BACKUP_SEMANTIC,NULL)
the function returns 0x522: PRIVILEGE NOT HELD. The pathToFile have a format like "\192.168.0.0\folder\file.txt"
Hope this clarify a bit the flow, the code to enable the Privileges is:
bStatus = LookupPrivilegeValue (NULL, privilegeStr, &luid);
if (!bStatus)
{
dwStatus = GetLastError();
// do stuff
}
ZeroMemory (&tp, sizeof (tp));
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
/* Adjust Token privileges */
bStatus = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
&oldtp, &dwSize);
dwStatus = GetLastError();
if (!bStatus || dwStatus != ERROR_SUCCESS )
{
//do stuff, print error etc.
}
where privilegeStr is for example SE_SECURITY_NAME
EDIT 3
In the hope to provide an all-inlcusive example of code that reproduce the problem and thus maybe getting a possible solution for it, I've prepared this ugly code snippet:
HANDLE hToken;
bStatus = OpenThreadToken(GetCurrentThread(), TOKEN_ADJUST_PRIVILEGES |
TOKEN_QUERY, TRUE, &hToken);
LUID luid;
LookupPrivilegeValue(NULL, SE_SECURITY_NAME, &luid);
TOKEN_PRIVILEGES tp = { 0, };
TOKEN_PRIVILEGES oldtp = { 0, };
DWORD dwSize = sizeof(TOKEN_PRIVILEGES);
ZeroMemory(&tp, sizeof(tp));
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
/* Adjust Token privileges */
bStatus = AdjustTokenPrivileges(hToken, FALSE, &tp, sizeof(TOKEN_PRIVILEGES),
&oldtp, &dwSize);
dwStatus = GetLastError();
if (!bStatus || dwStatus != ERROR_SUCCESS)
{
//Print error.
}
PRIVILEGE_SET privSet;
ZeroMemory(&privSet, sizeof(PRIVILEGE_SET));
privSet.PrivilegeCount = 1;
privSet.Control = PRIVILEGE_SET_ALL_NECESSARY;
privSet.Privilege[0].Attributes = SE_PRIVILEGE_ENABLED;
privSet.Privilege[0].Luid = luid;
BOOL bResult;
PrivilegeCheck(hToken, &privSet, &bResult);
fprintf(stderr,"Status bool: %d, attr value:0x%x, error code: 0x%x\n",
bResult,
privSet.Privilege[0].Attributes,
GetLastError());
hSrcFile = CreateFile (sourcePath, READ_CONTROL | ACCESS_SYSTEM_SECURITY, 0, NULL, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS, NULL);
if( hSrcFile == INVALID_HANDLE_VALUE )
{
fprintf(stderr,"CreateFile error 0x%x\n", GetLastError());
}
The output is Status bool:1, attr value:0x80000002, error code: 0x0
followed by CreateFile error 0x522
.
Does this example confirms that SE_SECURITY_NAME is enabled but CreateFile
still fail? Anything else is needed? Additionally:
ACCESS_SYSTEM_SECURITY
User contributions licensed under CC BY-SA 3.0