Set-Acl: Do not fail on untranslatable SID (#21096)

This commit is contained in:
Jordan Borean
2024-07-15 18:33:41 -07:00
committed by GitHub
parent 2e93c18769
commit c107c9c66b
2 changed files with 31 additions and 4 deletions
@@ -168,13 +168,15 @@ namespace Microsoft.PowerShell.Commands
{
// Get the security descriptor of the destination path
ObjectSecurity existingDescriptor = new FileInfo(path).GetAccessControl();
Type ntAccountType = typeof(System.Security.Principal.NTAccount);
// Use SecurityIdentifier to avoid having the below comparison steps
// fail when dealing with an untranslatable SID in the SD
Type identityType = typeof(System.Security.Principal.SecurityIdentifier);
AccessControlSections sections = AccessControlSections.All;
// If they didn't modify any audit information, don't try to set
// the audit section.
int auditRuleCount = sd.GetAuditRules(true, true, ntAccountType).Count;
int auditRuleCount = sd.GetAuditRules(true, true, identityType).Count;
if ((auditRuleCount == 0) &&
(sd.AreAuditRulesProtected == existingDescriptor.AreAccessRulesProtected))
{
@@ -182,13 +184,13 @@ namespace Microsoft.PowerShell.Commands
}
// If they didn't modify the owner, don't try to set that section.
if (sd.GetOwner(ntAccountType) == existingDescriptor.GetOwner(ntAccountType))
if (sd.GetOwner(identityType) == existingDescriptor.GetOwner(identityType))
{
sections &= ~AccessControlSections.Owner;
}
// If they didn't modify the group, don't try to set that section.
if (sd.GetGroup(ntAccountType) == existingDescriptor.GetGroup(ntAccountType))
if (sd.GetGroup(identityType) == existingDescriptor.GetGroup(identityType))
{
sections &= ~AccessControlSections.Group;
}
@@ -77,6 +77,31 @@ Describe "Acl cmdlets are available and operate properly" -Tag CI {
$newrule | Should -Not -BeNullOrEmpty
}
It "Can edit SD that contains an orphaned SID" {
$badSid = [System.Security.Principal.SecurityIdentifier]::new("S-1-5-1234-5678")
$currentUserSid = [System.Security.Principal.WindowsIdentity]::GetCurrent().User
$testFilePath = "TestDrive:\pwsh-acl-test.txt"
$testFile = New-Item -Path $testFilePath -ItemType File -Value 'foo' -Force
# We should be able to set an SD entry to an untranslatable SID
$fileSecurity = $testFilePath | Get-Acl
$fileSecurity.SetGroup($badSid)
Set-Acl -Path $testFile -AclObject $fileSecurity
# We should be able to get the SD with an untranslatable SID
$setSD = Get-Acl -Path $testFile
$setSD.GetGroup([System.Security.Principal.SecurityIdentifier]) | Should -Be $badSid
# We should be able to set it back to a known SID
$setSD.SetGroup($currentUserSid)
Set-Acl -Path $testFile -AclObject $setSD
$actual = Get-Acl -Path $testFile
$actualGroup = $actual.GetGroup([System.Security.Principal.SecurityIdentifier])
$actualGroup | Should -Be $currentUserSid
}
AfterAll {
$PSDefaultParameterValues.Remove("It:Skip")
}