public bool StartAsUser(string domain, string username, string password) { IntPtr userToken = IntPtr.Zero; IntPtr token = IntPtr.Zero; try { if (!NativeMethods.LogonUser(username, domain, password, NativeMethods.LogonType.Interactive, NativeMethods.LogonProvider.Default, out token)) { throw new Win32Exception(Marshal.GetLastWin32Error(), String.Format("ImpersonationProcess: LogonUser {0}\\{1} failed", domain, username)); } if (!NativeMethods.DuplicateTokenEx(token, NativeMethods.TokenAccess.AssignPrimary | NativeMethods.TokenAccess.Duplicate | NativeMethods.TokenAccess.Query, null, NativeMethods.SecurityImpersonationLevel.Impersonation, NativeMethods.TokenType.Primary, out userToken)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "ImpersonationProcess: DuplicateToken failed"); } return(StartAsUser(userToken)); } finally { ImpersonationHelper.SafeCloseHandle(token); ImpersonationHelper.SafeCloseHandle(userToken); } }
/// <summary> /// Executes the <paramref name="executable"/> and waits a maximum time of <paramref name="maxWaitMs"/> for completion. If the process doesn't end in /// this time, it gets aborted. This method tries to impersonate the interactive user and run the process under its identity. /// </summary> /// <param name="executable">Program to execute</param> /// <param name="arguments">Program arguments</param> /// <param name="priorityClass">Process priority</param> /// <param name="maxWaitMs">Maximum time to wait for completion</param> /// <returns><c>true</c> if process was executed and finished correctly</returns> public static bool TryExecute_Impersonated(string executable, string arguments, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = INFINITE) { IntPtr userToken; if (!ImpersonationHelper.GetTokenByProcess(out userToken, true)) { return(false); } try { string unused; return(TryExecute_Impersonated(executable, arguments, userToken, false, out unused, priorityClass, maxWaitMs)); } finally { ImpersonationHelper.SafeCloseHandle(userToken); } }
public static bool TryExecuteReadString_Impersonated(string executable, string arguments, out string result, ProcessPriorityClass priorityClass = ProcessPriorityClass.Normal, int maxWaitMs = DEFAULT_TIMEOUT) { IntPtr userToken; if (!ImpersonationHelper.GetTokenByProcess(out userToken, true)) { result = null; return(false); } try { return(TryExecute_Impersonated(executable, arguments, userToken, true, out result, priorityClass, maxWaitMs)); } finally { ImpersonationHelper.SafeCloseHandle(userToken); } }
public new void Kill() { IntPtr hProcess = IntPtr.Zero; try { int id = Id; hProcess = NativeMethods.OpenProcess(NativeMethods.ProcessAccess.Terminate, false, id); if (hProcess == IntPtr.Zero) { throw new Win32Exception(Marshal.GetLastWin32Error(), "ImpersonationProcess: OpenProcess failed"); } NativeMethods.TerminateProcess(hProcess, 0); } finally { ImpersonationHelper.SafeCloseHandle(hProcess); } }
/// <summary> /// Tries to impersonate the current process as the user which runs explorer.exe currently. The caller should always call <see cref="IDisposable.Dispose"/> on /// the returned instance to revert identity to self. /// </summary> private static ImpersonationHelper.ImpersonationContext ImpersonateUser(ImpersonationHelper.ImpersonationContext requestedIdentity) { NetworkNeighborhoodResourceProviderSettings settings = _settings.Settings; ImpersonationHelper.ImpersonationContext ctx = null; // Prefer to impersonate current interactive user. if (settings.ImpersonateInteractive) { if (requestedIdentity != null && !ImpersonationHelper.RequiresImpersonate(requestedIdentity.Identity)) return null; ctx = ImpersonationHelper.ImpersonateByProcess("explorer"); } if (ctx != null) return ctx; // Second way based on network credentials. if (settings.UseCredentials) ctx = ImpersonationHelper.ImpersonateUser(settings.NetworkUserName, settings.NetworkPassword); return ctx; }
protected override void Dispose(bool disposing) { ImpersonationHelper.SafeCloseHandle(ref _processInformation.hProcess); ImpersonationHelper.SafeCloseHandle(ref _processInformation.hThread); base.Dispose(disposing); }
public bool StartAsUser(IntPtr userToken) { _processInformation = new NativeMethods.ProcessInformation(); NativeMethods.StartupInfo startupInfo = new NativeMethods.StartupInfo(); switch (StartInfo.WindowStyle) { case ProcessWindowStyle.Hidden: startupInfo.wShowWindow = SW_HIDE; break; case ProcessWindowStyle.Maximized: startupInfo.wShowWindow = SW_MAXIMIZE; break; case ProcessWindowStyle.Minimized: startupInfo.wShowWindow = SW_MINIMIZE; break; case ProcessWindowStyle.Normal: startupInfo.wShowWindow = SW_SHOW; break; } CreateStandardPipe(out _stdinReadHandle, out _stdinWriteHandle, STD_INPUT_HANDLE, true, StartInfo.RedirectStandardInput); CreateStandardPipe(out _stdoutReadHandle, out _stdoutWriteHandle, STD_OUTPUT_HANDLE, false, StartInfo.RedirectStandardOutput); CreateStandardPipe(out _stderrReadHandle, out _stderrWriteHandle, STD_ERROR_HANDLE, false, StartInfo.RedirectStandardError); startupInfo.dwFlags = STARTF_USESTDHANDLES | STARTF_USESHOWWINDOW; startupInfo.hStdInput = _stdinReadHandle; startupInfo.hStdOutput = _stdoutWriteHandle; startupInfo.hStdError = _stderrWriteHandle; NativeMethods.CreateProcessFlags createFlags = NativeMethods.CreateProcessFlags.CreateNewConsole | NativeMethods.CreateProcessFlags.CreateNewProcessGroup | NativeMethods.CreateProcessFlags.CreateDefaultErrorMode; if (StartInfo.CreateNoWindow) { startupInfo.wShowWindow = SW_HIDE; createFlags |= NativeMethods.CreateProcessFlags.CreateNoWindow; } // Create process as user, fail hard if this is unsuccessful so it can be caught in EncoderUnit if (!NativeMethods.CreateProcessAsUserW(userToken, null, GetCommandLine(), IntPtr.Zero, IntPtr.Zero, true, createFlags, IntPtr.Zero, null, startupInfo, out _processInformation)) { throw new Win32Exception(Marshal.GetLastWin32Error(), "ImpersonationProcess: CreateProcessAsUser failed"); } if (_processInformation.hThread != (IntPtr)(-1)) { ImpersonationHelper.SafeCloseHandle(ref _processInformation.hThread); _processInformation.hThread = IntPtr.Zero; } if (StartInfo.RedirectStandardInput) { ImpersonationHelper.SafeCloseHandle(ref _stdinReadHandle); StreamWriter standardInput = new StreamWriter(new FileStream(_stdinWriteHandle, FileAccess.Write, 4096), Console.Out.Encoding) { AutoFlush = true }; SetField("standardInput", standardInput); } if (StartInfo.RedirectStandardOutput) { ImpersonationHelper.SafeCloseHandle(ref _stdoutWriteHandle); StreamReader standardOutput = new StreamReader(new FileStream(_stdoutReadHandle, FileAccess.Read, 4096), StartInfo.StandardOutputEncoding); SetField("standardOutput", standardOutput); } if (StartInfo.RedirectStandardError) { ImpersonationHelper.SafeCloseHandle(ref _stderrWriteHandle); StreamReader standardError = new StreamReader(new FileStream(_stderrReadHandle, FileAccess.Read, 4096), StartInfo.StandardErrorEncoding); SetField("standardError", standardError); } // Workaround to get process handle as non-public SafeProcessHandle Assembly processAssembly = typeof(System.Diagnostics.Process).Assembly; Type processManager = processAssembly.GetType("System.Diagnostics.ProcessManager"); object safeProcessHandle = processManager.InvokeMember("OpenProcess", BindingFlags.InvokeMethod | BindingFlags.Public | BindingFlags.Static, null, this, new object[] { _processInformation.dwProcessId, 0x100000, false }); InvokeMethod("SetProcessHandle", safeProcessHandle); InvokeMethod("SetProcessId", _processInformation.dwProcessId); return(true); }