advapi32: Fix GetNamedSecurityInfo with NULL descriptor.

This commit is contained in:
Alexandre Goujon 2010-08-24 11:04:35 +02:00 committed by Alexandre Julliard
parent be1aa20276
commit 2c127dd320
2 changed files with 76 additions and 22 deletions

View File

@ -5272,15 +5272,24 @@ DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
PACL* sacl, PSECURITY_DESCRIPTOR* descriptor ) PACL* sacl, PSECURITY_DESCRIPTOR* descriptor )
{ {
DWORD needed, offset; DWORD needed, offset;
SECURITY_DESCRIPTOR_RELATIVE *relative; SECURITY_DESCRIPTOR_RELATIVE *relative = NULL;
BYTE *buffer; BYTE *buffer;
TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner, TRACE( "%s %d %d %p %p %p %p %p\n", debugstr_w(name), type, info, owner,
group, dacl, sacl, descriptor ); group, dacl, sacl, descriptor );
if (!name || !descriptor) return ERROR_INVALID_PARAMETER; /* A NULL descriptor is allowed if any one of the other pointers is not NULL */
if (!name || !(owner||group||dacl||sacl||descriptor) ) return ERROR_INVALID_PARAMETER;
needed = sizeof(SECURITY_DESCRIPTOR_RELATIVE); /* If no descriptor, we have to check that there's a pointer for the requested information */
if( !descriptor && (
((info & OWNER_SECURITY_INFORMATION) && !owner)
|| ((info & GROUP_SECURITY_INFORMATION) && !group)
|| ((info & DACL_SECURITY_INFORMATION) && !dacl)
|| ((info & SACL_SECURITY_INFORMATION) && !sacl) ))
return ERROR_INVALID_PARAMETER;
needed = !descriptor ? 0 : sizeof(SECURITY_DESCRIPTOR_RELATIVE);
if (info & OWNER_SECURITY_INFORMATION) if (info & OWNER_SECURITY_INFORMATION)
needed += sizeof(sidWorld); needed += sizeof(sidWorld);
if (info & GROUP_SECURITY_INFORMATION) if (info & GROUP_SECURITY_INFORMATION)
@ -5290,6 +5299,8 @@ DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
if (info & SACL_SECURITY_INFORMATION) if (info & SACL_SECURITY_INFORMATION)
needed += WINE_SIZE_OF_WORLD_ACCESS_ACL; needed += WINE_SIZE_OF_WORLD_ACCESS_ACL;
if(descriptor)
{
/* must be freed by caller */ /* must be freed by caller */
*descriptor = HeapAlloc( GetProcessHeap(), 0, needed ); *descriptor = HeapAlloc( GetProcessHeap(), 0, needed );
if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY; if (!*descriptor) return ERROR_NOT_ENOUGH_MEMORY;
@ -5302,12 +5313,21 @@ DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
relative = *descriptor; relative = *descriptor;
relative->Control |= SE_SELF_RELATIVE; relative->Control |= SE_SELF_RELATIVE;
buffer = (BYTE *)relative; buffer = (BYTE *)relative;
offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE); offset = sizeof(SECURITY_DESCRIPTOR_RELATIVE);
}
else
{
buffer = HeapAlloc( GetProcessHeap(), 0, needed );
if (!buffer) return ERROR_NOT_ENOUGH_MEMORY;
offset = 0;
}
if (info & OWNER_SECURITY_INFORMATION) if (info & OWNER_SECURITY_INFORMATION)
{ {
memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) ); memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
if(relative)
relative->Owner = offset; relative->Owner = offset;
if (owner) if (owner)
*owner = buffer + offset; *owner = buffer + offset;
@ -5316,6 +5336,7 @@ DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
if (info & GROUP_SECURITY_INFORMATION) if (info & GROUP_SECURITY_INFORMATION)
{ {
memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) ); memcpy( buffer + offset, &sidWorld, sizeof(sidWorld) );
if(relative)
relative->Group = offset; relative->Group = offset;
if (group) if (group)
*group = buffer + offset; *group = buffer + offset;
@ -5323,21 +5344,28 @@ DWORD WINAPI GetNamedSecurityInfoW( LPWSTR name, SE_OBJECT_TYPE type,
} }
if (info & DACL_SECURITY_INFORMATION) if (info & DACL_SECURITY_INFORMATION)
{ {
relative->Control |= SE_DACL_PRESENT;
GetWorldAccessACL( (PACL)(buffer + offset) ); GetWorldAccessACL( (PACL)(buffer + offset) );
if(relative)
{
relative->Control |= SE_DACL_PRESENT;
relative->Dacl = offset; relative->Dacl = offset;
}
if (dacl) if (dacl)
*dacl = (PACL)(buffer + offset); *dacl = (PACL)(buffer + offset);
offset += WINE_SIZE_OF_WORLD_ACCESS_ACL; offset += WINE_SIZE_OF_WORLD_ACCESS_ACL;
} }
if (info & SACL_SECURITY_INFORMATION) if (info & SACL_SECURITY_INFORMATION)
{ {
relative->Control |= SE_SACL_PRESENT;
GetWorldAccessACL( (PACL)(buffer + offset) ); GetWorldAccessACL( (PACL)(buffer + offset) );
if(relative)
{
relative->Control |= SE_SACL_PRESENT;
relative->Sacl = offset; relative->Sacl = offset;
}
if (sacl) if (sacl)
*sacl = (PACL)(buffer + offset); *sacl = (PACL)(buffer + offset);
} }
return ERROR_SUCCESS; return ERROR_SUCCESS;
} }

