Here is my code:
logonSuccess = LogonUserW(userPartW, domainPartW, pwdW,
LOGON32_LOGON_BATCH,
LOGON32_PROVIDER_DEFAULT, &token);
Int result1 = SetNamedSecurityInfo("C:\\file.crt", SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, yveri, NULL, NULL, NULL);
fprintf(stderr, "result -> %d.\n", result1); //which gives me 0
if (ImpersonateLoggedOnUser(token) == FALSE)
{
printf("Imperesonating failed.\n");
return -1;
}
Int result2 = SetNamedSecurityInfo("C:\\Users\\nx\\.nx\\config\\authorized.crt", SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, yveri, NULL, NULL, NULL);
fprintf(stderr, "result -> %d.\n", result2); //which gives me 5
The first call to SetNamedSecurityInfo works, but the second call (once impersonation is in place) returns error code 5.
Building on what we figured out in the comments:
When you call any of the impersonation functions (ImpersonateLoggedOnUser
, ImpersonateNamedPipeClient
, RpcImpersonateClient
, etc.) you're basically calling SetThreadToken(GetCurrentThread(), __GetInterestingToken())
(where GetInterestingToken()
is a placeholder for getting the relevant token for each function).
When you perform any action that makes a security check against the current security context1 it makes the check against the current thread's token - whatever it is - if it exists. Otherwise it makes the check against the process token.
There's no "inheritance" of any sort from the process's security context to the thread's when the thread has a token attached to it. You either get the process's security context (all of it and nothing else) or a specific security context for the thread (and nothing else!).
That's actually the whole point behind impersonation, it's raison d'etre2.
Any success you had in doing anything before impersonation is completely irrelevant to your ability to perform the same action after impersonation3. Since you haven't enabled the privileges that allow you to change kernel objects' owner (SeTakeOwnershipPrivilege
to make yourself the owner, and as Harry Johnston correctly said - SeRestorePrivilege
to set someone else to be the owner) your attempt to change it is denied.
Enable the necessary privilege (assuming the token has it) to be able to change the owner.
1 In contrast to code that intentionally makes the check against another security context, such as when passing OpenAsSelf = TRUE
to OpenThreadToken
.
2 The classic example given when explaining client impersonation is a file server running as LOCAL_SYSTEM
impersonation the client during request servicing to make sure it doesn't accidently (or intentionally...) access files the client isn't allowed to access. If during impersonation any abilities (permissions or privileges) "leaked" to the impersonating thread that would pretty much defeat the purpose of impersonating the client.
3 Except in the special case of ImpersonateSelf
, where obviously you should be able to do anything you could have done before impersonation.