From 7d1b4c53024a4089307dc226675a2859dfffaa7a Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Fri, 9 Oct 2026 15:57:43 +0000 Subject: [PATCH] test: reach the owner restore of a descriptor retry and remove a deny entry from a descriptor The restore test of Set-NTFSSecurityDescriptor used a deny entry for the user, which a member of the owner group Administrators does not feel, so the first write succeeded and the ownership retry never ran. A deny entry for OWNER RIGHTS stops that write also for the owner; taking ownership drops the entry, the cmdlet writes the descriptor, and the user sets the group back without the Restore privilege. A probe shows the plain write is denied in that setup in both editions. Remove-NTFSAccess with -SecurityDescriptor and -AccessType Deny had no test, although the overload for a descriptor adds Synchronize to allow entries only. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant --- Tests/Access.Tests.ps1 | 18 ++++++++++++++++++ Tests/SecurityDescriptor.Tests.ps1 | 5 +++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/Tests/Access.Tests.ps1 b/Tests/Access.Tests.ps1 index c351038..8efdedd 100644 --- a/Tests/Access.Tests.ps1 +++ b/Tests/Access.Tests.ps1 @@ -856,6 +856,24 @@ Describe 'Security descriptor parameter sets' { Where-Object -FilterScript { $_.IdentityReference.Value -eq 'S-1-1-0' } $rule.InheritanceFlags | Should -Be ([System.Security.AccessControl.InheritanceFlags]::None) } + + # A deny entry has no Synchronize right to add or remove, unlike an allow entry. + It 'Remove-NTFSAccess should remove a deny entry from the descriptor and leave the item unchanged' { + $item = New-TestSandboxItem -Sandbox $sandbox -Name 'DenyInMemory' + $sd = Get-NTFSSecurityDescriptor -Path $item + Add-NTFSAccess -SecurityDescriptor $sd -Account 'Everyone' -AccessRights ReadData -AccessType Deny + $entries = @($sd.SecurityDescriptor.GetAccessRules($true, $false, [System.Security.Principal.SecurityIdentifier]) | + Where-Object -FilterScript { $_.IdentityReference.Value -eq 'S-1-1-0' }) + $entries | Should -HaveCount 1 + $entries[0].AccessControlType | Should -Be 'Deny' + + Remove-NTFSAccess -SecurityDescriptor $sd -Account 'Everyone' -AccessRights ReadData -AccessType Deny -ErrorAction Stop + + @($sd.SecurityDescriptor.GetAccessRules($true, $false, [System.Security.Principal.SecurityIdentifier]) | + Where-Object -FilterScript { $_.IdentityReference.Value -eq 'S-1-1-0' }) | Should -BeNullOrEmpty + @((Get-Acl -LiteralPath $item).GetAccessRules($true, $false, [System.Security.Principal.SecurityIdentifier]) | + Where-Object -FilterScript { $_.IdentityReference.Value -eq 'S-1-1-0' }) | Should -BeNullOrEmpty + } } Describe 'Clear-NTFSAccess' { diff --git a/Tests/SecurityDescriptor.Tests.ps1 b/Tests/SecurityDescriptor.Tests.ps1 index 76507fe..0595635 100644 --- a/Tests/SecurityDescriptor.Tests.ps1 +++ b/Tests/SecurityDescriptor.Tests.ps1 @@ -265,12 +265,13 @@ Describe 'Set-NTFSSecurityDescriptor' { } # The user can set a group of its access token back as the owner without the Restore privilege, such as the group - # Administrators of an elevated session, so the cmdlet restores the owner and reports nothing. + # Administrators of an elevated session, so the cmdlet restores the owner and reports nothing. A deny entry for + # OWNER RIGHTS stops the first write, also for the owner; taking ownership drops that entry. It 'Should set a previous owner back that the user can assign after the write that took ownership' -Skip:(-not $canAssignAnyOwner) { $administrators = 'S-1-5-32-544' $file = New-TestSandboxItem -Sandbox $sandbox -Name 'RetryRestored' - Add-TestDenyRule -Sandbox $sandbox -Path $file -Rights @{ $currentUser = 'ChangePermissions' } Set-TestOwner -Sandbox $sandbox -Path $file -Sid $administrators + Add-TestDenyRule -Sandbox $sandbox -Path $file -Rights @{ 'S-1-3-4' = 'ChangePermissions' } Get-RestorePrivilegeState | Should -Be 'Disabled' $sd = Get-NTFSSecurityDescriptor -Path $file Add-NTFSAccess -SecurityDescriptor $sd -Account 'Everyone' -AccessRights ReadData