Sign in with
Sign up | Sign in
Your question

How do I programmatically set *inheritable* permissions on..

Last response: in Windows 2000/NT
Share
Anonymous
a b 8 Security
January 28, 2005 4:51:11 PM

Archived from groups: microsoft.public.vc.mfc,microsoft.public.security,microsoft.public.windowsnt.registry,microsoft.public.win2000.registry (More info?)

I'm struggling to find a way to programmatically set inheritable
permissions on registry keys. The only examples I've seen set them on a
specified key and advise one to apply it recursively. This is fine if
that part of the registry is static... but useless if new keys are to be
created in the future as they won't inherit the new permissions.

I've cobbled together two code examples that do what I describe. How
would I modify them to make them inheritable? I read somewhere about
CONTAINER_INHERIT, but I don't know it's value, and nor where I should
apply it.

BOOL setPermissionsExample1()
{
// Resets permissions on a key so that they are Full Access to special
// group INTERACTIVE. Appears to only set permissions for the specified
// key and not for subkeys as well.

HKEY hKey = NULL;
TCHAR szSubkeyName[] = _T("SOFTWARE\\MyKey");
if (ERROR_SUCCESS != ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubkeyName,
0, WRITE_DAC, &hKey))
{
return FALSE;
}

SID_IDENTIFIER_AUTHORITY SecIA = SECURITY_NT_AUTHORITY;
PSID pSid = NULL;

if (FALSE == ::AllocateAndInitializeSid(&SecIA, 1,
SECURITY_INTERACTIVE_RID, 0, 0, 0, 0, 0, 0, 0, &pSid))
{
return FALSE;
}

BOOL bSuccess = FALSE;

DWORD dwAclSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) +
::GetLengthSid(pSid) - sizeof(DWORD);
PACL pDacl = (PACL) new BYTE[dwAclSize];

if (TRUE == ::InitializeAcl(pDacl, dwAclSize, ACL_REVISION))
{
if (TRUE == ::AddAccessAllowedAce(pDacl, ACL_REVISION, KEY_ALL_ACCESS,
pSid))
{
SECURITY_DESCRIPTOR SecDesc;
if (TRUE == ::InitializeSecurityDescriptor(&SecDesc,
SECURITY_DESCRIPTOR_REVISION))
{
if (TRUE == ::SetSecurityDescriptorDacl(&SecDesc, TRUE, pDacl, FALSE))
{
bSuccess = (ERROR_SUCCESS == ::RegSetKeySecurity(hKey,
(SECURITY_INFORMATION)DACL_SECURITY_INFORMATION, &SecDesc));
}
}
}
}

::RegCloseKey(hKey);
delete[] (BYTE*) pDacl;
if (pSid != NULL)
{
::FreeSid(pSid);
}

return bSuccess;
}


void setPermissionsExample2()
{
// Resets permissions on a key so that they are Full Access to special
// group EVERYONE. Appears to only set permissions for the specified
// key and not for subkeys as well.

TCHAR szSubkeyName[] = _T("SOFTWARE\\MyKey");
HKEY myKey;
unsigned char *p = new unsigned char[9000];
PSECURITY_DESCRIPTOR psecdesc = (PSECURITY_DESCRIPTOR)p;
DWORD sts = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubkeyName, 0,
KEY_ALL_ACCESS, &myKey);

if (sts == ERROR_SUCCESS)
{
sts = InitializeSecurityDescriptor(psecdesc,
SECURITY_DESCRIPTOR_REVISION);
sts = SetSecurityDescriptorDacl(psecdesc, TRUE, NULL, TRUE);
sts = ::RegSetKeySecurity(myKey, DACL_SECURITY_INFORMATION, psecdesc);
sts = ::RegCloseKey(myKey);
}
delete [] p;
}
Anonymous
a b 8 Security
January 30, 2005 2:04:14 AM

Archived from groups: microsoft.public.windowsnt.registry (More info?)

Got it: needed to use AddAccessAllowedAceEx:

