Example #1
0
        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);
            }
        }
Example #2
0
        /// <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);
            }
        }
Example #3
0
        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);
            }
        }
Example #4
0
        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;
    }
Example #6
0
 protected override void Dispose(bool disposing)
 {
     ImpersonationHelper.SafeCloseHandle(ref _processInformation.hProcess);
     ImpersonationHelper.SafeCloseHandle(ref _processInformation.hThread);
     base.Dispose(disposing);
 }
Example #7
0
        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);
        }