我需要在产品安装期间以编程方式修改已知注册表项上的访问描述符。我想要它的工作方式是:
这个问题类似于Setting Registry key write permissions using .NET,但是,我需要一个C ++ / Win32实现。
提前致谢
答案 0 :(得分:4)
要获取和设置密钥的ACL,您需要使用RegGetKeySecurity和RegSetKeySecurity。然后,您需要遍历ACE,检查适用于“用户”组SID的任何内容。然后,您将修改/删除现有的和/或添加新的。请注意,在普通的旧Win32 C中使用ACL是一件痛苦的事。
答案 1 :(得分:1)
只需扩展Mikhail Vorotilov的答案,还可以从以下示例代码中汲取灵感 https://docs.microsoft.com/en-us/windows/win32/secbp/creating-a-dacl
bool RegistryGrantAll(HKEY hKey)
{
bool bResult = false;
PSECURITY_DESCRIPTOR sd = nullptr;
const TCHAR* szSD =
TEXT("D:") // Discretionary ACL
TEXT("(D;OICI;KA;;;BG)") // Deny access to built-in guests
TEXT("(D;OICI;KA;;;AN)") // Deny access to anonymous logon
TEXT("(A;OICI;KRKW;;;AU)") // Allow KEY_READ and KEY_WRITE to authenticated users ("AU")
TEXT("(A;OICI;KA;;;BA)"); // Allow KEY_ALL_ACCESS to administrators ("BA" = Built-in Administrators)
if (ConvertStringSecurityDescriptorToSecurityDescriptor((LPCTSTR)szSD, SDDL_REVISION_1, &sd, 0))
{
auto result = RegSetKeySecurity(hKey, DACL_SECURITY_INFORMATION, sd);
if (ERROR_SUCCESS == result)
bResult = true;
else
SetLastError(result);
// Free the memory allocated for the SECURITY_DESCRIPTOR.
LocalFree(sd);
}
return bResult;
}
如果函数返回false,则调用GetLastError()以获取有关失败原因的更多信息。
代码在VS2019上编译并似乎可以工作。
我尚未添加代码来检查hKey是否为有效的注册表句柄。
编辑:在测试之后,我对此进行了几次编辑。对不起,所有修改。我最终得出的结论比开始时更接近米哈伊尔的答案。
链接到更多信息:
https://docs.microsoft.com/en-us/windows/win32/secbp/creating-a-dacl
https://docs.microsoft.com/en-us/windows/win32/secauthz/ace-strings
答案 2 :(得分:0)
授予访问权限的最小代码包含3个API调用。它为所有经过身份验证的用户和管理员提供对给定hkey
的完全访问权限。
此代码段不包含正确的错误处理和报告。请勿将其复制/粘贴到生产代码中。
PSECURITY_DESCRIPTOR sd = nullptr;
ULONG sd_size = 0;
TCHAR* rights = TEXT( "D:" ) // Discretionary ACL
TEXT( "(A;OICI;GA;;;AU)" ) // Allow full control to all authenticated users
TEXT( "(A;OICI;GA;;;BA)" ); // Allow full control to administrators
ConvertStringSecurityDescriptorToSecurityDescriptor( rights, SDDL_REVISION_1, &sd, &sd_size );
RegSetKeySecurity( hkey, DACL_SECURITY_INFORMATION, sd );
LocalFree( sd );
确定“用户”是否具有对该密钥的写访问权限可能比预期的难。我最后将测试值写入注册表并检查了写入结果。
答案 3 :(得分:0)
Sup,希望OP仍然对该答案感兴趣。这是将ACE添加到ACL的工作代码,可用于将ACE添加到注册表或文件系统DACL。我还没有尝试过其他任何方法。您可能会注意到,不需要繁琐的RegGetKeySecurity
或手动ACL编写。甚至不需要RegOpenKeyEx
。有关更多信息,请检查this MS doc.
UPD 当然,它需要管理员权限才能执行。
// sk - alloced string / path to needed key
// common look: MACHINE\\Software\\... where MACHINE == HKEY_LOCAL_MACHINE
// google for more address abbrevations
PSECURITY_DESCRIPTOR pSD = 0;
EXPLICIT_ACCESS ea;
PACL pOldDACL = 0, pNewDACL = 0;
if (ERROR_SUCCESS == GetNamedSecurityInfo(sk, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, 0, 0, &pOldDACL, 0, &pSD)) {
memset(&ea, 0, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = KEY_ALL_ACCESS;
ea.grfAccessMode = GRANT_ACCESS;
ea.grfInheritance = NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_NAME;
ea.Trustee.ptstrName = <USERNAME HERE>; //DOMAIN\\USERNAME
if (ERROR_SUCCESS == SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL)) {
if (ERROR_SUCCESS == SetNamedSecurityInfo(sk, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, 0, 0, pNewDACL, 0)) {
if (pSD != 0) LocalFree((HLOCAL)pSD);
if (pNewDACL != 0) LocalFree((HLOCAL)pNewDACL);
SAFE_FREE(sk);
// WE'RE GOOD!
return ... ;
} else {
if (pSD) LocalFree((HLOCAL)pSD);
if (pNewDACL) LocalFree((HLOCAL)pNewDACL);
SAFE_FREE(sk);
// SetNamedSecurityInfo failed
return ... ;
}
} else {
if (pSD) LocalFree((HLOCAL)pSD);
if (pNewDACL) LocalFree((HLOCAL)pNewDACL);
SAFE_FREE(sk);
// SetEntriesInAcl failed
return ... ;
}
} else {
if (pSD) LocalFree((HLOCAL)pSD);
SAFE_FREE(sk);
// GetNamedSecurityInfo failed
return ... ;
}