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>
Resolve relative paths with Get-Item2, report copies and moves to a drive that does not exist, warn once about MACTripleDES across pipeline objects, and check the exceptions of PrivilegeControl for held, repeated and missing privileges.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Cover the access and audit rule helpers that take a path, including the lazy iterator overloads and exact versus partial removal, the inheritance helpers for paths, owner and descriptor objects, generic rights mapping, identity construction errors and the PrivilegeEnabler class. These public APIs have no cmdlet caller.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
A cmdlet that enables the Backup, Restore, Take Ownership, and Security
privileges decided which ones to disable on the states that it had read
when it enabled them, and stopped at the first one that failed. When
another command in the pipeline, such as Disable-Privileges, had disabled
one of them, the cmdlet stopped with "Priviledge already disabled" and
left the privileges after that one enabled. After an early stop, which
Dispose handles since this branch, it left them enabled without any
message, because PowerShell ignores exceptions thrown in Dispose; and
Disable-Privileges threw that exception in Dispose on every call while
the privileges were disabled. 4.2.6 already decided on the old states.
DisablePrivilege now reads the current state, and the cleanup tries every
privilege: in EndProcessing, a privilege that it can't disable gives a
warning; in Dispose, it is ignored.
The early-stop tests now pin EnablePrivileges and check that the cmdlet
had enabled the privileges, so that they can't pass without testing
anything.
Found by the security review of fcb370e..00c3646 (findings 1 to 3).
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
The cmdlets that enable the Backup, Restore, Take Ownership, and Security
privileges disabled them only in EndProcessing, which PowerShell skips
when a later command, such as Select-Object -First, or a terminating
error stops the pipeline. The privileges then stayed enabled in the
session. BaseCmdletWithPrivControl now implements IDisposable and
disables them in Dispose as well; Enable-Privileges keeps them.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
- #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>
Copy-Item2 and Move-Item2 named the source path as the destination,
Disable-Privileges said that the privileges were now enabled, and the
warning of Get-NTFSEffectiveAccess misspelled the privilege.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
Defect 12. Besides the base class, which enables the privileges only when
the module setting EnablePrivileges is $true and disables them again in
EndProcessing, the six inheritance cmdlets called
EnableFileSystemPrivileges in BeginProcessing unconditionally. With
EnablePrivileges = $false they enabled the privileges anyway and, because
EndProcessing disables them only when the setting is $true, left them
enabled. The extra calls are gone; the inheritance cmdlets now behave like
the other cmdlets.
Tests/Privileges.Tests.ps1: 6 tests, one per cmdlet, CI-only, because
they need a token that holds the privileges. Without the fix the Backup
privilege is enabled after each call.
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Co-authored-by: AI Assistant <ai@example.com>
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>