From: "Erich E. Hoover" Subject: [PATCH 1/2] advapi32: Add builtin admins ACE to default registry DACL. Message-Id: Date: Sat, 27 Apr 2013 21:12:18 -0600 The attached patch adds the builtin admins ACE to the default registry DACL, fixing an issue where some applications fail to create their registry keys (Bug #33473). The issue these applications see is that the builtin users DACL provides insufficient permission for the application to create subkeys, by also providing the builtin admins ACE these applications can then successfully create their desired subkeys. From bd35430e452d325ce9ced1348930328262653f51 Mon Sep 17 00:00:00 2001 From: Erich Hoover Date: Sat, 27 Apr 2013 21:09:17 -0600 Subject: advapi32: Add builtin admins ACE to default registry DACL. --- dlls/advapi32/tests/security.c | 18 ++++++++++++++++-- server/registry.c | 11 +++++++++-- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index e10c1ed..32dfb2a 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -3012,12 +3012,12 @@ static void test_GetNamedSecurityInfoA(void) PSID system_sid = (PSID) system_ptr, user_sid; DWORD sid_size = sizeof(admin_ptr), user_size; char invalid_path[] = "/an invalid file path"; + int users_ace_id = -1, admins_ace_id = -1, i; char software_key[] = "MACHINE\\Software"; char sd[SECURITY_DESCRIPTOR_MIN_LENGTH]; SECURITY_DESCRIPTOR_CONTROL control; ACL_SIZE_INFORMATION acl_size; CHAR windows_dir[MAX_PATH]; - int users_ace_id = -1, i; PSECURITY_DESCRIPTOR pSD; ACCESS_ALLOWED_ACE *ace; BOOL bret = TRUE, isNT4; @@ -3030,6 +3030,7 @@ static void test_GetNamedSecurityInfoA(void) PSID owner, group; BOOL dacl_present; PACL pDacl; + BYTE flags; if (!pSetNamedSecurityInfoA || !pGetNamedSecurityInfoA || !pCreateWellKnownSid) { @@ -3228,6 +3229,8 @@ static void test_GetNamedSecurityInfoA(void) ok(bret, "Failed to get ACE %d.\n", i); bret = EqualSid(&ace->SidStart, users_sid); if (bret) users_ace_id = i; + bret = EqualSid(&ace->SidStart, admin_sid); + if (bret) admins_ace_id = i; } ok(users_ace_id != -1, "Bultin Users ACE not found.\n"); if (users_ace_id != -1) @@ -3240,7 +3243,18 @@ static void test_GetNamedSecurityInfoA(void) ok(ace->Mask == GENERIC_READ, "Builtin Users ACE has unexpected mask (0x%x != 0x%x)\n", ace->Mask, GENERIC_READ); } - + ok(admins_ace_id != -1, "Bultin Admins ACE not found.\n"); + if (admins_ace_id != -1) + { + bret = pGetAce(pDacl, admins_ace_id, (VOID **)&ace); + ok(bret, "Failed to get Builtin Admins ACE.\n"); + flags = ((ACE_HEADER *)ace)->AceFlags; + ok(flags == 0x0 + || broken(flags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE|INHERITED_ACE)) /* w2k8 */, + "Builtin Admins ACE has unexpected flags (0x%x != 0x0)\n", flags); + ok(ace->Mask == KEY_ALL_ACCESS || broken(ace->Mask == GENERIC_ALL) /* w2k8 */, + "Builtin Admins ACE has unexpected mask (0x%x != 0x%x)\n", ace->Mask, KEY_ALL_ACCESS); + } LocalFree(pSD); } diff --git a/server/registry.c b/server/registry.c index eb182f2..809a6d2 100644 --- a/server/registry.c +++ b/server/registry.c @@ -347,7 +347,8 @@ static struct security_descriptor *key_get_sd( struct object *obj ) { size_t users_sid_len = security_sid_len( security_builtin_users_sid ); size_t admins_sid_len = security_sid_len( security_builtin_admins_sid ); - size_t dacl_len = sizeof(ACL) + offsetof( ACCESS_ALLOWED_ACE, SidStart ) + users_sid_len; + size_t dacl_len = sizeof(ACL) + 2 * offsetof( ACCESS_ALLOWED_ACE, SidStart ) + + users_sid_len + admins_sid_len; ACCESS_ALLOWED_ACE *aaa; ACL *dacl; @@ -364,7 +365,7 @@ static struct security_descriptor *key_get_sd( struct object *obj ) dacl->AclRevision = ACL_REVISION; dacl->Sbz1 = 0; dacl->AclSize = dacl_len; - dacl->AceCount = 1; + dacl->AceCount = 2; dacl->Sbz2 = 0; aaa = (ACCESS_ALLOWED_ACE *)(dacl + 1); aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; @@ -372,6 +373,12 @@ static struct security_descriptor *key_get_sd( struct object *obj ) aaa->Header.AceSize = offsetof( ACCESS_ALLOWED_ACE, SidStart ) + users_sid_len; aaa->Mask = GENERIC_READ; memcpy( &aaa->SidStart, security_builtin_users_sid, users_sid_len ); + aaa = (ACCESS_ALLOWED_ACE *)((char *)aaa + aaa->Header.AceSize); + aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; + aaa->Header.AceFlags = 0; + aaa->Header.AceSize = offsetof( ACCESS_ALLOWED_ACE, SidStart ) + admins_sid_len; + aaa->Mask = KEY_ALL_ACCESS; + memcpy( &aaa->SidStart, security_builtin_admins_sid, admins_sid_len ); } return key_default_sd; } -- 1.7.9.5