commit 9171097d6790628cc2226456729026657ed91b60
parent bdb5faac4f1a5cb32baed8103c33ad55ecc8c151
Author: JohnMcPMS <johnmcp@microsoft.com>
Date: Wed, 12 Mar 2025 16:50:31 -0700
Handle access denied error when setting owner if already owner (#5282)
If we get `ERROR_ACCESS_DENIED` when attempting to set the owner, check
if the owner is already correct. If it is, attempt to set just the DACL.
Diffstat:
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/src/AppInstallerSharedLib/Filesystem.cpp b/src/AppInstallerSharedLib/Filesystem.cpp
@@ -417,7 +417,23 @@ namespace AppInstaller::Filesystem
securityInformation |= OWNER_SECURITY_INFORMATION;
}
- THROW_IF_WIN32_ERROR(SetNamedSecurityInfoW(&path[0], SE_FILE_OBJECT, securityInformation, ownerSID, nullptr, acl.get(), nullptr));
+ DWORD result = SetNamedSecurityInfoW(&path[0], SE_FILE_OBJECT, securityInformation, ownerSID, nullptr, acl.get(), nullptr);
+
+ // We can be denied access attempting to set the owner when the owner is already correct.
+ // Determine if the owner is correct; if so, try again without attempting to set the owner.
+ if (result == ERROR_ACCESS_DENIED && ownerSID)
+ {
+ wil::unique_hlocal_security_descriptor securityDescriptor;
+ PSID currentOwnerSID = nullptr;
+ DWORD getResult = GetNamedSecurityInfoW(&path[0], SE_FILE_OBJECT, OWNER_SECURITY_INFORMATION, ¤tOwnerSID, nullptr, nullptr, nullptr, &securityDescriptor);
+
+ if (SUCCEEDED_WIN32_LOG(getResult) && currentOwnerSID && EqualSid(currentOwnerSID, ownerSID))
+ {
+ result = SetNamedSecurityInfoW(&path[0], SE_FILE_OBJECT, securityInformation & ~OWNER_SECURITY_INFORMATION, nullptr, nullptr, acl.get(), nullptr);
+ }
+ }
+
+ THROW_IF_WIN32_ERROR(result);
}
std::filesystem::path InitializeAndGetPathTo(PathDetails&& details)