public void Impersonate(string userName, string domainName, string password, LogonType logonType, LogonProvider logonProvider) { UndoImpersonation(); IntPtr logonToken = IntPtr.Zero; IntPtr logonTokenDuplicate = IntPtr.Zero; try { _wic = WindowsIdentity.Impersonate(IntPtr.Zero); if (ADVAPI32.LogonUser(userName, domainName, password, (int)logonType, (int)logonProvider, ref logonToken) != 0) { if (ADVAPI32.DuplicateToken(logonToken, (int)ImpersonationLevel.SecurityIdentification, ref logonTokenDuplicate) != 0) { var wi = new WindowsIdentity(logonTokenDuplicate); wi.Impersonate(); } else { throw new Win32Exception(Marshal.GetLastWin32Error()); } } else { throw new Win32Exception(Marshal.GetLastWin32Error()); } } finally { if (logonToken != IntPtr.Zero) { KERNEL32.CloseHandle(logonToken); } if (logonTokenDuplicate != IntPtr.Zero) { KERNEL32.CloseHandle(logonTokenDuplicate); } } }
protected override void ProcessRecord() { base.ProcessRecord(); IntPtr hToken = IntPtr.Zero; bool openProcessToken = ADVAPI32.OpenProcessToken(ADVAPI32.GetCurrentProcess(), ADVAPI32.TOKEN_ALL_ACCESS, ref hToken); if (!openProcessToken) { int win32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); ThrowTerminatingError(new ErrorRecord(new InvalidOperationException(string.Format("Cannot open process token: {0}", win32Error)), "100", ErrorCategory.ResourceUnavailable, null)); } Process lsassProcess = null; try { switch (this.ParameterSetName) { case "ById": lsassProcess = Process.GetProcessById(processId); break; case "ByName": lsassProcess = Process.GetProcessesByName(processName)[0]; break; case "ProcessObject": lsassProcess = processObject; break; } } catch { ThrowTerminatingError(new ErrorRecord(new FileNotFoundException("Specified cannot be located."), "100", ErrorCategory.ObjectNotFound, null)); } IntPtr lsaToken = IntPtr.Zero; bool processOpen = ADVAPI32.OpenProcessToken(lsassProcess.Handle, ADVAPI32.TOKEN_IMPERSONATE | ADVAPI32.TOKEN_DUPLICATE | ADVAPI32.TOKEN_QUERY, ref lsaToken); if (!processOpen) { int win32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); ThrowTerminatingError(new ErrorRecord(new FileNotFoundException(string.Format("Cannot open process: {0}", win32Error)), "100", ErrorCategory.ConnectionError, null)); } try { WindowsIdentity newId = new WindowsIdentity(hToken); using (WindowsImpersonationContext impersonatedUser = newId.Impersonate()) { IntPtr dupeToken = IntPtr.Zero; int tokenDuplication = ADVAPI32.DuplicateToken(lsaToken, 2, ref dupeToken); if (tokenDuplication < 0) { int win32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); ThrowTerminatingError(new ErrorRecord(new OperationCallFailedException(string.Format("Could not duplicate token: {0}", win32Error)), "100", ErrorCategory.SecurityError, null)); } AdjustToken(hToken, "SeIncreaseQuotaPrivilege"); AdjustToken(hToken, "SeSecurityPrivilege"); AdjustToken(hToken, "SeTakeOwnershipPrivilege"); AdjustToken(hToken, "SeLoadDriverPrivilege"); AdjustToken(hToken, "SeSystemProfilePrivilege"); AdjustToken(hToken, "SeSystemtimePrivilege"); AdjustToken(hToken, "SeProfileSingleProcessPrivilege"); AdjustToken(hToken, "SeIncreaseBasePriorityPrivilege"); AdjustToken(hToken, "SeCreatePagefilePrivilege"); AdjustToken(hToken, "SeBackupPrivilege"); AdjustToken(hToken, "SeRestorePrivilege"); AdjustToken(hToken, "SeShutdownPrivilege"); AdjustToken(hToken, "SeDebugPrivilege"); AdjustToken(hToken, "SeSystemEnvironmentPrivilege"); AdjustToken(hToken, "SeChangeNotifyPrivilege"); AdjustToken(hToken, "SeRemoteShutdownPrivilege"); AdjustToken(hToken, "SeUndockPrivilege"); AdjustToken(hToken, "SeManageVolumePrivilege"); AdjustToken(hToken, "SeImpersonatePrivilege"); AdjustToken(hToken, "SeCreateGlobalPrivilege"); AdjustToken(hToken, "SeTimeZonePrivilege"); AdjustToken(hToken, "SeCreateSymbolicLinkPrivilege"); AdjustToken(hToken, "SeIncreaseWorkingSetPrivilege"); bool setToken = ADVAPI32.SetThreadToken(IntPtr.Zero, dupeToken); if (!setToken) { int win32Error = System.Runtime.InteropServices.Marshal.GetLastWin32Error(); ThrowTerminatingError(new ErrorRecord(new SecurityAccessDeniedException(string.Format("Could not set thread token: {0}", win32Error)), "100", ErrorCategory.SecurityError, null)); } try { Collection <PSObject> results = scriptBlock.Invoke(); WriteObject(results, true); } catch (Exception ex) { ThrowTerminatingError(new ErrorRecord(new ApplicationException(string.Format("An internal error occured", ex.Message), ex), "200", ErrorCategory.NotSpecified, null)); } } } catch (Exception) { ThrowTerminatingError(new ErrorRecord(new SecurityException(string.Format("Could not change identity")), "100", ErrorCategory.SecurityError, null)); } }