2

I have a non-admin user (without SeImpersonatePrivilege) that needs to temporarily impersonate another user. According to the MSDN article for ImpersonateLoggedOnUser (emphasis mine):

All impersonate functions, including ImpersonateLoggedOnUser allow the requested impersonation if one of the following is true:
• The requested impersonation level of the token is less than SecurityImpersonation,
such as SecurityIdentification or SecurityAnonymous.
• The caller has the SeImpersonatePrivilege privilege.
• A process (or another process in the caller's logon session) created the token
using explicit credentials through LogonUser or LsaLogonUser function.
• The authenticated identity is same as the caller.

I'm attempting to use the Italicized approach. I can create the token using LogonUserW:

HANDLE token = NULL;
if (::LogonUserW(user, L".", password, LOGON32_LOGON_INTERACTIVE,
    LOGON32_PROVIDER_DEFAULT, &token))
{
    if (::ImpersonateLoggedOnUser(token))
    {
        DoOtherUserStuff();
    }
}

This calls succeed; I reach the DoOtherUserStuff function. However, when I then try to use the token I just created to do anything at all requiring a privilege check, it fails. GetLastError returns 1346, which is

Either a required impersonation level was not provided, or the provided impersonation level is invalid.

This is the error you get if you try to impersonate another user using a token obtained through some other method (OpenThreadToken, etc.) and don't have SeImpersonatePrivilege. However, I am creating the token using LogonUser with explicit credentials. Why isn't it working? Is the MSDN documentation just wrong?

I've tried using different logon types and different logon providers, to no avail. LOGON32_LOGON_NETWORK produces an impersonation token, as expected, but otherwise fails in exactly the same way.

System is Windows 8.0 Enterprise. The caller is a Microsoft account, but the user being logged on and impersonated is a local account.

CBHacking
  • 1,984
  • 16
  • 20
  • I've [noticed this before](http://stackoverflow.com/a/20485489/886887). I haven't looked very hard for a workaround; you could try, for example, using LOGON32_LOGON_NETWORK and see if it makes any difference. – Harry Johnston Aug 05 '14 at 23:04
  • Thanks, Harry. I'll watch that question too (I swear I searched first...). I did try a number of different approaches, including various values of the `dwLogonType` and `dwLogonProvider` but to no avail. `LOGON32_LOGON_NETWORK` gave an impersonation token, as expected, but otherwise failed in the exact same way. – CBHacking Aug 06 '14 at 03:53
  • I'm not surprised you didn't spot that question - it certainly isn't a duplicate of yours, it just happens to bring up the same issue. – Harry Johnston Aug 06 '14 at 05:02

0 Answers0