I'm trying to start a .NET application under a different user from a .NET service. The idea is to create a sandboxed hosting application in windows. In the service, I programatically created the user in windows, create a folder for that user, and download the host .exe from a server into that folder. I then I run the host .exe using System.Diagnostics.Process. Here is the StartInfo for the process:
_process = new Process
{
StartInfo =
{
Arguments = " -debug",
FileName = instanceDirectory + "host.exe",
WorkingDirectory = instanceDirectory,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = true,
UserName = Helpers.GetUserNameForInstance(_hostid),
Password = _hostpass,
Domain = ""
},
EnableRaisingEvents = true
};
When I run the service as a SERVICE, the process crashes instantly with an error code of -1073741502. but when I run the service as the same user specified in the windows service but interactively in the console, everything works fine. This only happens whenever running the service as a SERVICE and not directly in the console.
Any help would be MUCH appreciated. This has been a headache for a long time now and this is a last resort :(
It seems like using the new Process()
with a username and password and the Service mode "doesn't compute" :)
Quote from MSDN:
You can change the parameters specified in the StartInfo property up to the time that you call the Start method on the process. After you start the process, changing the StartInfo values does not affect or restart the associated process. If you call the Start(ProcessStartInfo) method with the ProcessStartInfo..::.UserName and ProcessStartInfo..::.Password properties set, the unmanaged CreateProcessWithLogonW function is called, which starts the process in a new window even if the CreateNoWindow property value is true or the WindowStyle property value is Hidden.
Furthermore, looking at the CreateProcessWithLogonW documentation:
lpStartupInfo [in]
A pointer to a STARTUPINFO structure. The application must add permission for the specified user account to the specified window station and desktop, even for WinSta0\Default.
If the lpDesktop member is NULL or an empty string, the new process inherits the desktop and window station of its parent process. The application must add permission for the specified user account to the inherited window station and desktop.
There is no lpDesktop in the .NET StartupInfo, on the other hand the SERVICE user has no desktop, which could cause your problem.
Long story short, try to set the LoadUserProfile
to true
to load the user's information from the registry, or maybe you need to set the working directory, etc.
To further investigate, your should check your environment and maybe log which files are accessed using FileMon.
I would try to create the process under the impersonated context of the newly created user as below.
[DllImport("advapi32.DLL", SetLastError = true)]
public static extern int LogonUser(string lpszUsername, string lpszDomain, string lpszPassword, int dwLogonType, int dwLogonProvider, out IntPtr phToken);
[DllImport("kernel32.dll", CharSet = CharSet.Auto)]
public extern static bool CloseHandle(IntPtr handle);
[DllImport("advapi32.DLL")]
public static extern bool ImpersonateLoggedOnUser(IntPtr hToken);
static void Main()
{
IntPtr admin_token = new IntPtr();
WindowsIdentity wid_admin = null;
WindowsImpersonationContext wic = null;
LogonUser("username", "domain", "password", 9, 3, out admin_token);
wid_admin = new WindowsIdentity(admin_token);
wic = wid_admin.Impersonate();
_process = new Process
{
StartInfo =
{
Arguments = " -debug",
FileName = instanceDirectory + "host.exe",
WorkingDirectory = instanceDirectory,
UseShellExecute = false,
RedirectStandardError = true,
RedirectStandardOutput = true,
RedirectStandardInput = true,
UserName = Helpers.GetUserNameForInstance(_hostid),
Password = _hostpass,
Domain = ""
},
EnableRaisingEvents = true
};
if (wic != null) wic.Undo();
CloseHandle(admin_token);
}
A double hop between servers may cause the service credentials to get dropped, maybe setting up Kerberos would solve this issue.
http://neverknewthat.wordpress.com/2009/05/14/kerberos/
0xc0000142
(-1073741502) is STATUS_DLL_INIT_FAILED:
Initialization of the dynamic link library [name] failed. The process is terminating abnormally.
As the website TenaciousImpy gave pointed out, you need to give the account permissions to the window station and desktop. But if the program is interactive, you need to set the session ID of the process token as well.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With