View File

@ -2628,10 +2628,11 @@ static void test_GetNamedSecurityInfoA(void)
SECURITY_DESCRIPTOR_CONTROL control; SECURITY_DESCRIPTOR_CONTROL control;
PSID owner; PSID owner;
PSID group; PSID group;
PACL dacl;
BOOL owner_defaulted; BOOL owner_defaulted;
BOOL group_defaulted; BOOL group_defaulted;
DWORD error; DWORD error;
BOOL ret; BOOL ret, isNT4;
CHAR windows_dir[MAX_PATH]; CHAR windows_dir[MAX_PATH];
if (!pGetNamedSecurityInfoA) if (!pGetNamedSecurityInfoA)
@ -2660,13 +2661,38 @@ static void test_GetNamedSecurityInfoA(void)
broken((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == SE_DACL_PRESENT), /* NT4 */ broken((control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == SE_DACL_PRESENT), /* NT4 */
"control (0x%x) doesn't have (SE_SELF_RELATIVE|SE_DACL_PRESENT) flags set\n", control); "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); ok(revision == SECURITY_DESCRIPTOR_REVISION1, "revision was %d instead of 1\n", revision);
isNT4 = (control & (SE_SELF_RELATIVE|SE_DACL_PRESENT)) == SE_DACL_PRESENT;
ret = GetSecurityDescriptorOwner(pSecDesc, &owner, &owner_defaulted); ret = GetSecurityDescriptorOwner(pSecDesc, &owner, &owner_defaulted);
ok(ret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError()); ok(ret, "GetSecurityDescriptorOwner failed with error %d\n", GetLastError());
ok(owner != NULL, "owner should not be NULL\n"); ok(owner != NULL, "owner should not be NULL\n");
ret = GetSecurityDescriptorGroup(pSecDesc, &group, &group_defaulted); ret = GetSecurityDescriptorGroup(pSecDesc, &group, &group_defaulted);
ok(ret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); ok(ret, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError());
ok(group != NULL, "group should not be NULL\n"); ok(group != NULL, "group should not be NULL\n");
LocalFree(pSecDesc); LocalFree(pSecDesc);
/* NULL descriptor tests */
if(isNT4)
{
win_skip("NT4 does not support GetNamedSecutityInfo with a NULL descriptor\n");
return;
}
error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,
NULL, NULL, NULL, NULL, NULL);
ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %d\n", error);
error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,DACL_SECURITY_INFORMATION,
NULL, NULL, &dacl, NULL, NULL);
ok(!error, "GetNamedSecurityInfo failed with error %d\n", error);
ok(dacl != NULL, "dacl should not be NULL\n");
error = pGetNamedSecurityInfoA(windows_dir, SE_FILE_OBJECT,OWNER_SECURITY_INFORMATION,
NULL, NULL, &dacl, NULL, NULL);
ok(error==ERROR_INVALID_PARAMETER, "GetNamedSecurityInfo failed with error %d\n", error);
} }
static void test_ConvertStringSecurityDescriptor(void) static void test_ConvertStringSecurityDescriptor(void)