How to launch a process as a different user without storing their credentials?

You may run into a situation where you need to create a token to be used at a later time since you can’t keep the credentials around in your application.  The token representing the user is going to be used to launch a process.  In the past, this would be done by generating the token with LogonUser() and then launching the application with CreateProcessAsUser().  In order to launch an INTERACTIVE process, you need to modify the INTERACTIVE Window Station and Desktop (referred to as the INTERACTIVE desktop) to grant access to the user,   https://support.microsoft.com/kb/165194.  (The KB article was written by me).  The weakness in this technique is that you are responsible for the DACLs on the INTERACTIVE Window Station and Desktop.  Since this a SYSTEM named object, the SYSTEM (and other processes) may not be aware of the changes that you have made.   If the SYSTEM or another process makes a change to the DACLs and is unaware of your changes, your user will not have any more access to the INTERACTIVE desktop.

A better technique for granting access to the user is to use the technique used by CreateProcessWithLogonW().  CreateProcessWithLogonW() internally grants access to the user by obtaining the LOGON SID of the current INTERACTIVELY logged on user and adding this LOGON SID to the user specified in CreateProcessWithLogonW(). 

What you can do is launch a temporary process suspended.  CreateProcessWithLogonW() will go through the steps of creating the token with the appropriate permissions to the INTERACTIVE desktop.  You can then obtain this token via a call to OpenProcessToken().  You can then get your own copy of the token by calling DuplicateTokenEx().  Once you have the token, you can get rid of the suspended temporary process.

At a later time, when you need to launch a process as a specific user, you can call CreateProcessWithTokenW() to launch the process.

The above solution will not work on Windows XP since CreateProcessWithLogonw() isn’t supported. You may be asking why you don’t just call CreateProcessAsUser() instead of CreateProcessWithTokenW() since you have a token from CreateProcessWithLogonW().  The reason is because CreateProcessAsUser() requires the “Replace a Process Level Token” right for the caller which even Administrators do not have by default.  (This avoids granting any additional rights to the caller for this technique to work).

 

Follow us on Twitter, www.twitter.com/WindowsSDK.