From 67cb31fedd64ed9c071e8b7a3017bbae81084e8a Mon Sep 17 00:00:00 2001 From: Jordan Borean Date: Tue, 5 Mar 2024 05:19:59 +1000 Subject: [PATCH 1/4] Get-Process: Remove admin for IncludeUserName Removes the administrator requirements checked on Get-Process -IncludeUserName as it can be used to get the username on processes you currently own. The check was unecessary and the value can be set to null on processes the current user does not have access to. This also changes the logic for translating the SecurityIdentifier in the access token to use the builtin .NET class which handles more scenarios (like Font Driver Host users), and is simpler. --- .../commands/management/Process.cs | 42 +++++-------------- .../resources/ProcessResources.resx | 3 -- .../Get-Process.Tests.ps1 | 12 +----- 3 files changed, 12 insertions(+), 45 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs index 1d877ed5a21..7b834ad26bc 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs @@ -544,20 +544,6 @@ public override Process[] InputObject #region Overrides - /// - /// Check the elevation mode if IncludeUserName is specified. - /// - protected override void BeginProcessing() - { - // The parameter 'IncludeUserName' requires administrator privilege - if (IncludeUserName.IsPresent && !Utils.IsAdministrator()) - { - var ex = new InvalidOperationException(ProcessResources.IncludeUserNameRequiresElevation); - var er = new ErrorRecord(ex, "IncludeUserNameRequiresElevation", ErrorCategory.InvalidOperation, null); - ThrowTerminatingError(er); - } - } - /// /// Write the process objects. /// @@ -685,7 +671,7 @@ protected override void ProcessRecord() } else { - WriteObject(IncludeUserName.IsPresent ? AddUserNameToProcess(process) : (object)process); + WriteObject(IncludeUserName.IsPresent ? AddUserNameToProcess(process) : process); } } } @@ -765,23 +751,15 @@ private static string RetrieveProcessUserName(Process process) } var tokenUser = Marshal.PtrToStructure(tokenUserInfo); - - // Max username is defined as UNLEN = 256 in lmcons.h - // Max domainname is defined as DNLEN = CNLEN = 15 in lmcons.h - // The buffer length must be +1, last position is for a null string terminator. - int userNameLength = 257; - int domainNameLength = 16; - Span userNameStr = stackalloc char[userNameLength]; - Span domainNameStr = stackalloc char[domainNameLength]; - Win32Native.SID_NAME_USE accountType; - - // userNameLength and domainNameLength will be set to actual lengths. - if (!Win32Native.LookupAccountSid(null, tokenUser.User.Sid, userNameStr, ref userNameLength, domainNameStr, ref domainNameLength, out accountType)) + SecurityIdentifier sid = new SecurityIdentifier(tokenUser.User.Sid); + try { - return null; + return sid.Translate(typeof(System.Security.Principal.NTAccount)).Value; + } + catch (IdentityNotMappedException) + { + return sid.Value; } - - userName = string.Concat(domainNameStr.Slice(0, domainNameLength), "\\", userNameStr.Slice(0, userNameLength)); } catch (NotSupportedException) { @@ -898,7 +876,7 @@ public int Timeout _timeOutSpecified = true; } } - + /// /// Gets or sets a value indicating whether to return after any one process exits. /// @@ -1047,7 +1025,7 @@ protected override void EndProcessing() } } } - + if (PassThru) { WriteObject(_processList, enumerateCollection: true); diff --git a/src/Microsoft.PowerShell.Commands.Management/resources/ProcessResources.resx b/src/Microsoft.PowerShell.Commands.Management/resources/ProcessResources.resx index 65513e55f5f..a6f6d286dbe 100644 --- a/src/Microsoft.PowerShell.Commands.Management/resources/ProcessResources.resx +++ b/src/Microsoft.PowerShell.Commands.Management/resources/ProcessResources.resx @@ -204,9 +204,6 @@ Parameters "{0}" and "{1}" cannot be specified at the same time. - - The 'IncludeUserName' parameter requires elevated user rights. Try running the command again in a session that has been opened with elevated user rights (that is, Run as Administrator). - Cannot debug process "{0} ({1})" because of the following error: {2} diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Process.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Process.Tests.ps1 index 90e20a2c479..29a53ee196c 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Process.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Get-Process.Tests.ps1 @@ -1,10 +1,6 @@ # Copyright (c) Microsoft Corporation. # Licensed under the MIT License. Describe "Get-Process for admin" -Tags @('CI', 'RequireAdminOnWindows') { - It "Should support -IncludeUserName" { - (Get-Process -Id $PID -IncludeUserName).UserName | Should -Match $env:USERNAME - } - It "Should support -Module" -Pending:$IsMacOS { $modules = Get-Process -Id $PID -Module $modules.GetType() | Should -BeExactly "System.Object[]" @@ -78,12 +74,8 @@ Describe "Get-Process" -Tags "CI" { (Get-Process -Id $PID).Id | Should -BeExactly $PID } - It "Should fail to run Get-Process with -IncludeUserName without admin" -Skip:(!$IsWindows) { - if (Test-IsElevated) { - Set-ItResult -Skipped -Because "must NOT be run as admin" - } - - { Get-Process -IncludeUserName } | Should -Throw -ErrorId "IncludeUserNameRequiresElevation,Microsoft.PowerShell.Commands.GetProcessCommand" + It "Should support -IncludeUserName" { + (Get-Process -Id $PID -IncludeUserName).UserName | Should -Match $env:USERNAME } It "Should fail to run Get-Process with -Module without admin" -Skip:(!$IsWindows) { From 621ca0e79104ad834c615a842a46d84111a45e7a Mon Sep 17 00:00:00 2001 From: Jordan Borean Date: Tue, 5 Mar 2024 10:43:49 +1000 Subject: [PATCH 2/4] Return null for unknown sid translations --- .../commands/management/Process.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs index 7b834ad26bc..c773176bf5c 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs @@ -758,7 +758,7 @@ private static string RetrieveProcessUserName(Process process) } catch (IdentityNotMappedException) { - return sid.Value; + return null; } } catch (NotSupportedException) From 92655b4d3dae54b7ce9ca9b199d83780fd474076 Mon Sep 17 00:00:00 2001 From: Jordan Borean Date: Tue, 5 Mar 2024 11:59:08 +1000 Subject: [PATCH 3/4] Use outer catch block --- .../commands/management/Process.cs | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs index c773176bf5c..a9b0b9b4794 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs @@ -752,19 +752,16 @@ private static string RetrieveProcessUserName(Process process) var tokenUser = Marshal.PtrToStructure(tokenUserInfo); SecurityIdentifier sid = new SecurityIdentifier(tokenUser.User.Sid); - try - { - return sid.Translate(typeof(System.Security.Principal.NTAccount)).Value; - } - catch (IdentityNotMappedException) - { - return null; - } + return sid.Translate(typeof(System.Security.Principal.NTAccount)).Value; } catch (NotSupportedException) { // The Process not started yet, or it's a process from a remote machine. } + catch (IdentityNotMappedException) + { + // SID cannot be mapped to a user + } catch (InvalidOperationException) { // The Process has exited, Process.Handle will raise this exception. From cf268af57ece24f06028dc07b146c298ba06b672 Mon Sep 17 00:00:00 2001 From: Dongbo Wang Date: Mon, 4 Mar 2024 18:15:19 -0800 Subject: [PATCH 4/4] Update Process.cs --- .../commands/management/Process.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs index a9b0b9b4794..197e3662c25 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Process.cs @@ -752,7 +752,7 @@ private static string RetrieveProcessUserName(Process process) var tokenUser = Marshal.PtrToStructure(tokenUserInfo); SecurityIdentifier sid = new SecurityIdentifier(tokenUser.User.Sid); - return sid.Translate(typeof(System.Security.Principal.NTAccount)).Value; + userName = sid.Translate(typeof(System.Security.Principal.NTAccount)).Value; } catch (NotSupportedException) {