Browse Source

fix: let Disable-Privileges work when EnablePrivileges is $false

Defect 11. DisableFileSystemPrivileges read the privileges of the token
into a local variable that hid the field, and DisablePrivilege read the
field. With the module setting EnablePrivileges = $false, BeginProcessing
never filled the field, so every DisablePrivilege call hit a null
reference, which TryDisablePrivilege turned into a warning, and the
privileges stayed enabled. The method now refreshes the field.

Tests/Privileges.Tests.ps1 (new): 1 test, CI-only, because it needs a
token that holds the privileges. Without the fix it fails on the warnings
and on the Backup privilege that stays enabled.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
pull/100/head
Raimund Andree 1 week ago
parent
commit
804cfd292e
  1. 2
      CHANGELOG.md
  2. 2
      Docs/Cmdlets/Disable-Privileges.md
  3. 3
      NTFSSecurity/BaseCmdlets.cs
  4. 1
      NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml
  5. 63
      Tests/Privileges.Tests.ps1

2
CHANGELOG.md

@ -83,5 +83,7 @@ The format is based on
denied access
- Fix `Copy-Item2`, which failed with a `DirectoryNotFoundException` when it
copied a folder that contained files
- Fix `Disable-Privileges`, which couldn't disable the privileges when the
module setting `EnablePrivileges` was `$false`
[Unreleased]: https://github.com/raandree/NTFSSecurity/compare/4.2.6...HEAD

2
Docs/Cmdlets/Disable-Privileges.md

@ -99,6 +99,8 @@ With `-PassThru`, the cmdlet writes the privilege collection of the current proc
When the module setting `EnablePrivileges` is `$true` (the default in the `PrivateData` section of NTFSSecurity.psd1), the file system cmdlets of the module try to enable the Backup, Restore, Take Ownership, and Security privileges while they run and disable the privileges they enabled when they finish. You therefore need `Disable-Privileges` only after an explicit `Enable-Privileges`. These privileges are only available in an elevated session of an account that holds them, such as a member of the local Administrators group.
Before 5.0.0, when `EnablePrivileges` was `$false`, the cmdlet wrote warnings that it could not disable the privileges and left them enabled.
## RELATED LINKS
[Enable-Privileges](Enable-Privileges.md)

3
NTFSSecurity/BaseCmdlets.cs

@ -278,7 +278,8 @@ namespace NTFSSecurity
protected void DisableFileSystemPrivileges()
{
var privileges = privControl.GetPrivileges();
// Refreshes the field that DisablePrivilege reads; it is null when BeginProcessing enabled nothing.
privileges = privControl.GetPrivileges();
if (privileges.Where(p => p.Privilege == Privilege.TakeOwnership) != null)
if (!TryDisablePrivilege(Privilege.TakeOwnership))

1
NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml

@ -2788,6 +2788,7 @@ PS C:\&gt; Set-NTFSSecurityDescriptor -SecurityDescriptor $sd</dev:code>
<maml:alertSet>
<maml:alert>
<maml:para>When the module setting `EnablePrivileges` is `$true` (the default in the `PrivateData` section of NTFSSecurity.psd1), the file system cmdlets of the module try to enable the Backup, Restore, Take Ownership, and Security privileges while they run and disable the privileges they enabled when they finish. You therefore need `Disable-Privileges` only after an explicit `Enable-Privileges`. These privileges are only available in an elevated session of an account that holds them, such as a member of the local Administrators group.</maml:para>
<maml:para>Before 5.0.0, when `EnablePrivileges` was `$false`, the cmdlet wrote warnings that it could not disable the privileges and left them enabled.</maml:para>
</maml:alert>
</maml:alertSet>
<command:examples>

63
Tests/Privileges.Tests.ps1

@ -0,0 +1,63 @@
<#
Tests how the cmdlets of the module built in NTFSSecurity\bin\Release handle the Backup, Restore, Take Ownership,
and Security privileges. These tests need an access token that holds the privileges, so they skip without them
and run in CI, whose runners are elevated. They change only the privileges of the test process and restore the
module setting EnablePrivileges.
#>
[Diagnostics.CodeAnalysis.SuppressMessageAttribute(
'PSUseDeclaredVarsMoreThanAssignments', '', Justification = 'Pester shares variables between blocks.'
)]
param ()
BeforeDiscovery {
Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath 'TestHelpers.psm1') -Force
$missingPrivileges = @('SeBackupPrivilege', 'SeRestorePrivilege', 'SeTakeOwnershipPrivilege', 'SeSecurityPrivilege') |
Where-Object -FilterScript { -not (Test-PrivilegeHeld -Name $_) }
$holdsPrivileges = -not $missingPrivileges
}
BeforeAll {
Import-Module -Name (Join-Path -Path $PSScriptRoot -ChildPath 'TestHelpers.psm1') -Force
$modulePath = Join-Path -Path $PSScriptRoot -ChildPath '..\NTFSSecurity\bin\Release\NTFSSecurity.psd1'
Import-Module -Name $modulePath -Force -ErrorAction Stop
$sandbox = New-TestSandbox -Name 'Privileges'
Push-Location -LiteralPath $sandbox
$privateData = (Get-Module -Name NTFSSecurity).PrivateData
$enablePrivileges = $privateData['EnablePrivileges']
function Get-BackupPrivilegeState {
(Get-Privileges | Where-Object -Property Privilege -EQ -Value 'Backup').PrivilegeState
}
}
AfterAll {
$privateData['EnablePrivileges'] = $enablePrivileges
Disable-Privileges -ErrorAction SilentlyContinue -WarningAction SilentlyContinue
Pop-Location
Remove-TestSandbox -Sandbox $sandbox
Remove-Module -Name NTFSSecurity -Force -ErrorAction SilentlyContinue
}
Describe 'Disable-Privileges' {
Context 'When the module setting EnablePrivileges is $false' {
BeforeAll {
$privateData['EnablePrivileges'] = $false
}
AfterAll {
$privateData['EnablePrivileges'] = $enablePrivileges
}
# Before 5.0.0, the cmdlet warned that it could not disable the privileges and left them enabled.
It 'Should disable the privileges that Enable-Privileges enabled' -Skip:(-not $holdsPrivileges) {
Enable-Privileges
Get-BackupPrivilegeState | Should -Be 'Enabled'
Disable-Privileges -WarningVariable privilegeWarnings -WarningAction SilentlyContinue
$privilegeWarnings | Should -BeNullOrEmpty
Get-BackupPrivilegeState | Should -Be 'Disabled'
}
}
}
Loading…
Cancel
Save