Required privilege not held returned by CreateFile

1

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:

  • The logged user can open the file using any random application, like notepad.
  • If the process create a new file in the samba folder then it can also open it without problems, the issue seems to affect files already created before the program starts.

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:

  • I can open any other random file on the local disk with ACCESS_SYSTEM_SECURITY
  • The file that fails to access is on SAMBA, as explained in the very first line of my question, does this have any relevance on the way those attributes have to be configured? It seems so, but don't know how.
windows
winapi
asked on Stack Overflow Jun 28, 2018 by fjanisze • edited Jun 28, 2018 by fjanisze

0 Answers

Nobody has answered this question yet.


User contributions licensed under CC BY-SA 3.0