fix: drive roots, audit descriptors, -WhatIf conflicts, and small items
- #41: for the root of a drive, the cmdlets read and changed the security
descriptor of the drive, a device object. FileSystemSecurity2 now routes
drive roots through the path-based AlphaFS methods, which keep the
trailing backslash; the removal and inheritance helpers use it too.
- #109: Add-, Remove-, and Clear-NTFSAudit report a security descriptor
without the audit entries like Get-NTFSAudit, through one helper, and
Get-NTFSEffectiveAccess names the cause that Windows reported instead
of a missing Security privilege.
- #108: Copy-Item2 and Move-Item2 check the destination only for an
operation that runs; with -WhatIf, a verbose message names the conflict.
- #111: Disable-Privileges skips the privileges that the token doesn't
hold, the privilege messages are spelled right, and Get-FileHash2
declares the type name of its objects; 05-Releasing.md documents the
release metadata tests.
- rc3 review leftovers: Remove-NTFSAudit writes nothing for an item
without a SACL, the owner retry of Set-NTFSSecurityDescriptor restores
the previous owner in a finally block and keeps an owner that the
descriptor sets, and FileSystemSecurity2.Write with another item writes
only the sections that were read.
Each fix has a test that failed first, in Windows PowerShell 5.1 and
PowerShell 7; writing a drive root was checked once on a temporary VHD.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
|
|
|
<#
|
test: cover token handles, drive-root writes, name filters, and descriptor APIs
New guards cover the default AllAccess token handle, token handles that lack the right to query or to adjust privileges, and the finalizer of an abandoned PrivilegeEnabler, which closes the handle that it owns; writes to the root of a drive that subst maps to a sandbox folder, which skip for the restricted token of the basic-user runner that cannot define a drive letter; Get-ChildItem2 -Filter against a match by short name; retargeting a descriptor with Item; the path overloads of the inheritance helpers for a missing path and of the audit rule reader for folders; removing a generic right while another account holds an exact entry; and an empty -ServerName.
Follow-ups of the independent review: dispose the enabler in the finally block before its handle, don't pin that the iterator overloads write only when enumerated, arrange the previous owner of the RestoreOwnerError test, and describe what ObjectApis.Tests.ps1 does.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
|
|
|
Tests the cmdlets of the module built in NTFSSecurity\bin\Release on the root folder of the system drive, which they
|
|
|
|
|
only read, and on the root of a drive that maps a folder of a sandbox, which they change.
|
fix: drive roots, audit descriptors, -WhatIf conflicts, and small items
- #41: for the root of a drive, the cmdlets read and changed the security
descriptor of the drive, a device object. FileSystemSecurity2 now routes
drive roots through the path-based AlphaFS methods, which keep the
trailing backslash; the removal and inheritance helpers use it too.
- #109: Add-, Remove-, and Clear-NTFSAudit report a security descriptor
without the audit entries like Get-NTFSAudit, through one helper, and
Get-NTFSEffectiveAccess names the cause that Windows reported instead
of a missing Security privilege.
- #108: Copy-Item2 and Move-Item2 check the destination only for an
operation that runs; with -WhatIf, a verbose message names the conflict.
- #111: Disable-Privileges skips the privileges that the token doesn't
hold, the privilege messages are spelled right, and Get-FileHash2
declares the type name of its objects; 05-Releasing.md documents the
release metadata tests.
- rc3 review leftovers: Remove-NTFSAudit writes nothing for an item
without a SACL, the owner retry of Set-NTFSSecurityDescriptor restores
the previous owner in a finally block and keeps an owner that the
descriptor sets, and FileSystemSecurity2.Write with another item writes
only the sections that were read.
Each fix has a test that failed first, in Windows PowerShell 5.1 and
PowerShell 7; writing a drive root was checked once on a temporary VHD.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
|
|
|
#>
|
|
|
|
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
|
|
|
|
|
'PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Pester shares variables between blocks.'
|
|
|
|
|
)]
|
|
|
|
|
param ()
|
|
|
|
|
|
test: cover token handles, drive-root writes, name filters, and descriptor APIs
New guards cover the default AllAccess token handle, token handles that lack the right to query or to adjust privileges, and the finalizer of an abandoned PrivilegeEnabler, which closes the handle that it owns; writes to the root of a drive that subst maps to a sandbox folder, which skip for the restricted token of the basic-user runner that cannot define a drive letter; Get-ChildItem2 -Filter against a match by short name; retargeting a descriptor with Item; the path overloads of the inheritance helpers for a missing path and of the audit rule reader for folders; removing a generic right while another account holds an exact entry; and an empty -ServerName.
Follow-ups of the independent review: dispose the enabler in the finally block before its handle, don't pin that the iterator overloads write only when enumerated, arrange the previous owner of the RestoreOwnerError test, and describe what ObjectApis.Tests.ps1 does.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
|
|
|
BeforeDiscovery {
|
|
|
|
|
Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath 'TestHelpers.psm1') -Force
|
|
|
|
|
# The restricted token of the basic-user runner cannot define a drive letter.
|
|
|
|
|
$canMapDrive = Test-DriveMappingAvailable
|
|
|
|
|
}
|
|
|
|
|
|
fix: drive roots, audit descriptors, -WhatIf conflicts, and small items
- #41: for the root of a drive, the cmdlets read and changed the security
descriptor of the drive, a device object. FileSystemSecurity2 now routes
drive roots through the path-based AlphaFS methods, which keep the
trailing backslash; the removal and inheritance helpers use it too.
- #109: Add-, Remove-, and Clear-NTFSAudit report a security descriptor
without the audit entries like Get-NTFSAudit, through one helper, and
Get-NTFSEffectiveAccess names the cause that Windows reported instead
of a missing Security privilege.
- #108: Copy-Item2 and Move-Item2 check the destination only for an
operation that runs; with -WhatIf, a verbose message names the conflict.
- #111: Disable-Privileges skips the privileges that the token doesn't
hold, the privilege messages are spelled right, and Get-FileHash2
declares the type name of its objects; 05-Releasing.md documents the
release metadata tests.
- rc3 review leftovers: Remove-NTFSAudit writes nothing for an item
without a SACL, the owner retry of Set-NTFSSecurityDescriptor restores
the previous owner in a finally block and keeps an owner that the
descriptor sets, and FileSystemSecurity2.Write with another item writes
only the sections that were read.
Each fix has a test that failed first, in Windows PowerShell 5.1 and
PowerShell 7; writing a drive root was checked once on a temporary VHD.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
|
|
|
BeforeAll {
|
|
|
|
|
$modulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\NTFSSecurity\bin\Release\NTFSSecurity.psd1'
|
|
|
|
|
Import-Module -Name $modulePath -Force -ErrorAction Stop
|
|
|
|
|
$root = [IO.Path]::GetPathRoot($env:SystemRoot)
|
|
|
|
|
$sidType = [System.Security.Principal.SecurityIdentifier]
|
|
|
|
|
$acl = Get-Acl -LiteralPath $root
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AfterAll {
|
|
|
|
|
Remove-Module -Name NTFSSecurity -Force -ErrorAction SilentlyContinue
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Before 5.0.0-rc4, the cmdlets read the security descriptor of the drive, a device object, instead of that of its root
|
|
|
|
|
# folder, so they showed other entries than Explorer, icacls, and Get-Acl (#41).
|
|
|
|
|
Describe 'The root folder of a drive' {
|
|
|
|
|
It 'Get-NTFSAccess should return the access entries of the root folder' {
|
|
|
|
|
$expected = @($acl.GetAccessRules($true, $true, $sidType) | ForEach-Object -Process { $_.IdentityReference.Value } | Sort-Object)
|
|
|
|
|
|
|
|
|
|
$entries = @(Get-NTFSAccess -Path $root)
|
|
|
|
|
|
|
|
|
|
@($entries | ForEach-Object -Process { $_.Account.Sid } | Sort-Object) | Should -Be $expected
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
It 'Get-NTFSSecurityDescriptor should read the DACL of the root folder' {
|
|
|
|
|
$sd = Get-NTFSSecurityDescriptor -Path $root
|
|
|
|
|
|
|
|
|
|
$sd.SecurityDescriptor.GetSecurityDescriptorSddlForm('Access') | Should -Be $acl.GetSecurityDescriptorSddlForm('Access')
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
It 'Get-NTFSOwner should return the owner of the root folder' {
|
|
|
|
|
(Get-NTFSOwner -Path $root).Owner.Sid | Should -Be $acl.GetOwner($sidType).Value
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
It 'Get-NTFSAccess should return the access entries of the root folder for the volume name, such as \\?\Volume{GUID}\' {
|
|
|
|
|
# Win32_Volume returns nothing to a user without elevation; mountvol works for every user.
|
|
|
|
|
$volume = (mountvol.exe $root /L | Out-String).Trim()
|
|
|
|
|
$volume | Should -BeLike '\\?\Volume{*}\'
|
|
|
|
|
$expected = @($acl.GetAccessRules($true, $true, $sidType) | ForEach-Object -Process { $_.IdentityReference.Value } | Sort-Object)
|
|
|
|
|
|
|
|
|
|
$entries = @(Get-NTFSAccess -Path $volume)
|
|
|
|
|
|
|
|
|
|
@($entries | ForEach-Object -Process { $_.Account.Sid } | Sort-Object) | Should -Be $expected
|
|
|
|
|
}
|
fix: drive roots, audit descriptors, -WhatIf conflicts, and small items
- #41: for the root of a drive, the cmdlets read and changed the security
descriptor of the drive, a device object. FileSystemSecurity2 now routes
drive roots through the path-based AlphaFS methods, which keep the
trailing backslash; the removal and inheritance helpers use it too.
- #109: Add-, Remove-, and Clear-NTFSAudit report a security descriptor
without the audit entries like Get-NTFSAudit, through one helper, and
Get-NTFSEffectiveAccess names the cause that Windows reported instead
of a missing Security privilege.
- #108: Copy-Item2 and Move-Item2 check the destination only for an
operation that runs; with -WhatIf, a verbose message names the conflict.
- #111: Disable-Privileges skips the privileges that the token doesn't
hold, the privilege messages are spelled right, and Get-FileHash2
declares the type name of its objects; 05-Releasing.md documents the
release metadata tests.
- rc3 review leftovers: Remove-NTFSAudit writes nothing for an item
without a SACL, the owner retry of Set-NTFSSecurityDescriptor restores
the previous owner in a finally block and keeps an owner that the
descriptor sets, and FileSystemSecurity2.Write with another item writes
only the sections that were read.
Each fix has a test that failed first, in Windows PowerShell 5.1 and
PowerShell 7; writing a drive root was checked once on a temporary VHD.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
|
|
|
}
|
test: cover token handles, drive-root writes, name filters, and descriptor APIs
New guards cover the default AllAccess token handle, token handles that lack the right to query or to adjust privileges, and the finalizer of an abandoned PrivilegeEnabler, which closes the handle that it owns; writes to the root of a drive that subst maps to a sandbox folder, which skip for the restricted token of the basic-user runner that cannot define a drive letter; Get-ChildItem2 -Filter against a match by short name; retargeting a descriptor with Item; the path overloads of the inheritance helpers for a missing path and of the audit rule reader for folders; removing a generic right while another account holds an exact entry; and an empty -ServerName.
Follow-ups of the independent review: dispose the enabler in the finally block before its handle, don't pin that the iterator overloads write only when enumerated, arrange the previous owner of the RestoreOwnerError test, and describe what ObjectApis.Tests.ps1 does.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
3 weeks ago
|
|
|
|
|
|
|
|
# A test must not change the permissions of a volume. A drive letter that subst maps to a folder of a sandbox is the root
|
|
|
|
|
# of a drive for Windows and for the module, so the code that changes the root folder of a drive changes that folder.
|
|
|
|
|
Describe 'Changing the root folder of a drive' -Skip:(-not $canMapDrive) {
|
|
|
|
|
BeforeAll {
|
|
|
|
|
Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath 'TestHelpers.psm1') -Force
|
|
|
|
|
$sandbox = New-TestSandbox -Name 'DriveRootChange'
|
|
|
|
|
$mapped = New-TestSandboxItem -Sandbox $sandbox -Name 'Mapped' -Directory
|
|
|
|
|
$driveRoot = New-TestDriveMapping -Sandbox $sandbox -Path $mapped
|
|
|
|
|
if (-not $driveRoot) {
|
|
|
|
|
throw 'No drive letter could be mapped to the sandbox folder.'
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
function Get-MappedEntry {
|
|
|
|
|
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
|
|
|
|
|
'PSUseSingularNouns', '', Justification = 'The helper returns the explicit entries of the folder.'
|
|
|
|
|
)]
|
|
|
|
|
param ([string] $Account)
|
|
|
|
|
|
|
|
|
|
@((Get-Acl -LiteralPath $mapped).GetAccessRules($true, $false, $sidType) |
|
|
|
|
|
Where-Object -FilterScript { $_.IdentityReference.Value -eq $Account })
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
AfterAll {
|
|
|
|
|
if ($driveRoot) {
|
|
|
|
|
Remove-TestDriveMapping -Root $driveRoot
|
|
|
|
|
}
|
|
|
|
|
Remove-TestSandbox -Sandbox $sandbox
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
It 'Should read the access entries of the folder that the drive maps' {
|
|
|
|
|
$expected = @((Get-Acl -LiteralPath $mapped).GetAccessRules($true, $true, $sidType) |
|
|
|
|
|
ForEach-Object -Process { $_.IdentityReference.Value } | Sort-Object)
|
|
|
|
|
|
|
|
|
|
$entries = @(Get-NTFSAccess -Path $driveRoot)
|
|
|
|
|
|
|
|
|
|
@($entries | ForEach-Object -Process { $_.Account.Sid } | Sort-Object) | Should -Be $expected
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
It 'Should add and remove an access entry of the folder that the drive maps' {
|
|
|
|
|
Add-NTFSAccess -Path $driveRoot -Account 'S-1-1-0' -AccessRights ReadData -ErrorAction Stop
|
|
|
|
|
|
|
|
|
|
Get-MappedEntry -Account 'S-1-1-0' | Should -HaveCount 1
|
|
|
|
|
|
|
|
|
|
Remove-NTFSAccess -Path $driveRoot -Account 'S-1-1-0' -AccessRights ReadData -ErrorAction Stop
|
|
|
|
|
|
|
|
|
|
Get-MappedEntry -Account 'S-1-1-0' | Should -BeNullOrEmpty
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
It 'Should block and restore the access inheritance of the folder that the drive maps' {
|
|
|
|
|
Disable-NTFSAccessInheritance -Path $driveRoot -ErrorAction Stop
|
|
|
|
|
|
|
|
|
|
(Get-Acl -LiteralPath $mapped).AreAccessRulesProtected | Should -BeTrue
|
|
|
|
|
|
|
|
|
|
Enable-NTFSAccessInheritance -Path $driveRoot -ErrorAction Stop
|
|
|
|
|
|
|
|
|
|
(Get-Acl -LiteralPath $mapped).AreAccessRulesProtected | Should -BeFalse
|
|
|
|
|
}
|
|
|
|
|
}
|