From 34250e53075672d3f41b54f66aefd1d750ff41a4 Mon Sep 17 00:00:00 2001 From: Raimund Andree Date: Mon, 5 Oct 2026 00:35:19 +0200 Subject: [PATCH] fix: take InheritanceEnabled of audit entries from the SACL Defect 7. FileSystemAuditRule2.GetFileSystemAuditRules set the InheritanceEnabled property of every audit entry from AreAccessRulesProtected, the protection of the DACL. It now uses AreAuditRulesProtected, so the property, and the "Inheritance enabled" header of the audit view, describe the audit entries. Tests/Audit.Tests.ps1: 1 test on an in-memory security descriptor whose SACL is protected and whose DACL is not. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant --- CHANGELOG.md | 3 +++ Docs/Cmdlets/Get-NTFSAudit.md | 2 +- NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml | 2 +- .../FileSystemAuditRule2.GetFileSystemAuditRules.cs | 2 +- Tests/Audit.Tests.ps1 | 12 ++++++++++++ 5 files changed, 18 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index fc2071a..6c153da 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -71,5 +71,8 @@ The format is based on - Fix `-PassThru` of `Add-NTFSAudit` with `-SecurityDescriptor` and of `Remove-NTFSAudit` with `-Path`, which returned access entries; both now return the audit entries +- Fix the `InheritanceEnabled` property of audit entries, which reported the + inheritance of the access entries; it now reports whether the audit + entries are inherited [Unreleased]: https://github.com/raandree/NTFSSecurity/compare/4.2.6...HEAD diff --git a/Docs/Cmdlets/Get-NTFSAudit.md b/Docs/Cmdlets/Get-NTFSAudit.md index b010e7f..2b03198 100644 --- a/Docs/Cmdlets/Get-NTFSAudit.md +++ b/Docs/Cmdlets/Get-NTFSAudit.md @@ -183,7 +183,7 @@ Reading the SACL requires the Security privilege (`SeSecurityPrivilege`, "Manage If the security descriptor cannot be read because access is denied, the cmdlet takes ownership of the item, reads the descriptor again, and restores the previous owner. If the second attempt fails as well, the cmdlet writes an error, and the ownership change is not rolled back. -Before 5.0.0, the cmdlet returned no entries and no error without the Security privilege, and after a path whose security descriptor could not be read, it returned the entries of the previous item again. +Before 5.0.0, the cmdlet returned no entries and no error without the Security privilege, and after a path whose security descriptor could not be read, it returned the entries of the previous item again. The `InheritanceEnabled` property of the entries also reported whether the access entries were inherited instead of the audit entries. ## RELATED LINKS diff --git a/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml b/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml index a420e33..993a3d0 100644 --- a/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml +++ b/NTFSSecurity/en-US/NTFSSecurity.dll-Help.xml @@ -4842,7 +4842,7 @@ PS C:\> Disable-Privileges When the module setting `EnablePrivileges` is `$true` (the default in the `PrivateData` section of NTFSSecurity.psd1), this cmdlet tries to enable the Backup, Restore, Take Ownership, and Security privileges while it runs and disables the privileges it enabled when it finishes. These privileges are only available in an elevated session of an account that holds them, such as a member of the local Administrators group. If a privilege cannot be enabled, the cmdlet continues without it and writes a debug message. Reading the SACL requires the Security privilege (`SeSecurityPrivilege`, "Manage auditing and security log"), so run this cmdlet in an elevated session of an account that holds that privilege. Without it, the cmdlet writes the non-terminating error `ReadSecurityError` for each item, which reports "A required privilege is not held by the client". `Get-NTFSSecurityDescriptor` reads a security descriptor without its SACL when the privilege is missing; for such a descriptor, the cmdlet writes a `ReadSecurityError` as well. If the security descriptor cannot be read because access is denied, the cmdlet takes ownership of the item, reads the descriptor again, and restores the previous owner. If the second attempt fails as well, the cmdlet writes an error, and the ownership change is not rolled back. - Before 5.0.0, the cmdlet returned no entries and no error without the Security privilege, and after a path whose security descriptor could not be read, it returned the entries of the previous item again. + Before 5.0.0, the cmdlet returned no entries and no error without the Security privilege, and after a path whose security descriptor could not be read, it returned the entries of the previous item again. The `InheritanceEnabled` property of the entries also reported whether the access entries were inherited instead of the audit entries. diff --git a/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.GetFileSystemAuditRules.cs b/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.GetFileSystemAuditRules.cs index 9e797b6..9fc525c 100644 --- a/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.GetFileSystemAuditRules.cs +++ b/Security2/FileSystem/FileSystemAuditRule2 Class/FileSystemAuditRule2.GetFileSystemAuditRules.cs @@ -31,7 +31,7 @@ namespace Security2 foreach (FileSystemAuditRule ace in acl) { - var ace2 = new FileSystemAuditRule2(ace) { FullName = sd.Item.FullName, InheritanceEnabled = !sd.SecurityDescriptor.AreAccessRulesProtected }; + var ace2 = new FileSystemAuditRule2(ace) { FullName = sd.Item.FullName, InheritanceEnabled = !sd.SecurityDescriptor.AreAuditRulesProtected }; if (getInheritedFrom) { ace2.inheritedFrom = string.IsNullOrEmpty(inheritedFrom[aceCounter]) ? "" : inheritedFrom[aceCounter].Substring(0, inheritedFrom[aceCounter].Length - 1); diff --git a/Tests/Audit.Tests.ps1 b/Tests/Audit.Tests.ps1 index 3ce0b6f..587ea5b 100644 --- a/Tests/Audit.Tests.ps1 +++ b/Tests/Audit.Tests.ps1 @@ -105,6 +105,18 @@ Describe 'Add-NTFSAudit' { $result | ForEach-Object -Process { $_ | Should -BeOfType [Security2.FileSystemAuditRule2] } @($result | Where-Object -FilterScript { $_.Account.Sid -eq 'S-1-1-0' }) | Should -HaveCount 1 } + + It 'Should report the inheritance of the audit entries in InheritanceEnabled, not that of the access entries' { + $file = New-TestSandboxItem -Sandbox $sandbox -Name 'AuditProtected' + $sd = Get-NTFSSecurityDescriptor -Path $file + $sd.SecurityDescriptor.SetAuditRuleProtection($true, $false) + + $result = @(Add-NTFSAudit -SecurityDescriptor $sd -Account 'Everyone' -AccessRights ReadData -InheritanceFlags None -PropagationFlags None -PassThru) + + $sd.SecurityDescriptor.AreAccessRulesProtected | Should -BeFalse + $result | Should -Not -BeNullOrEmpty + $result | ForEach-Object -Process { $_.InheritanceEnabled | Should -BeFalse } + } } }