diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index 86a42372cd5..e10c1ed8a5a 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -3007,7 +3007,9 @@ static void test_GetNamedSecurityInfoA(void) { char admin_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES], *user; char system_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES]; - PSID admin_sid = (PSID) admin_ptr, system_sid = (PSID) system_ptr, user_sid; + char users_ptr[sizeof(SID)+sizeof(ULONG)*SID_MAX_SUB_AUTHORITIES]; + PSID admin_sid = (PSID) admin_ptr, users_sid = (PSID) users_ptr; + PSID system_sid = (PSID) system_ptr, user_sid; DWORD sid_size = sizeof(admin_ptr), user_size; char invalid_path[] = "/an invalid file path"; char software_key[] = "MACHINE\\Software"; @@ -3015,6 +3017,7 @@ static void test_GetNamedSecurityInfoA(void) 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; @@ -3022,8 +3025,10 @@ static void test_GetNamedSecurityInfoA(void) DWORD error, revision; BOOL owner_defaulted; BOOL group_defaulted; + BOOL dacl_defaulted; HANDLE token, hTemp; PSID owner, group; + BOOL dacl_present; PACL pDacl; if (!pSetNamedSecurityInfoA || !pGetNamedSecurityInfoA || !pCreateWellKnownSid) @@ -3202,6 +3207,41 @@ static void test_GetNamedSecurityInfoA(void) || broken(((SID*)group)->SubAuthority[0] == SECURITY_NT_NON_UNIQUE) /* Vista */, "MACHINE\\Software group SID != Local System SID.\n"); LocalFree(pSD); + + /* Test querying the DACL of a built-in registry key */ + sid_size = sizeof(users_ptr); + pCreateWellKnownSid(WinBuiltinUsersSid, NULL, users_sid, &sid_size); + error = pGetNamedSecurityInfoA(software_key, SE_REGISTRY_KEY, DACL_SECURITY_INFORMATION, + NULL, NULL, NULL, NULL, &pSD); + ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); + + bret = GetSecurityDescriptorDacl(pSD, &dacl_present, &pDacl, &dacl_defaulted); + ok(bret, "GetSecurityDescriptorDacl failed with error %d\n", GetLastError()); + ok(dacl_present, "DACL should be present\n"); + ok(pDacl && IsValidAcl(pDacl), "GetSecurityDescriptorDacl returned invalid DACL.\n"); + bret = pGetAclInformation(pDacl, &acl_size, sizeof(acl_size), AclSizeInformation); + ok(bret, "GetAclInformation failed\n"); + ok(acl_size.AceCount != 0, "GetAclInformation returned no ACLs\n"); + for (i=0; iSidStart, users_sid); + if (bret) users_ace_id = i; + } + ok(users_ace_id != -1, "Bultin Users ACE not found.\n"); + if (users_ace_id != -1) + { + bret = pGetAce(pDacl, users_ace_id, (VOID **)&ace); + ok(bret, "Failed to get Builtin Users ACE.\n"); + ok(((ACE_HEADER *)ace)->AceFlags == (INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE), + "Builtin Users ACE has unexpected flags (0x%x != 0x%x)\n", ((ACE_HEADER *)ace)->AceFlags, + INHERIT_ONLY_ACE|CONTAINER_INHERIT_ACE); + ok(ace->Mask == GENERIC_READ, "Builtin Users ACE has unexpected mask (0x%x != 0x%x)\n", + ace->Mask, GENERIC_READ); + } + + LocalFree(pSD); } static void test_ConvertStringSecurityDescriptor(void) diff --git a/server/registry.c b/server/registry.c index efc2005487b..eb182f21122 100644 --- a/server/registry.c +++ b/server/registry.c @@ -345,16 +345,33 @@ static struct security_descriptor *key_get_sd( struct object *obj ) if (!key_default_sd) { - size_t sid_len = security_sid_len( security_builtin_admins_sid ); + 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; + ACCESS_ALLOWED_ACE *aaa; + ACL *dacl; - key_default_sd = mem_alloc( sizeof(*key_default_sd) + 2 * sid_len ); - key_default_sd->control = 0; - key_default_sd->owner_len = sid_len; - key_default_sd->group_len = sid_len; + key_default_sd = mem_alloc( sizeof(*key_default_sd) + 2 * admins_sid_len + dacl_len ); + key_default_sd->control = SE_DACL_PRESENT; + key_default_sd->owner_len = admins_sid_len; + key_default_sd->group_len = admins_sid_len; key_default_sd->sacl_len = 0; - key_default_sd->dacl_len = 0; - memcpy( key_default_sd + 1, security_builtin_admins_sid, sid_len ); - memcpy( (char *)(key_default_sd + 1) + sid_len, security_builtin_admins_sid, sid_len ); + key_default_sd->dacl_len = dacl_len; + memcpy( key_default_sd + 1, security_builtin_admins_sid, admins_sid_len ); + memcpy( (char *)(key_default_sd + 1) + admins_sid_len, security_builtin_admins_sid, admins_sid_len ); + + dacl = (ACL *)((char *)(key_default_sd + 1) + 2 * admins_sid_len); + dacl->AclRevision = ACL_REVISION; + dacl->Sbz1 = 0; + dacl->AclSize = dacl_len; + dacl->AceCount = 1; + dacl->Sbz2 = 0; + aaa = (ACCESS_ALLOWED_ACE *)(dacl + 1); + aaa->Header.AceType = ACCESS_ALLOWED_ACE_TYPE; + aaa->Header.AceFlags = INHERIT_ONLY_ACE | CONTAINER_INHERIT_ACE; + 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 ); } return key_default_sd; } diff --git a/server/security.h b/server/security.h index 9856f96a5ac..ab5f02763d2 100644 --- a/server/security.h +++ b/server/security.h @@ -42,6 +42,7 @@ extern const LUID SeCreateGlobalPrivilege; extern const PSID security_world_sid; extern const PSID security_local_user_sid; extern const PSID security_local_system_sid; +extern const PSID security_builtin_users_sid; extern const PSID security_builtin_admins_sid; diff --git a/server/token.c b/server/token.c index 7d6086d2dc9..6d8961a229b 100644 --- a/server/token.c +++ b/server/token.c @@ -84,6 +84,13 @@ static const struct /* same fields as struct SID */ SID_IDENTIFIER_AUTHORITY IdentifierAuthority; DWORD SubAuthority[2]; } builtin_admins_sid = { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS } }; +static const struct /* same fields as struct SID */ +{ + BYTE Revision; + BYTE SubAuthorityCount; + SID_IDENTIFIER_AUTHORITY IdentifierAuthority; + DWORD SubAuthority[2]; +} builtin_users_sid = { SID_REVISION, 2, { SECURITY_NT_AUTHORITY }, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS } }; const PSID security_world_sid = (PSID)&world_sid; static const PSID security_local_sid = (PSID)&local_sid; @@ -92,6 +99,7 @@ static const PSID security_authenticated_user_sid = (PSID)&authenticated_user_si const PSID security_local_system_sid = (PSID)&local_system_sid; const PSID security_local_user_sid = (PSID)&local_user_sid; const PSID security_builtin_admins_sid = (PSID)&builtin_admins_sid; +const PSID security_builtin_users_sid = (PSID)&builtin_users_sid; static luid_t prev_luid_value = { 1000, 0 };