My app runs as requestedExecutionLevel
set to highestAvailable
.
How do I run a process unelevated?
I tried the following but it didn't work:
Process.Start(new ProcessStartInfo {FileName = "foo.exe", Verb = "open"})
I have tried the following trust levels to start my process using Win32 API but none of them work correctly:
0
1260: This program is blocked by group policy. For more information, contact your system administrator.
0x1000
The application was unable to start correctly (0xc0000142). Click OK to close the application.
0x10000
Process starts then hangs
0x20000
All options are not available
0x40000
Runs as admin
If I run tskill foo
from my elevated app, it restarts foo with correct privileges.
What I need is a solution in which I don't have to specify the trust level. The process should start with the correct trust level automatically just like the tskill
tool restarts foo.exe
in the correct trust level. The user selects and runs foo.exe
and so it can be anything.
If I can get the trust level of a process somehow, I can do this easily since foo.exe
runs when my app can capture its trust level.
The Win32 Security Management functions provide the capability to create a restricted token with normal user rights; with the token, you can call
CreateProcessAsUser
to run the process with that token. Below is a proof of concept that runs cmd.exe as a normal user, regardless of whether the process is run in an elevated context.This approach makes use the following Win32 functions:
SaferIdentifyLevel
to indicate the identity level (limited, normal, or elevated). Setting thelevelId
toSAFER_LEVELID_NORMALUSER
(0x20000) provides the normal user level.SaferComputeTokenFromLevel
creates a token for the provided level. PassingNULL
to the InAccessToken parameter uses the identity of the current thread.CreateProcessAsUser
creates the process with the provided token. Since the session is already interactive, most of the parameters can be kept at default values. (The third parameter,lpCommandLine
can be provided as a string to specify the command line.)CloseHandle
(Kernel32) andSaferCloseLevel
to free allocated memory.Finally, the P/Invoke code is below (copied mostly from pinvoke.net):