if (TRUE == AddAccessAllowedAceEx(pDacl, ACL_REVISION,
CONTAINER_INHERIT_ACE | OBJECT_INHERIT_ACE, KEY_ALL_ACCESS, pSid))

Malcolm Ferguson wrote:
> I'm struggling to find a way to programmatically set inheritable
> permissions on registry keys. The only examples I've seen set them on a
> specified key and advise one to apply it recursively. This is fine if
> that part of the registry is static... but useless if new keys are to be
> created in the future as they won't inherit the new permissions.
>
> I've cobbled together two code examples that do what I describe. How
> would I modify them to make them inheritable? I read somewhere about
> CONTAINER_INHERIT, but I don't know it's value, and nor where I should
> apply it.
>
> BOOL setPermissionsExample1()
> {
> // Resets permissions on a key so that they are Full Access to special
> // group INTERACTIVE. Appears to only set permissions for the
> specified
> // key and not for subkeys as well.
>
> HKEY hKey = NULL;
> TCHAR szSubkeyName[] = _T("SOFTWARE\\MyKey");
> if (ERROR_SUCCESS != ::RegOpenKeyEx(HKEY_LOCAL_MACHINE,
> szSubkeyName, 0, WRITE_DAC, &hKey))
> {
> return FALSE;
> }
>
> SID_IDENTIFIER_AUTHORITY SecIA = SECURITY_NT_AUTHORITY;
> PSID pSid = NULL;
>
> if (FALSE == ::AllocateAndInitializeSid(&SecIA, 1,
> SECURITY_INTERACTIVE_RID, 0, 0, 0, 0, 0, 0, 0, &pSid))
> {
> return FALSE;
> }
>
> BOOL bSuccess = FALSE;
>
> DWORD dwAclSize = sizeof(ACL) + sizeof(ACCESS_ALLOWED_ACE) +
> ::GetLengthSid(pSid) - sizeof(DWORD);
> PACL pDacl = (PACL) new BYTE[dwAclSize];
>
> if (TRUE == ::InitializeAcl(pDacl, dwAclSize, ACL_REVISION))
> {
> if (TRUE == ::AddAccessAllowedAce(pDacl, ACL_REVISION,
> KEY_ALL_ACCESS, pSid))
> {
> SECURITY_DESCRIPTOR SecDesc;
> if (TRUE == ::InitializeSecurityDescriptor(&SecDesc,
> SECURITY_DESCRIPTOR_REVISION))
> {
> if (TRUE == ::SetSecurityDescriptorDacl(&SecDesc, TRUE,
> pDacl, FALSE))
> {
> bSuccess = (ERROR_SUCCESS ==
> ::RegSetKeySecurity(hKey,
> (SECURITY_INFORMATION)DACL_SECURITY_INFORMATION, &SecDesc));
> }
> }
> }
> }
>
> ::RegCloseKey(hKey);
> delete[] (BYTE*) pDacl;
> if (pSid != NULL)
> {
> ::FreeSid(pSid);
> }
>
> return bSuccess;
> }
>
>
> void setPermissionsExample2()
> {
> // Resets permissions on a key so that they are Full Access to special
> // group EVERYONE. Appears to only set permissions for the specified
> // key and not for subkeys as well.
>
> TCHAR szSubkeyName[] = _T("SOFTWARE\\MyKey");
> HKEY myKey;
> unsigned char *p = new unsigned char[9000];
> PSECURITY_DESCRIPTOR psecdesc = (PSECURITY_DESCRIPTOR)p;
> DWORD sts = ::RegOpenKeyEx(HKEY_LOCAL_MACHINE, szSubkeyName, 0,
> KEY_ALL_ACCESS, &myKey);
>
> if (sts == ERROR_SUCCESS)
> {
> sts = InitializeSecurityDescriptor(psecdesc,
> SECURITY_DESCRIPTOR_REVISION);
> sts = SetSecurityDescriptorDacl(psecdesc, TRUE, NULL, TRUE);
> sts = ::RegSetKeySecurity(myKey, DACL_SECURITY_INFORMATION,
> psecdesc);
> sts = ::RegCloseKey(myKey);
> }
> delete [] p;
> }
!