Inside and Out…

An attempt to understand technology better…

Managed CreateProcessWithLogonW

Posted by Gaurav Khanna on February 9, 2005

I returned this past weekend after a family function. It had me very busy and thus, no blogging for sometime for me 🙂

That said, today I was working with one of my friends over email – she was stuck about getting to launch a process in a specific user context, using managed code. Since the .NET Framework doesn’t support such functionality out of the box, we tried different ways to do this:

1) LogonUser followed by WindowsIdentity impersonation using the obtained token – the token wasn’t getting down to the spawned process even after we attempted Impersonate method of WindowsIdentity.

2) WMI also tried – it works but needs to be slightly modified when running on a local machine compared to a remote machine (we cannot specify credentials for local machine in the options).

Finally, we thought about working on CreateProcessWithLogonW. It turned out to be rather simple and clean way of achieving our goal. For those who are interested, the following snippet uses CreateProcessWithLogonW via PInvoke and launches a process under the specified user context:

The following are the PInvoke declarations and data types required:

[Flags]
enumLogonFlags
{
LOGON_WITH_PROFILE = 0x00000001,
LOGON_NETCREDENTIALS_ONLY = 0x00000002
}

[Flags]
enumCreationFlags
{
CREATE_SUSPENDED = 0x00000004,
CREATE_NEW_CONSOLE = 0x00000010,
CREATE_NEW_PROCESS_GROUP = 0x00000200,
CREATE_UNICODE_ENVIRONMENT = 0x00000400,
CREATE_SEPARATE_WOW_VDM = 0x00000800,
CREATE_DEFAULT_ERROR_MODE = 0x04000000,
}

[StructLayout(LayoutKind.Sequential)]
structProcessInfo
{
publicIntPtr hProcess;
publicIntPtr hThread;
public uintdwProcessId;
public uintdwThreadId;
}

[StructLayout(LayoutKind.Sequential, CharSet=CharSet.Unicode)]
structStartupInfo
{
public intcb;
public stringreserved1;
public stringdesktop;
public stringtitle;
public uintdwX;
public uintdwY;
public uintdwXSize;
public uintdwYSize;
public uintdwXCountChars;
public uintdwYCountChars;
public uintdwFillAttribute;
public uintdwFlags;
public ushortwShowWindow;
public shortreserved2;
public intreserved3;
publicIntPtr hStdInput;
publicIntPtr hStdOutput;
publicIntPtr hStdError;
}

[DllImport(“advapi32.dll”, CharSet=CharSet.Unicode, ExactSpelling=true, SetLastError=true)]
static extern boolCreateProcessWithLogonW(
stringprincipal,
stringauthority,
stringpassword,
LogonFlags logonFlags,
stringappName,
stringcmdLine,
CreationFlags creationFlags,
IntPtr environmentBlock,
stringcurrentDirectory,
refStartupInfo startupInfo,
outProcessInfo processInfo);

[DllImport(“kernel32.dll”)]
static extern boolCloseHandle(IntPtr h);

The following is the code snippet that does the PInvoke and spawns the process under a specific user context:

StartupInfo si = newStartupInfo();
si.cb = Marshal.SizeOf(typeof(StartupInfo));
si.title = “This is impersonated command prompt”;

ProcessInfo pi = newProcessInfo();
stringapp = Path.Combine(Environment.SystemDirectory, “cmd.exe”);

if(CreateProcessWithLogonW(“username”, “domain”, “password”,
LogonFlags.LOGON_WITH_PROFILE,
app, null,
0, IntPtr.Zero, null,
refsi, outpi))
{
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
elseConsole.WriteLine(“Error code: {0}”, Marshal.GetLastWin32Error());

Advertisements

One Response to “Managed CreateProcessWithLogonW”

  1. […] Blocked 0 spam comments blocked byAkismet « Managed CreateProcessWithLogonW Welcome Windows CE Remote API (RAPI) to the managed world […]

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

 
%d bloggers like this: