Browse Source

test: write the deny entries of the test helper without Set-Acl

Set-Acl compares AreAuditRulesProtected of the new descriptor with
AreAccessRulesProtected of the item (FileSystemSecurity.cs in PowerShell),
so it also writes the audit section of an item whose DACL is protected.
Without the Security privilege that fails with PrivilegeNotHeldException:
after Disable-NTFSAccessInheritance, Add-TestDenyRule added nothing, and
the take-ownership test of PathErrors.Tests.ps1 failed as a basic user.
With the privilege, Set-Acl wrote all sections and dropped the audit
entries of the item.

Add-TestDenyRule now writes only the DACL with SetAccessControl. Two
regression tests cover both effects; each failed before the change in its
configuration.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
ai/release-5.0.0-rc6
Raimund Andree 4 days ago
parent
commit
8f5da8b33d
  1. 37
      Tests/TestHelpers.Tests.ps1
  2. 11
      Tests/TestHelpers.psm1

37
Tests/TestHelpers.Tests.ps1

@ -11,6 +11,8 @@ BeforeDiscovery {
Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath 'TestHelpers.psm1') -Force
# Assigning an owner other than the user or one of its groups needs the Restore privilege.
$canAssignAnyOwner = Test-PrivilegeHeld -Name 'SeRestorePrivilege'
# Reading and writing audit entries needs the Security privilege.
$holdsSecurityPrivilege = Test-PrivilegeHeld -Name 'SeSecurityPrivilege'
}
BeforeAll {
@ -212,6 +214,41 @@ Describe 'Test helpers' {
$rules[0].AccessControlType | Should -Be 'Deny'
}
# Set-Acl also writes the audit section of an item whose DACL is protected, which fails without the Security
# privilege.
It 'Should add a deny entry to an item whose DACL is protected' {
$file = New-TestSandboxItem -Sandbox $sandbox -Name 'Protected'
& icacls.exe $file /inheritance:d *> $null
$LASTEXITCODE | Should -Be 0
Add-TestDenyRule -Sandbox $sandbox -Path $file -Rights @{ 'S-1-5-32-546' = 'ReadData' }
$acl = Get-Acl -LiteralPath $file
$acl.AreAccessRulesProtected | Should -BeTrue
$rules = @($acl.GetAccessRules($true, $false, [System.Security.Principal.SecurityIdentifier]) |
Where-Object -FilterScript { $_.IdentityReference.Value -eq 'S-1-5-32-546' })
$rules | Should -HaveCount 1
$rules[0].AccessControlType | Should -Be 'Deny'
}
# With the Security privilege, Set-Acl writes all sections, so the audit entries of the item would be lost.
It 'Should keep the audit entries of the item' -Skip:(-not $holdsSecurityPrivilege) {
$file = New-TestSandboxItem -Sandbox $sandbox -Name 'Audited'
$auditAcl = Get-Acl -LiteralPath $file -Audit
$auditAcl.AddAuditRule((New-Object -TypeName 'System.Security.AccessControl.FileSystemAuditRule' -ArgumentList (
(New-Object -TypeName 'System.Security.Principal.SecurityIdentifier' -ArgumentList 'S-1-1-0'),
[System.Security.AccessControl.FileSystemRights]::Delete,
[System.Security.AccessControl.AuditFlags]::Success
)))
Set-Acl -LiteralPath $file -AclObject $auditAcl
Add-TestDenyRule -Sandbox $sandbox -Path $file -Rights @{ 'S-1-5-32-546' = 'ReadData' }
$auditRules = @((Get-Acl -LiteralPath $file -Audit).GetAuditRules($true, $false, [System.Security.Principal.SecurityIdentifier]))
$auditRules | Should -HaveCount 1
$auditRules[0].IdentityReference.Value | Should -Be 'S-1-1-0'
}
It 'Should refuse an item outside the sandbox' {
{ Add-TestDenyRule -Sandbox $sandbox -Path "$sandbox-Other\File.txt" -Rights @{ 'S-1-5-32-546' = 'ReadData' } } |
Should -Throw -ExpectedMessage 'Refusing to change*'

11
Tests/TestHelpers.psm1

@ -277,6 +277,7 @@ function Add-TestDenyRule {
)
Assert-TestSandboxPath -Sandbox $Sandbox -Path $Path
$item = Get-Item -LiteralPath $Path -Force -ErrorAction Stop
$acl = Get-Acl -LiteralPath $Path
foreach ($sid in $Rights.Keys) {
$identity = New-Object -TypeName 'System.Security.Principal.SecurityIdentifier' -ArgumentList $sid
@ -286,7 +287,15 @@ function Add-TestDenyRule {
)
$acl.AddAccessRule($rule)
}
Set-Acl -LiteralPath $Path -AclObject $acl
# Not Set-Acl: it compares AreAuditRulesProtected with AreAccessRulesProtected, so it also writes the audit
# section of an item whose DACL is protected, which fails without the Security privilege. With the privilege, it
# writes all sections and drops the audit entries. SetAccessControl writes only the DACL, the section that changed.
if ($PSVersionTable.PSEdition -eq 'Core') {
[System.IO.FileSystemAclExtensions]::SetAccessControl($item, $acl)
}
else {
$item.SetAccessControl($acl)
}
}
function Set-TestOwner {

Loading…
Cancel
Save