From 141ecd9eeda58e462d4259170d51bf73be9da9c1 Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Sat, 5 Jan 2019 23:18:56 +0530 Subject: [PATCH 01/20] Add -SecurityDescriptor parameter to Set-Service --- .../commands/management/Service.cs | 72 ++++++++++++++++++- .../resources/ServiceResources.resx | 5 +- .../utils/PInvokeDllNames.cs | 2 + 3 files changed, 76 insertions(+), 3 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs index 755130dfde4..44dafe42c18 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs @@ -1560,10 +1560,28 @@ public ServiceStartupType StartupType startupType = value; } } + // We set the initial value to an invalid value so that we can // distinguish when this is and is not set. internal ServiceStartupType startupType = ServiceStartupType.InvalidValue; + /// + /// The following is the definition of the input parameter "SecurityDescriptor". + /// Changes the SecurityDescriptor of the service. + /// + [Parameter] + [Alias("sd")] + [ValidateNotNullOrEmpty] + public string SecurityDescriptor + { + get { return securityDescriptor; } + set + { + securityDescriptor = value; + } + } + private string securityDescriptor ; + /// /// The following is the definition of the input parameter "Status". /// This specifies what state the service should be in (e.g. Running, Stopped, @@ -1718,8 +1736,9 @@ protected override void ProcessRecord() hService = NativeMethods.OpenServiceW( hScManager, Name, - NativeMethods.SERVICE_CHANGE_CONFIG + NativeMethods.SERVICE_CHANGE_CONFIG | NativeMethods.WRITE_DAC | NativeMethods.WRITE_OWNER | NativeMethods.ACCESS_SYSTEM_SECURITY ); + if (IntPtr.Zero == hService) { int lastError = Marshal.GetLastWin32Error(); @@ -1870,6 +1889,34 @@ protected override void ProcessRecord() } } + // Handle the '-SecurityDescriptor' parameter + bool returnStatus = NativeMethods.ConvertStringSecurityDescriptorToSecurityDescriptorW( + securityDescriptor, + NativeMethods.stringSDRevision, + psecurityDescriptor, + IntPtr.Zero); + + if(!string.IsNullOrEmpty(securityDescriptor)) + { + bool executionStatus = NativeMethods.SetServiceObjectSecurity( + hService, + psecurityDescriptor, + IntPtr.Zero + ); + } + + if (!executionStatus) + { + int lastError = Marshal.GetLastWin32Error(); + Win32Exception exception = new Win32Exception(lastError); + WriteNonTerminatingError( + service, + exception, + "CouldNotSetServiceSecurityDescriptor", + ServiceResources.CouldNotSetServiceSecurityDescriptor, + ErrorCategory.PermissionDenied); + } + if (PassThru.IsPresent) { // To display the service, refreshing the service would not show the display name after updating @@ -2567,7 +2614,10 @@ internal static class NativeMethods internal const DWORD SERVICE_CONFIG_DESCRIPTION = 1; internal const DWORD SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3; internal const DWORD SERVICE_CONFIG_SERVICE_SID_INFO = 5; - + internal const DWORD WRITE_DAC =18; + internal const DWORD WRITE_OWNER =19; + internal const DWORD ACCESS_SYSTEM_SECURITY =24; + internal const DWORD stringSDRevision = 1; internal const DWORD SERVICE_WIN32_OWN_PROCESS = 0x10; internal const DWORD SERVICE_ERROR_NORMAL = 1; @@ -2688,6 +2738,24 @@ NakedWin32Handle CreateServiceW( [In] IntPtr lpPassword ); + + [DllImport(PinvokeDllNames.SetServiceObjectSecurityDllName, CharSet = CharSet.Unicode, SetLastError = true)] + internal static extern + bool SetServiceObjectSecurity( + NakedWin32Handle hSCManager, + DWORD dwSecurityInformation, + IntPtr lpSecurityDescriptor + ); + + [DllImport(PinvokeDllNames.ConvertStringSecurityDescriptorToSecurityDescriptorWDllName, CharSet = CharSet.Unicode, SetLastError = true)] + internal static extern + bool ConvertStringSecurityDescriptorToSecurityDescriptorW( + [In, MarshalAs(UnmanagedType.LPWStr)] string stringSecurityDescriptor, + DWORD stringSDRevision, + IntPtr psecurityDescriptor, + IntPtr psecurityDescriptorSize + ); + /// /// CreateJobObject API creates or opens a job object. /// diff --git a/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx b/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx index 7f8538e5d02..61b28d768dc 100644 --- a/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx +++ b/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx @@ -168,6 +168,9 @@ Service '{1} ({0})' automatic (delayed start) cannot be configured due to the following error: {2} + + Service '{1} ({0})' security descriptor cannot be configured due to the following error: {2} + Service '{1} ({0})' cannot be created due to the following error: {2} @@ -179,7 +182,7 @@ Service '{1} ({0})' cannot be removed due to the following error: {2} - + 'Cannot access dependent services of '{1} ({0})' diff --git a/src/System.Management.Automation/utils/PInvokeDllNames.cs b/src/System.Management.Automation/utils/PInvokeDllNames.cs index a9c8cc022be..48171d93920 100644 --- a/src/System.Management.Automation/utils/PInvokeDllNames.cs +++ b/src/System.Management.Automation/utils/PInvokeDllNames.cs @@ -137,5 +137,7 @@ internal static class PinvokeDllNames internal const string DeleteServiceDllName = "api-ms-win-service-management-l1-1-0.dll"; /*124*/ internal const string QueryServiceConfigDllName = "api-ms-win-service-management-l2-1-0.dll"; /*125*/ internal const string QueryServiceConfig2DllName = "api-ms-win-service-management-l2-1-0.dll"; /*126*/ + internal const string SetServiceObjectSecurityDllName = "api-ms-win-service-management-l2-1-0.dll"; /*127*/ + internal const string ConvertStringSecurityDescriptorToSecurityDescriptorWDllName = "api-ms-win-service-management-l2-1-0.dll"; /*128*/ } } From 69d909a770b240af901d0e38b071ce66b10f455e Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Sat, 5 Jan 2019 23:22:06 +0530 Subject: [PATCH 02/20] Define psecurityDescriptor --- .../commands/management/Service.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs index 44dafe42c18..92bbd44dd20 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs @@ -1890,6 +1890,9 @@ protected override void ProcessRecord() } // Handle the '-SecurityDescriptor' parameter + + IntPtr psecurityDescriptor = IntPtr.Zero; + bool returnStatus = NativeMethods.ConvertStringSecurityDescriptorToSecurityDescriptorW( securityDescriptor, NativeMethods.stringSDRevision, From 6eff7feba9137298d8c07394c827764c1fdfb12c Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Fri, 11 Jan 2019 23:33:25 +0530 Subject: [PATCH 03/20] change in status variable --- .../commands/management/Service.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs index a6cdf7fb7f1..aba53fd839e 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs @@ -1901,14 +1901,14 @@ protected override void ProcessRecord() if(!string.IsNullOrEmpty(securityDescriptor)) { - bool executionStatus = NativeMethods.SetServiceObjectSecurity( + bool status = NativeMethods.SetServiceObjectSecurity( hService, psecurityDescriptor, IntPtr.Zero ); } - if (!executionStatus) + if (!status) { int lastError = Marshal.GetLastWin32Error(); Win32Exception exception = new Win32Exception(lastError); From 01569ca4d5eeaf82b5240b3f8235c799d7ceb35c Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Mon, 21 Jan 2019 23:40:58 +0530 Subject: [PATCH 04/20] DACL Support only --- .../commands/management/Service.cs | 56 +++++++------------ .../utils/PInvokeDllNames.cs | 1 - 2 files changed, 21 insertions(+), 36 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs index aba53fd839e..faed98ff8da 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs @@ -14,6 +14,7 @@ using System.Runtime.Serialization; using System.Runtime.InteropServices; // Marshal, DllImport using System.Security.Permissions; +using System.Security.AccessControl; using NakedWin32Handle = System.IntPtr; using DWORD = System.UInt32; @@ -1574,13 +1575,9 @@ public ServiceStartupType StartupType [ValidateNotNullOrEmpty] public string SecurityDescriptor { - get { return securityDescriptor; } - set - { - securityDescriptor = value; - } + get; + set; } - private string securityDescriptor ; /// /// The following is the definition of the input parameter "Status". @@ -1736,7 +1733,7 @@ protected override void ProcessRecord() hService = NativeMethods.OpenServiceW( hScManager, Name, - NativeMethods.SERVICE_CHANGE_CONFIG | NativeMethods.WRITE_DAC | NativeMethods.WRITE_OWNER | NativeMethods.ACCESS_SYSTEM_SECURITY + NativeMethods.SERVICE_CHANGE_CONFIG | NativeMethods.WRITE_DAC | NativeMethods.WRITE_OWNER ); if (IntPtr.Zero == hService) @@ -1890,22 +1887,22 @@ protected override void ProcessRecord() } // Handle the '-SecurityDescriptor' parameter + RawSecurityDescriptor rawSecurityDescriptor = new RawSecurityDescriptor(SecurityDescriptor); + RawAcl rawDiscretionaryAcl = rawSecurityDescriptor.DiscretionaryAcl ; + DiscretionaryAcl discretionaryAcl = new DiscretionaryAcl (false, false, rawDiscretionaryAcl ); - IntPtr psecurityDescriptor = IntPtr.Zero; + byte[] rawDacl = new byte[discretionaryAcl.BinaryLength]; + discretionaryAcl.GetBinaryForm(rawDacl, 0); + rawSecurityDescriptor.DiscretionaryAcl = new RawAcl(rawDacl, 0); + byte[] securityDescriptorByte = new byte[rawSecurityDescriptor.BinaryLength]; + rawSecurityDescriptor.GetBinaryForm(securityDescriptorByte, 0); - bool returnStatus = NativeMethods.ConvertStringSecurityDescriptorToSecurityDescriptorW( - securityDescriptor, - NativeMethods.stringSDRevision, - psecurityDescriptor, - IntPtr.Zero); - - if(!string.IsNullOrEmpty(securityDescriptor)) + if(!string.IsNullOrEmpty(SecurityDescriptor)) { - bool status = NativeMethods.SetServiceObjectSecurity( - hService, - psecurityDescriptor, - IntPtr.Zero - ); + status = NativeMethods.SetServiceObjectSecurity( + hService, + SecurityInfos.DiscretionaryAcl, + securityDescriptorByte); } if (!status) @@ -2617,10 +2614,8 @@ internal static class NativeMethods internal const DWORD SERVICE_CONFIG_DESCRIPTION = 1; internal const DWORD SERVICE_CONFIG_DELAYED_AUTO_START_INFO = 3; internal const DWORD SERVICE_CONFIG_SERVICE_SID_INFO = 5; - internal const DWORD WRITE_DAC =18; - internal const DWORD WRITE_OWNER =19; - internal const DWORD ACCESS_SYSTEM_SECURITY =24; - internal const DWORD stringSDRevision = 1; + internal const DWORD WRITE_DAC = 262144; + internal const DWORD WRITE_OWNER =524288; internal const DWORD SERVICE_WIN32_OWN_PROCESS = 0x10; internal const DWORD SERVICE_ERROR_NORMAL = 1; @@ -2746,17 +2741,8 @@ [In] IntPtr lpPassword internal static extern bool SetServiceObjectSecurity( NakedWin32Handle hSCManager, - DWORD dwSecurityInformation, - IntPtr lpSecurityDescriptor - ); - - [DllImport(PinvokeDllNames.ConvertStringSecurityDescriptorToSecurityDescriptorWDllName, CharSet = CharSet.Unicode, SetLastError = true)] - internal static extern - bool ConvertStringSecurityDescriptorToSecurityDescriptorW( - [In, MarshalAs(UnmanagedType.LPWStr)] string stringSecurityDescriptor, - DWORD stringSDRevision, - IntPtr psecurityDescriptor, - IntPtr psecurityDescriptorSize + System.Security.AccessControl.SecurityInfos dwSecurityInformation, + byte[] lpSecurityDescriptor ); /// diff --git a/src/System.Management.Automation/utils/PInvokeDllNames.cs b/src/System.Management.Automation/utils/PInvokeDllNames.cs index 48171d93920..d0ce5ea844a 100644 --- a/src/System.Management.Automation/utils/PInvokeDllNames.cs +++ b/src/System.Management.Automation/utils/PInvokeDllNames.cs @@ -138,6 +138,5 @@ internal static class PinvokeDllNames internal const string QueryServiceConfigDllName = "api-ms-win-service-management-l2-1-0.dll"; /*125*/ internal const string QueryServiceConfig2DllName = "api-ms-win-service-management-l2-1-0.dll"; /*126*/ internal const string SetServiceObjectSecurityDllName = "api-ms-win-service-management-l2-1-0.dll"; /*127*/ - internal const string ConvertStringSecurityDescriptorToSecurityDescriptorWDllName = "api-ms-win-service-management-l2-1-0.dll"; /*128*/ } } From 8c28270a8f6e1d102c74ff6ce96bbf8d7cfe9920 Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Sat, 26 Jan 2019 23:30:39 +0530 Subject: [PATCH 05/20] Addressing review comments --- .../commands/management/Service.cs | 47 +++++++++---------- .../resources/ServiceResources.resx | 4 +- 2 files changed, 24 insertions(+), 27 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs index faed98ff8da..f65c47f97f9 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs @@ -1567,13 +1567,13 @@ public ServiceStartupType StartupType internal ServiceStartupType startupType = ServiceStartupType.InvalidValue; /// - /// The following is the definition of the input parameter "SecurityDescriptor". - /// Changes the SecurityDescriptor of the service. + /// The following is the definition of the input parameter "SecurityDescriptorSddl". + /// Sets the SecurityDescriptorSddl of the service using a SDDL string. /// [Parameter] [Alias("sd")] [ValidateNotNullOrEmpty] - public string SecurityDescriptor + public string SecurityDescriptorSddl { get; set; @@ -1886,35 +1886,32 @@ protected override void ProcessRecord() } } - // Handle the '-SecurityDescriptor' parameter - RawSecurityDescriptor rawSecurityDescriptor = new RawSecurityDescriptor(SecurityDescriptor); - RawAcl rawDiscretionaryAcl = rawSecurityDescriptor.DiscretionaryAcl ; - DiscretionaryAcl discretionaryAcl = new DiscretionaryAcl (false, false, rawDiscretionaryAcl ); + // Handle the '-SecurityDescriptorSddl' parameter + if(!string.IsNullOrEmpty(SecurityDescriptorSddl)) + { + var rawSecurityDescriptor = new RawSecurityDescriptor(SecurityDescriptorSddl); + RawAcl rawDiscretionaryAcl = rawSecurityDescriptor.DiscretionaryAcl ; + var discretionaryAcl = new DiscretionaryAcl (false, false, rawDiscretionaryAcl ); - byte[] rawDacl = new byte[discretionaryAcl.BinaryLength]; - discretionaryAcl.GetBinaryForm(rawDacl, 0); - rawSecurityDescriptor.DiscretionaryAcl = new RawAcl(rawDacl, 0); - byte[] securityDescriptorByte = new byte[rawSecurityDescriptor.BinaryLength]; - rawSecurityDescriptor.GetBinaryForm(securityDescriptorByte, 0); + byte[] rawDacl = new byte[discretionaryAcl.BinaryLength]; + discretionaryAcl.GetBinaryForm(rawDacl, 0); + rawSecurityDescriptor.DiscretionaryAcl = new RawAcl(rawDacl, 0); + byte[] securityDescriptorByte = new byte[rawSecurityDescriptor.BinaryLength]; + rawSecurityDescriptor.GetBinaryForm(securityDescriptorByte, 0); - if(!string.IsNullOrEmpty(SecurityDescriptor)) - { status = NativeMethods.SetServiceObjectSecurity( hService, SecurityInfos.DiscretionaryAcl, securityDescriptorByte); - } - if (!status) - { - int lastError = Marshal.GetLastWin32Error(); - Win32Exception exception = new Win32Exception(lastError); - WriteNonTerminatingError( - service, - exception, - "CouldNotSetServiceSecurityDescriptor", - ServiceResources.CouldNotSetServiceSecurityDescriptor, - ErrorCategory.PermissionDenied); + + if (!status) + { + int lastError = Marshal.GetLastWin32Error(); + Win32Exception exception = new Win32Exception(lastError); + string errorMessage = StringUtil.Format(ServiceResources.CouldNotSetServiceSecurityDescriptorSddl,Name,exception.Message); + throw new Exception(errorMessage); + } } if (PassThru.IsPresent) diff --git a/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx b/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx index 61b28d768dc..3792ce8db99 100644 --- a/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx +++ b/src/Microsoft.PowerShell.Commands.Management/resources/ServiceResources.resx @@ -168,8 +168,8 @@ Service '{1} ({0})' automatic (delayed start) cannot be configured due to the following error: {2} - - Service '{1} ({0})' security descriptor cannot be configured due to the following error: {2} + + Service '{0}' security descriptor cannot be configured due to the following error: {1} Service '{1} ({0})' cannot be created due to the following error: {2} From c56687eed330117700aaf4d418d45cc4375e761f Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Mon, 11 Feb 2019 23:05:56 +0530 Subject: [PATCH 06/20] add unit tests --- .../Set-Service.Tests.ps1 | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 index 5020e3dce45..c39870bbec7 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 @@ -9,14 +9,15 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW if ($IsWindows) { $userName = "testuserservices" $testPass = "Secret123!" + $SecurityDescriptorSddl = 'D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(D;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)' net user $userName $testPass /add > $null $password = ConvertTo-SecureString $testPass -AsPlainText -Force $creds = [pscredential]::new(".\$userName", $password) + $svcbinaryname = New-Item -Path TestDrive:\TestExecutable.exe -ItemType File $testservicename1 = "testservice1" $testservicename2 = "testservice2" - $svcbinaryname = "TestService" - $svccmd = Get-Command $svcbinaryname + $svccmd = Get-Command $svcbinaryname.FullName $svccmd | Should -Not -BeNullOrEmpty $svcfullpath = $svccmd.Path $testservice1 = New-Service -BinaryPathName $svcfullpath -Name $testservicename1 @@ -72,6 +73,10 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW @{ script = {Set-Service foo -StartupType bar -ErrorAction Stop}; errorid = "CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.SetServiceCommand" + }, + @{ + script = {Set-Service -Name $testservicename1 -SecurityDescriptorSddl 'D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA' }; + errorid = "System.ArgumentException,Microsoft.PowerShell.Commands.SetServiceCommand" } ) { param($script, $errorid) From 5fdfc7a0ad821a9fcd5f0a46b974c9085f4d72ca Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Sat, 9 Mar 2019 23:57:49 +0530 Subject: [PATCH 07/20] using pinned handle --- .../commands/management/Service.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs index f65c47f97f9..604b4573bf2 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs @@ -1889,6 +1889,8 @@ protected override void ProcessRecord() // Handle the '-SecurityDescriptorSddl' parameter if(!string.IsNullOrEmpty(SecurityDescriptorSddl)) { + //IntPtr hDacl = IntPtr.Zero; + IntPtr lpDacl = IntPtr.Zero; var rawSecurityDescriptor = new RawSecurityDescriptor(SecurityDescriptorSddl); RawAcl rawDiscretionaryAcl = rawSecurityDescriptor.DiscretionaryAcl ; var discretionaryAcl = new DiscretionaryAcl (false, false, rawDiscretionaryAcl ); @@ -1899,11 +1901,15 @@ protected override void ProcessRecord() byte[] securityDescriptorByte = new byte[rawSecurityDescriptor.BinaryLength]; rawSecurityDescriptor.GetBinaryForm(securityDescriptorByte, 0); + GCHandle hDacl = GCHandle.Alloc(rawDacl, GCHandleType.Pinned); + lpDacl = hDacl.AddrOfPinnedObject(); + status = NativeMethods.SetServiceObjectSecurity( hService, SecurityInfos.DiscretionaryAcl, - securityDescriptorByte); + lpDacl); + hDacl.Free(); if (!status) { @@ -2739,7 +2745,7 @@ internal static extern bool SetServiceObjectSecurity( NakedWin32Handle hSCManager, System.Security.AccessControl.SecurityInfos dwSecurityInformation, - byte[] lpSecurityDescriptor + [In] IntPtr lpSecurityDescriptor ); /// From 042ee84d6863e88f94ce752d7efb270b4944cac6 Mon Sep 17 00:00:00 2001 From: "Mathias R. Jessen" Date: Sun, 10 Mar 2019 03:40:48 +0100 Subject: [PATCH 08/20] Fix sddl handle in Set-Service Alloc pinned handle for `securityDescriptorByte` rather than `rawDacl`, change error handling behavior to write a non-terminating error on failure (throwing exceptions is no good here, will be swallowed by outer tryf block) and finally attempt to safely free the pinned handle --- .../commands/management/Service.cs | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs index 604b4573bf2..084c012804d 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs @@ -1889,8 +1889,6 @@ protected override void ProcessRecord() // Handle the '-SecurityDescriptorSddl' parameter if(!string.IsNullOrEmpty(SecurityDescriptorSddl)) { - //IntPtr hDacl = IntPtr.Zero; - IntPtr lpDacl = IntPtr.Zero; var rawSecurityDescriptor = new RawSecurityDescriptor(SecurityDescriptorSddl); RawAcl rawDiscretionaryAcl = rawSecurityDescriptor.DiscretionaryAcl ; var discretionaryAcl = new DiscretionaryAcl (false, false, rawDiscretionaryAcl ); @@ -1901,22 +1899,33 @@ protected override void ProcessRecord() byte[] securityDescriptorByte = new byte[rawSecurityDescriptor.BinaryLength]; rawSecurityDescriptor.GetBinaryForm(securityDescriptorByte, 0); - GCHandle hDacl = GCHandle.Alloc(rawDacl, GCHandleType.Pinned); - lpDacl = hDacl.AddrOfPinnedObject(); - - status = NativeMethods.SetServiceObjectSecurity( - hService, - SecurityInfos.DiscretionaryAcl, - lpDacl); - - hDacl.Free(); + GCHandle hDacl = GCHandle.Alloc(securityDescriptorByte, GCHandleType.Pinned); + try + { + status = NativeMethods.SetServiceObjectSecurity( + hService, + SecurityInfos.DiscretionaryAcl, + hDacl.AddrOfPinnedObject()); - if (!status) + if (!status) + { + int lastError = Marshal.GetLastWin32Error(); + Win32Exception exception = new Win32Exception(lastError); + bool accessDenied = exception.NativeErrorCode == 0x5; + WriteNonTerminatingError( + service, + exception, + nameof(ServiceResources.CouldNotSetServiceSecurityDescriptorSddl), + StringUtil.Format(ServiceResources.CouldNotSetServiceSecurityDescriptorSddl, Name, exception.Message), + accessDenied ? ErrorCategory.PermissionDenied : ErrorCategory.WriteError); + } + } + finally { - int lastError = Marshal.GetLastWin32Error(); - Win32Exception exception = new Win32Exception(lastError); - string errorMessage = StringUtil.Format(ServiceResources.CouldNotSetServiceSecurityDescriptorSddl,Name,exception.Message); - throw new Exception(errorMessage); + if (hDacl.IsAllocated) + { + hDacl.Free(); + } } } From 7c1a761395a49b1d67606ccc5837142ff2e75cbb Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Wed, 13 Mar 2019 00:25:50 +0530 Subject: [PATCH 09/20] add unit tests --- .../commands/management/Service.cs | 41 +++++++------------ .../Set-Service.Tests.ps1 | 21 +++++++++- 2 files changed, 34 insertions(+), 28 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs index 084c012804d..bbc3864ca03 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs @@ -1899,33 +1899,22 @@ protected override void ProcessRecord() byte[] securityDescriptorByte = new byte[rawSecurityDescriptor.BinaryLength]; rawSecurityDescriptor.GetBinaryForm(securityDescriptorByte, 0); - GCHandle hDacl = GCHandle.Alloc(securityDescriptorByte, GCHandleType.Pinned); - try - { - status = NativeMethods.SetServiceObjectSecurity( - hService, - SecurityInfos.DiscretionaryAcl, - hDacl.AddrOfPinnedObject()); + status = NativeMethods.SetServiceObjectSecurity( + hService, + SecurityInfos.DiscretionaryAcl, + securityDescriptorByte); - if (!status) - { - int lastError = Marshal.GetLastWin32Error(); - Win32Exception exception = new Win32Exception(lastError); - bool accessDenied = exception.NativeErrorCode == 0x5; - WriteNonTerminatingError( - service, - exception, - nameof(ServiceResources.CouldNotSetServiceSecurityDescriptorSddl), - StringUtil.Format(ServiceResources.CouldNotSetServiceSecurityDescriptorSddl, Name, exception.Message), - accessDenied ? ErrorCategory.PermissionDenied : ErrorCategory.WriteError); - } - } - finally + if (!status) { - if (hDacl.IsAllocated) - { - hDacl.Free(); - } + int lastError = Marshal.GetLastWin32Error(); + Win32Exception exception = new Win32Exception(lastError); + bool accessDenied = exception.NativeErrorCode == 0x5; + WriteNonTerminatingError( + service, + exception, + nameof(ServiceResources.CouldNotSetServiceSecurityDescriptorSddl), + StringUtil.Format(ServiceResources.CouldNotSetServiceSecurityDescriptorSddl, Name, exception.Message), + accessDenied ? ErrorCategory.PermissionDenied : ErrorCategory.WriteError); } } @@ -2754,7 +2743,7 @@ internal static extern bool SetServiceObjectSecurity( NakedWin32Handle hSCManager, System.Security.AccessControl.SecurityInfos dwSecurityInformation, - [In] IntPtr lpSecurityDescriptor + byte[] lpSecurityDescriptor ); /// diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 index c39870bbec7..b28f7d73579 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 @@ -9,7 +9,8 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW if ($IsWindows) { $userName = "testuserservices" $testPass = "Secret123!" - $SecurityDescriptorSddl = 'D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(D;;CCLCSWLOCRRC;;;IU)(A;;CCLCSWLOCRRC;;;SU)' + $SecurityDescriptorSddl = 'D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;SU)' + $WrongSecurityDescriptorSddl = 'D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BB)(A;;CCLCSWLOCRRC;;;SU)' net user $userName $testPass /add > $null $password = ConvertTo-SecureString $testPass -AsPlainText -Force $creds = [pscredential]::new(".\$userName", $password) @@ -75,7 +76,7 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW errorid = "CannotConvertArgumentNoMessage,Microsoft.PowerShell.Commands.SetServiceCommand" }, @{ - script = {Set-Service -Name $testservicename1 -SecurityDescriptorSddl 'D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA' }; + script = {Set-Service -Name $testservicename1 -SecurityDescriptorSddl $WrongSecurityDescriptorSddl }; errorid = "System.ArgumentException,Microsoft.PowerShell.Commands.SetServiceCommand" } ) { @@ -83,6 +84,22 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW { & $script } | Should -Throw -ErrorId $errorid } + + It "Sets securitydescriptor of service using Set-Service " { + Set-Service -Name $TestServiceName1 -SecurityDescriptor $SecurityDescriptorSddl + $Counter = 0 + $ExpectedSDDL = ConvertFrom-SddlString -Sddl $SecurityDescriptorSddl + $UpdatedSDDL = ConvertFrom-SddlString -Sddl (sc sdshow $TestServiceName1)[-1] + + $UpdatedSDDL.Owner | Should -Be $ExpectedSDDL.Owner + $UpdatedSDDL.Group | Should -Be $ExpectedSDDL.Group + $UpdatedSDDL.DiscretionaryAcl.Count | Should -Be $ExpectedSDDL.DiscretionaryAcl.Count + $UpdatedSDDL.DiscretionaryAcl | ForEach-Object -Process { + $_ | Should -Be $ExpectedSDDL.DiscretionaryAcl[$Counter] + $Counter++ + } + } + It "Set-Service can change '' to ''" -TestCases @( @{parameter = "Description"; value = "hello"}, @{parameter = "DisplayName"; value = "test spooler"}, From 7368a4d60be1afe9a189293b14b875f363228828 Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Wed, 13 Mar 2019 01:00:33 +0530 Subject: [PATCH 10/20] review comment change for error msg and const code --- .../commands/management/Service.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs index bbc3864ca03..203d791b74d 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs @@ -1908,13 +1908,13 @@ protected override void ProcessRecord() { int lastError = Marshal.GetLastWin32Error(); Win32Exception exception = new Win32Exception(lastError); - bool accessDenied = exception.NativeErrorCode == 0x5; + bool accessDenied = exception.NativeErrorCode == NativeMethods.ERROR_ACCESS_DENIED; WriteNonTerminatingError( service, exception, nameof(ServiceResources.CouldNotSetServiceSecurityDescriptorSddl), StringUtil.Format(ServiceResources.CouldNotSetServiceSecurityDescriptorSddl, Name, exception.Message), - accessDenied ? ErrorCategory.PermissionDenied : ErrorCategory.WriteError); + accessDenied ? ErrorCategory.PermissionDenied : ErrorCategory.InvalidOperation); } } @@ -2602,6 +2602,7 @@ internal static class NativeMethods internal const int ERROR_SERVICE_ALREADY_RUNNING = 1056; internal const int ERROR_SERVICE_NOT_ACTIVE = 1062; internal const int ERROR_INSUFFICIENT_BUFFER = 122; + internal const DWORD ERROR_ACCESS_DENIED = 0x5; internal const DWORD SC_MANAGER_CONNECT = 1; internal const DWORD SC_MANAGER_CREATE_SERVICE = 2; internal const DWORD SC_MANAGER_ALL_ACCESS = 0xf003f; From e43facaf559ba40f1ab85652cdcad63f0796380a Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Sat, 30 Mar 2019 14:09:16 +0530 Subject: [PATCH 11/20] adding comment as per review --- .../Microsoft.PowerShell.Management/Set-Service.Tests.ps1 | 2 ++ 1 file changed, 2 insertions(+) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 index b28f7d73579..b04b0f6c62b 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 @@ -89,6 +89,8 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW Set-Service -Name $TestServiceName1 -SecurityDescriptor $SecurityDescriptorSddl $Counter = 0 $ExpectedSDDL = ConvertFrom-SddlString -Sddl $SecurityDescriptorSddl + + # Selecting the last item in the output array as below command gives plain text output from the native sc.exe. $UpdatedSDDL = ConvertFrom-SddlString -Sddl (sc sdshow $TestServiceName1)[-1] $UpdatedSDDL.Owner | Should -Be $ExpectedSDDL.Owner From 0b9a7bb1780dfdfa543450e453dc6e5dc2ee7439 Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Sat, 30 Mar 2019 14:14:46 +0530 Subject: [PATCH 12/20] adding comment as per review --- .../Microsoft.PowerShell.Management/Set-Service.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 index b04b0f6c62b..739bb28f94c 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 @@ -91,7 +91,7 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW $ExpectedSDDL = ConvertFrom-SddlString -Sddl $SecurityDescriptorSddl # Selecting the last item in the output array as below command gives plain text output from the native sc.exe. - $UpdatedSDDL = ConvertFrom-SddlString -Sddl (sc sdshow $TestServiceName1)[-1] + $UpdatedSDDL = ConvertFrom-SddlString -Sddl (sc sdshow $TestServiceName1)[1] $UpdatedSDDL.Owner | Should -Be $ExpectedSDDL.Owner $UpdatedSDDL.Group | Should -Be $ExpectedSDDL.Group From 2067c21fa636096432808dd90f6d18f6570d5bb4 Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Sat, 30 Mar 2019 14:15:35 +0530 Subject: [PATCH 13/20] adding comment as per review --- .../Microsoft.PowerShell.Management/Set-Service.Tests.ps1 | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 index 739bb28f94c..ff57f1051aa 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 @@ -90,7 +90,7 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW $Counter = 0 $ExpectedSDDL = ConvertFrom-SddlString -Sddl $SecurityDescriptorSddl - # Selecting the last item in the output array as below command gives plain text output from the native sc.exe. + # Selecting the first item in the output array as below command gives plain text output from the native sc.exe. $UpdatedSDDL = ConvertFrom-SddlString -Sddl (sc sdshow $TestServiceName1)[1] $UpdatedSDDL.Owner | Should -Be $ExpectedSDDL.Owner From 9a96aac53ed674c420eafe28db2710f11443a671 Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Tue, 2 Apr 2019 00:05:07 +0530 Subject: [PATCH 14/20] revert dummy service executable creation --- .../Microsoft.PowerShell.Management/Set-Service.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 index ff57f1051aa..10d35ecb205 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 @@ -15,10 +15,10 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW $password = ConvertTo-SecureString $testPass -AsPlainText -Force $creds = [pscredential]::new(".\$userName", $password) - $svcbinaryname = New-Item -Path TestDrive:\TestExecutable.exe -ItemType File $testservicename1 = "testservice1" $testservicename2 = "testservice2" - $svccmd = Get-Command $svcbinaryname.FullName + $svcbinaryname = "TestService" + $svccmd = Get-Command $svcbinaryname $svccmd | Should -Not -BeNullOrEmpty $svcfullpath = $svccmd.Path $testservice1 = New-Service -BinaryPathName $svcfullpath -Name $testservicename1 From ab4fbd0cd051ce918d78c88b2181f96acdc3b994 Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Wed, 3 Apr 2019 01:03:43 +0530 Subject: [PATCH 15/20] review comment fixes --- .../commands/management/Service.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs index 203d791b74d..7fe3c06e7c4 100644 --- a/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs +++ b/src/Microsoft.PowerShell.Commands.Management/commands/management/Service.cs @@ -1567,7 +1567,6 @@ public ServiceStartupType StartupType internal ServiceStartupType startupType = ServiceStartupType.InvalidValue; /// - /// The following is the definition of the input parameter "SecurityDescriptorSddl". /// Sets the SecurityDescriptorSddl of the service using a SDDL string. /// [Parameter] @@ -1886,7 +1885,6 @@ protected override void ProcessRecord() } } - // Handle the '-SecurityDescriptorSddl' parameter if(!string.IsNullOrEmpty(SecurityDescriptorSddl)) { var rawSecurityDescriptor = new RawSecurityDescriptor(SecurityDescriptorSddl); @@ -2740,6 +2738,7 @@ [In] IntPtr lpPassword [DllImport(PinvokeDllNames.SetServiceObjectSecurityDllName, CharSet = CharSet.Unicode, SetLastError = true)] + [return: MarshalAs(UnmanagedType.Bool)] internal static extern bool SetServiceObjectSecurity( NakedWin32Handle hSCManager, From 644e2d0309650c3898bca83bfbbe5d8c462e984e Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Sat, 6 Apr 2019 01:21:12 +0530 Subject: [PATCH 16/20] random password generation --- .../Set-Service.Tests.ps1 | 20 +++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 index 10d35ecb205..89fabfab625 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 @@ -1,5 +1,8 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. +Import-Module (Join-Path -Path $PSScriptRoot '..\Microsoft.PowerShell.Security\certificateCommon.psm1') -Force +Import-Module (Join-Path -Path $PSScriptRoot '..\..\..\Tools\Modules\HelpersCommon\HelpersCommon.psm1') -Force + Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows" { BeforeAll { $originalDefaultParameterValues = $PSDefaultParameterValues.Clone() @@ -8,12 +11,11 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW } if ($IsWindows) { $userName = "testuserservices" - $testPass = "Secret123!" + $testPass = New-CertificatePassword + $creds = [pscredential]::new(".\$userName", $testPass) $SecurityDescriptorSddl = 'D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;SU)' $WrongSecurityDescriptorSddl = 'D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BB)(A;;CCLCSWLOCRRC;;;SU)' - net user $userName $testPass /add > $null - $password = ConvertTo-SecureString $testPass -AsPlainText -Force - $creds = [pscredential]::new(".\$userName", $password) + net user $userName $creds.GetNetworkCredential().Password /add > $null $testservicename1 = "testservice1" $testservicename2 = "testservice2" @@ -166,12 +168,11 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW try { $startUsername = "user1" $endUsername = "user2" - $testPass = "Secret123!" + $testPass = New-CertificatePassword $servicename = "testsetcredential" - net user $startUsername $testPass /add > $null - net user $endUsername $testPass /add > $null - $password = ConvertTo-SecureString $testPass -AsPlainText -Force - $creds = [pscredential]::new(".\$startUsername", $password) + $creds = [pscredential]::new(".\$endUsername", $testPass) + net user $startUsername $creds.GetNetworkCredential().Password /add > $null + net user $endUsername $creds.GetNetworkCredential().Password /add > $null $parameters = @{ Name = $servicename; BinaryPathName = "$PSHOME\pwsh.exe"; @@ -183,7 +184,6 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW $service = Get-CimInstance Win32_Service -Filter "name='$servicename'" $service.StartName | Should -BeExactly $creds.UserName - $creds = [pscredential]::new(".\$endUsername", $password) Set-Service -Name $servicename -Credential $creds $service = Get-CimInstance Win32_Service -Filter "name='$servicename'" $service.StartName | Should -BeExactly $creds.UserName From c77cf2c7c87fc46eb938776420154fd2782f7074 Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Sat, 6 Apr 2019 09:17:49 +0530 Subject: [PATCH 17/20] changes as per suggestion --- .../Microsoft.PowerShell.Management/Set-Service.Tests.ps1 | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 index 89fabfab625..665ade30948 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 @@ -1,7 +1,7 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. -Import-Module (Join-Path -Path $PSScriptRoot '..\Microsoft.PowerShell.Security\certificateCommon.psm1') -Force -Import-Module (Join-Path -Path $PSScriptRoot '..\..\..\Tools\Modules\HelpersCommon\HelpersCommon.psm1') -Force +Import-Module (Join-Path -Path $PSScriptRoot '..\Microsoft.PowerShell.Security\certificateCommon.psm1') +Import-Module HelpersCommon Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows" { BeforeAll { From e81813e22d7651da4fe13311d779c6ae1f663013 Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Sun, 2 Jun 2019 22:05:09 +0530 Subject: [PATCH 18/20] removing explicit loading of HelpersCommon module --- .../Microsoft.PowerShell.Management/Set-Service.Tests.ps1 | 1 - 1 file changed, 1 deletion(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 index 665ade30948..b249260017a 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 @@ -1,7 +1,6 @@ # Copyright (c) Microsoft Corporation. All rights reserved. # Licensed under the MIT License. Import-Module (Join-Path -Path $PSScriptRoot '..\Microsoft.PowerShell.Security\certificateCommon.psm1') -Import-Module HelpersCommon Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnWindows" { BeforeAll { From 761778e8195682a536c0692fc9cdc7a3f926a86f Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Wed, 3 Jul 2019 23:43:15 +0530 Subject: [PATCH 19/20] create complex password --- .../Microsoft.PowerShell.Management/Set-Service.Tests.ps1 | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 index b249260017a..19b630dfeea 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 @@ -10,8 +10,9 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW } if ($IsWindows) { $userName = "testuserservices" - $testPass = New-CertificatePassword - $creds = [pscredential]::new(".\$userName", $testPass) + $Password = ([char[]]([char]33..[char]95) + ([char[]]([char]97..[char]126)) + 0..9 | Sort-Object {Get-Random})[0..12] -join '' + $testPass = (New-Object -TypeName Net.NetworkCredential("", $Password)).SecurePassword + $creds = [pscredential]::new(".\$userName", $testPass) $SecurityDescriptorSddl = 'D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BA)(A;;CCLCSWLOCRRC;;;SU)' $WrongSecurityDescriptorSddl = 'D:(A;;CCLCSWRPWPDTLOCRRC;;;SY)(A;;CCDCLCSWRPWPDTLOCRSDRCWDWO;;;BB)(A;;CCLCSWLOCRRC;;;SU)' net user $userName $creds.GetNetworkCredential().Password /add > $null From 51add23c98e1ca7ca0a60f5b0741a649452fc55d Mon Sep 17 00:00:00 2001 From: kvprasoon Date: Thu, 4 Jul 2019 10:05:10 +0530 Subject: [PATCH 20/20] create complex pwd --- .../Microsoft.PowerShell.Management/Set-Service.Tests.ps1 | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 index 19b630dfeea..98963a30628 100644 --- a/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 +++ b/test/powershell/Modules/Microsoft.PowerShell.Management/Set-Service.Tests.ps1 @@ -168,8 +168,9 @@ Describe "Set/New/Remove-Service cmdlet tests" -Tags "Feature", "RequireAdminOnW try { $startUsername = "user1" $endUsername = "user2" - $testPass = New-CertificatePassword $servicename = "testsetcredential" + $Password = ([char[]]([char]33..[char]95) + ([char[]]([char]97..[char]126)) + 0..9 | Sort-Object {Get-Random})[0..12] -join '' + $testPass = (New-Object -TypeName Net.NetworkCredential("", $Password)).SecurePassword $creds = [pscredential]::new(".\$endUsername", $testPass) net user $startUsername $creds.GetNetworkCredential().Password /add > $null net user $endUsername $creds.GetNetworkCredential().Password /add > $null