You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

124 lines
5.3 KiB

10 years ago
using Alphaleonis.Win32.Filesystem;
using System.Collections.Generic;
using System.Security.AccessControl;
namespace Security2
{
public partial class FileSystemAuditRule2
{
public static FileSystemAuditRule2 AddFileSystemAuditRule(FileSystemSecurity2 sd, IdentityReference2 account, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags)
{
FileSystemAuditRule2 ace = null;
if (sd.IsFile)
{
ace = (FileSystemAuditRule)sd.SecurityDescriptor.AuditRuleFactory(account, (int)rights, false, InheritanceFlags.None, PropagationFlags.None, type);
((FileSecurity)sd.SecurityDescriptor).AddAuditRule(ace);
}
else
{
ace = (FileSystemAuditRule)sd.SecurityDescriptor.AuditRuleFactory(account, (int)rights, false, inheritanceFlags, propagationFlags, type);
((DirectorySecurity)sd.SecurityDescriptor).AddAuditRule(ace);
}
return ace;
}
public static FileSystemAuditRule2 AddFileSystemAuditRule(FileSystemInfo item, IdentityReference2 account, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags)
{
fix: write only the sections of the security descriptor that a cmdlet changes The access and audit cmdlets wrote the owner of an item back with the entries they changed. For a DACL without the auto-inherit flag, Windows returns the owner and the group even when only the DACL is read, and the cmdlets wrote every section that the descriptor held. Without the Restore privilege, or on a file server that refuses the owner, the write failed with error 1307 (#34). - Add-NTFSAccess, Clear-NTFSAccess, Add-NTFSAudit, and Clear-NTFSAudit read only the DACL or the SACL. FileSystemSecurity2.Write(), Remove-NTFSAccess, and Remove-NTFSAudit write only the sections they read, which also fixes the access inheritance cmdlets. - Read together with the SACL, the inherited entries of such a DACL lose their inherited flag when the parent folder has no SACL, and the cmdlets stored them as explicit copies. Get-NTFSSecurityDescriptor now reads the DACL in a separate call. - Set-NTFSSecurityDescriptor writes only the sections that changed since they were read; an unchanged descriptor writes nothing (maintainer decision of 2026-10-06). - Clear-NTFSAudit writes nothing for an item without a SACL, and reports an error without the Security privilege (maintainer decision). The regression tests failed before and pass after the fix in Windows PowerShell 5.1 and PowerShell 7, elevated and as a basic user. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> Co-authored-by: AI Assistant <ai@example.com>
4 weeks ago
// Only the SACL, so that neither the owner (#34) nor the DACL is written back
var sd = new FileSystemSecurity2(item, AccessControlSections.Audit);
10 years ago
var ace = AddFileSystemAuditRule(sd, account, rights, type, inheritanceFlags, propagationFlags);
sd.Write();
return ace;
}
public static FileSystemAuditRule2 AddFileSystemAuditRule(string path, IdentityReference2 account, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags)
{
FileSystemAuditRule ace = null;
if (File.Exists(path))
{
var item = new FileInfo(path);
ace = AddFileSystemAuditRule(item, account, rights, type, inheritanceFlags, propagationFlags);
}
else
{
var item = new DirectoryInfo(path);
ace = AddFileSystemAuditRule(item, account, rights, type, inheritanceFlags, propagationFlags);
}
return ace;
}
public static IEnumerable<FileSystemAuditRule2> AddFileSystemAuditRule(FileSystemSecurity2 sd, List<IdentityReference2> accounts, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags)
{
var aces = new List<FileSystemAuditRule2>();
foreach (var account in accounts)
{
aces.Add(AddFileSystemAuditRule(sd, account, rights, type, inheritanceFlags, propagationFlags));
}
return aces;
}
public static IEnumerable<FileSystemAuditRule2> AddFileSystemAuditRule(FileSystemInfo item, List<IdentityReference2> accounts, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags)
{
var aces = new List<FileSystemAuditRule2>();
foreach (var account in accounts)
{
aces.Add(AddFileSystemAuditRule(item, account, rights, type, inheritanceFlags, propagationFlags));
}
return aces;
}
/// <summary>
/// Adds one audit entry per account to the item at the path, and returns them in the order of
/// <paramref name="accounts"/>. Before 5.0.0, this overload was an iterator (a yield return in the loop
/// below), so nothing happened until the caller enumerated the result; called as a statement, or assigned to
/// a variable that is never read, it changed nothing. It now builds the list and writes the entries before
/// returning, like its FileSystemInfo and FileSystemSecurity2 siblings; an exception that adding an entry
/// raises is now thrown by this call, not by the later enumeration.
/// </summary>
10 years ago
public static IEnumerable<FileSystemAuditRule2> AddFileSystemAuditRule(string path, List<IdentityReference2> accounts, FileSystemRights2 rights, AuditFlags type, InheritanceFlags inheritanceFlags, PropagationFlags propagationFlags)
{
var aces = new List<FileSystemAuditRule2>();
10 years ago
if (File.Exists(path))
{
var item = new FileInfo(path);
foreach (var account in accounts)
{
aces.Add(AddFileSystemAuditRule(item, account, rights, type, inheritanceFlags, propagationFlags));
10 years ago
}
}
else
{
var item = new DirectoryInfo(path);
foreach (var account in accounts)
{
aces.Add(AddFileSystemAuditRule(item, account, rights, type, inheritanceFlags, propagationFlags));
10 years ago
}
}
return aces;
10 years ago
}
public static void AddFileSystemAuditRule(FileSystemAuditRule2 rule)
{
AddFileSystemAuditRule(rule.fullName,
rule.Account,
rule.AccessRights,
rule.AuditFlags,
rule.InheritanceFlags,
rule.PropagationFlags);
}
}
}