Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Service needs to spawn non-interactive child process, but fails with "Access denied"

First off, I'm not trying to interact with the desktop in any kind.

What I'm trying to do is to separate concerns. I have a service that runs under the local system account (LSA). Sometimes, I need to execute processes under a different account.

I am using System.Diagnostics.Process for this. This is what I have tried with so far:

  • Running the service app as an ordinary desktop app, launching the child process under the same account: works
  • Running the service app as an ordinary desktop app, launching the child process under another account: works
  • Running the service as a service app (as LSA), launching the child process under the same account (LSA): works
  • Running the service as a service app (as LSA), launching the child process under another account: does not work

The case that does not work for me throws me a Win32Exception with "Access denied." I have granted the user account in question the right to log on as a service, but it does not make any difference.

For fun, I have also tried these scenarios:

  • If I run the service under my own dev account (let's call it Developer), and tries to start the child process under the less privileged account (let's call it ServiceAccount), process.Start() does not throw, and returns true, but I never see any process being started in the Sys Internal's Process Explorer, and Process.Exited is fired immediately.
  • If I run the service under ServiceAccount, and starts the child process under the same account (ServiceAccount), it works as expected.

This is the code I'm working with:

var pi = new ProcessStartInfo {
    CreateNoWindow = true,
    WindowStyle = ProcessWindowStyle.Hidden,
    UseShellExecute = false,
    ErrorDialog = false,
    RedirectStandardError = false,
    RedirectStandardInput = false,
    RedirectStandardOutput = false,
    FileName = @"C:\Path\To\SomeApplication.exe",
    Arguments = @"Some arguments",
    UserName = "SomeUserName",
    Domain = "SomeDomain",
    Password = SecureStringUtils.Convert("SomePassword")
};

var process = new Process();
process.StartInfo = pi;
process.Start(); // Throws when run as a service

Any ideas?

like image 663
Jörgen Sigvardsson Avatar asked Oct 07 '22 17:10

Jörgen Sigvardsson


1 Answers

I finally found this: Using Process.Start() to start a process as a different user from within a Windows Service, and it solves my problem. Granted, the code provided in the answer needs a ton of polishing, but it does seem to fix my problem.

like image 180
Jörgen Sigvardsson Avatar answered Oct 10 '22 07:10

Jörgen Sigvardsson