I have an ASP.NET Core 6.0 Web API that runs on IIS 7. The application pool is running under an account local to the machine but not the local system, call it 'local-system-web-account'. I am trying to start an executable from the API, but do it with the credentials of a domain joined account, let's call it 'domain-account-with-different-access'.
Both user accounts have access to a folder on the C:\
drive, to a folder called Tools
. Tools has a single application, HelloWorld.exe
, that simply prints 'Hello World!' to the command line and exits (a standard, brand new console application).
When I run the API endpoint that does not switch to the domain account, the output from the following API call is
[HttpGet("api/v1/test/noContextSwitchingTest")]
public async Task<ActionResult<ReturnDetail<object>>> NoContextSwitchingTest()
{
var prInfo = new ProcessStartInfo
{
FileName = @"C:\tools\helloworld.exe",
Arguments = "",
ErrorDialog = false,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
};
var stdout = new StringBuilder();
var stderr = new StringBuilder();
using (System.Diagnostics.Process proc = new())
{
proc.StartInfo = prInfo;
proc.EnableRaisingEvents = true;
proc.ErrorDataReceived += (sender, errorLine) => { if (errorLine.Data != null) stderr.AppendLine(errorLine.Data); };
proc.OutputDataReceived += (sender, outputLine) => { if (outputLine.Data != null) stdout.AppendLine(outputLine.Data); };
proc.Start();
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();
proc.WaitForExit();
}
return Ok(new { Out = stdout.ToString(), Erro = stderr.ToString() });
}
{
"out": "Hello, World!\r\n",
"erro": ""
}
When I call the following API endpoint:
[HttpGet("api/v1/test/WithContextSwitchingTest")]
public async Task<ActionResult<ReturnDetail<object>>> WithContextSwitchingTest()
{
var prInfo = new ProcessStartInfo
{
FileName = @"C:\tools\helloworld.exe",
Arguments = "",
ErrorDialog = false,
UseShellExecute = false,
RedirectStandardOutput = true,
RedirectStandardError = true,
CreateNoWindow = true,
};
prInfo.UserName = "domain-account-with-different-access";
prInfo.PasswordInClearText = "PASSWORD";
var stdout = new StringBuilder();
var stderr = new StringBuilder();
using (System.Diagnostics.Process proc = new())
{
proc.StartInfo = prInfo;
proc.EnableRaisingEvents = true;
proc.ErrorDataReceived += (sender, errorLine) => { if (errorLine.Data != null) stderr.AppendLine(errorLine.Data); };
proc.OutputDataReceived += (sender, outputLine) => { if (outputLine.Data != null) stdout.AppendLine(outputLine.Data); };
proc.Start();
proc.BeginErrorReadLine();
proc.BeginOutputReadLine();
proc.WaitForExit();
}
return Ok(new { Out = stdout.ToString(), Erro = stderr.ToString() });
}
with a switch to the domain account, I get an error in the Event Viewer
Application popup: HelloWorld.exe - Application Error : The application was unable to start correctly (0xc0000142). Click OK to close the application.
and I also get the following output from the API:
{
"out": "",
"erro": ""
}
But nothing else. No exception is thrown. It just silently doesn't work and nothing in the Standard Out or Standard Error.
If I switch the application pool to run as the domain account in IIS and rerun the no context switching endpoint, the HelloWorld executes just fine, so I know the domain account can run the executable and access it.
I'm looking for any advice on different code that could be used or areas of security interest that could be preventing the switch.
C:\tools
directory andHelloWorld.exe
. YouProcessStartInfo
withUseShellExecute = true
and FileName = "cmd.exe" to prompt for credentials securely, avoiding PasswordInClearText by using SecureString for the password. In addition, you should check Event Viewer logs for detailed error messages and test executing HelloWorld.exe manually under both accounts to verify permissions and resolve any access issues.Process.Start
, have you tried usingP/Invoke
to callCreateProcessWithLogonW
, which is designed to start a process as a different user. This might bypass some of the issues you're encountering.