diff --git a/dlls/advapi32/security.c b/dlls/advapi32/security.c index 126a4ac260a..b46a6f7ab36 100644 --- a/dlls/advapi32/security.c +++ b/dlls/advapi32/security.c @@ -3951,32 +3951,38 @@ DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type, buffer = (BYTE *)relative; offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE); - if (owner && (info & OWNER_SECURITY_INFORMATION)) + if (info & OWNER_SECURITY_INFORMATION) { memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) ); relative->Owner = offset; - *owner = buffer + offset; + if (owner) + *owner = buffer + offset; offset += sizeof(sidWorld); } - if (group && (info & GROUP_SECURITY_INFORMATION)) + if (info & GROUP_SECURITY_INFORMATION) { memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) ); relative->Group = offset; - *group = buffer + offset; + if (group) + *group = buffer + offset; offset += sizeof(sidWorld); } - if (dacl && (info & DACL_SECURITY_INFORMATION)) + if (info & DACL_SECURITY_INFORMATION) { + relative->Control |= SE_DACL_PRESENT; GetWorldAccessACL( (PACL)(buffer + offset) ); relative->Dacl = offset; - *dacl = (PACL)(buffer + offset); + if (dacl) + *dacl = (PACL)(buffer + offset); offset += WINE_SIZE_OF_WORLD_ACCESS_ACL; } - if (sacl && (info & SACL_SECURITY_INFORMATION)) + if (info & SACL_SECURITY_INFORMATION) { + relative->Control |= SE_SACL_PRESENT; GetWorldAccessACL( (PACL)(buffer + offset) ); relative->Sacl = offset; - *sacl = (PACL)(buffer + offset); + if (sacl) + *sacl = (PACL)(buffer + offset); } return ERROR_SUCCESS; } diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index 9aba94bc810..532dc69e2d0 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -1718,6 +1718,40 @@ static void test_SetEntriesInAcl(void) ok(acl == NULL, "acl=%p, expected NULL\n", acl); } +static void test_GetNamedSecurityInfoA(void) +{ + PSECURITY_DESCRIPTOR pSecDesc; + DWORD revision; + SECURITY_DESCRIPTOR_CONTROL control; + PSID owner; + PSID group; + BOOL owner_defaulted; + BOOL group_defaulted; + DWORD error; + BOOL ret; + CHAR windows_dir[MAX_PATH]; + + ret = GetWindowsDirectoryA(windows_dir, MAX_PATH); + ok(ret, "GetWindowsDirectory failed with error %d\n", GetLastError()); + + error = GetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT, + OWNER_SECURITY_INFORMATION|GROUP_SECURITY_INFORMATION|DACL_SECURITY_INFORMATION, + NULL, NULL, NULL, NULL, &pSecDesc); + ok(!error, "GetNamedSecurityInfo failed with error %d\n", error); + + ret = GetSecurityDescriptorControl(pSecDesc, &control, &revision); + ok(ret, "GetSecurityDescriptorControl failed with error %d\n", GetLastError()); + ok((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == (SE_SELF_RELATIVE|SE_DACL_PRESENT), + "control (0x%x) doesn't have (SE_SELF_RELATIVE|SE_DACL_PRESENT) flags set\n", control); + ok(revision == SECURITY_DESCRIPTOR_REVISION1, "revision was %d instead of 1\n", revision); + ret = GetSecurityDescriptorOwner(pSecDesc, &owner, &owner_defaulted); + ok(ret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError()); + ok(owner != NULL, "owner should not be NULL\n"); + ret = GetSecurityDescriptorGroup(pSecDesc, &group, &group_defaulted); + ok(ret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); + ok(group != NULL, "group should not be NULL\n"); +} + START_TEST(security) { init(); @@ -1739,4 +1773,5 @@ START_TEST(security) test_process_security(); test_impersonation_level(); test_SetEntriesInAcl(); + test_GetNamedSecurityInfoA(); }