Running CreateProcessAsUser() keeps elevated access permissions

Corey Minyard 66 Reputation points

I'm trying to create something to run a program as a lower-privilege user. I have it running, but the new process seems to retain elevated access control rights.

I admit that I do not understand the Windows security model very well, but I can't find a good explanation of how this all works. It's terribly complicated.

The program at is a good starting place, as it does the same thing I'm doing. So I have that program compiled to try it out. I created a C:\etc directory with only admin access. From my account:

C:\>cd C:\etc  
Access is denied.  

as it should be. Then, as a System account, I run the program in s4u:

C:\msys64\home\cminyard\s-4-u-for-windows>.\s4u windows2\cminyard  
... a bunch of output  
C:\Users\tcmin>cd C:\etc  

whoami shows the right user in both cases. Doing "whoami /all" shows a bunch more permissions and a somewhat different set of groups.

The user is an admin user, but normally when I login I don't have all those permission.

Second, I can't use this program to change to a normal user account:

C:\msys64\home\cminyard\s-4-u-for-windows>.\s4u windows2\testuser  
Could not get user: Logon failure: the user has not been granted the requested logon type at this computer.  

What am I doing wrong? Is there any resource (I'm willing to pay) available that explains all this stuff? The documentation online is too fragmented for me to really understand how all this stuff works.

Windows API - Win32
Windows API - Win32
A core set of Windows application programming interfaces (APIs) for desktop and server applications. Previously known as Win32 API.
2,352 questions
A high-level, general-purpose programming language, created as an extension of the C programming language, that has object-oriented, generic, and functional features in addition to facilities for low-level memory manipulation.
3,440 questions
0 comments No comments
{count} votes

Accepted answer
  1. RLWA32 38,846 Reputation points

    When the S4U logon is done by a process running as SYSTEM for a user in the Administrators group the resultant token will contain full administrator rights and privileges. This is standard windows behavior.

    If you want to start a process with CreateProcessAsUser that runs as a standard user then you need to use a token that does not contain administrator rights and privileges. For a user in the Administrators group use LogonUser to obtain the token or copy the token from an unelevated process already running as that user (e.g. explorer.exe).

    Ordinarily, when UAC is enabled and a user that is a member of the Administrators group logs on the system creates a split token. Essentially, there are two tokens that are linked -- one that is filtered to remove administrator rights and privileges and one that is not filtered. Ordinarily, the system uses the filtered token and related processes are not elevated and run at the medium integrity level. Upon requesting elevation, the system uses the unfiltered token for the elevated process which then runs at the high integrity level.

    In order for an s4u logon to succeed for a standard user account that account must be granted the log on as a batch job right. See log-on-as-a-batch-job

4 additional answers

Sort by: Most helpful
  1. Corey Minyard 66 Reputation points

    Well, CreateRestrictedToken() would have been a useful function to know about. It pretty much does what I need.

  2. Corey Minyard 66 Reputation points

    So now I have things working sort of like I want with CreateRestrictedToken, but there's still an issue. I'm unable to run pretty much any command if I disable the BUILTIN\Administrators group, including whoami and the debugger. Looking at the groups, it looks like I'm missing:

    S-1-5-32-559 - BUILTIN\Performance Log Users
    S-1-2-0 - LOCAL

    which I assume come with an Interactive logon. I can't figure out how to add groups to a token; I suspect you can't. Any ideas?

  3. Corey Minyard 66 Reputation points

    Oh, and I also found that you have to set the TokenIntegrityLevel to a medium level mandatory security level, which CreateRestrictedToken, oddly enough, doesn't seem to do.

  4. Corey Minyard 66 Reputation points

    Oh, doh, you can add groups in LsaLogonUser.

    0 comments No comments