server: Implement querying the security label of a security descriptor.
Signed-off-by: Matteo Bruni <mbruni@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
538e46adea
commit
2ebe679638
|
@ -6163,11 +6163,17 @@ static void test_AddMandatoryAce(void)
|
||||||
{
|
{
|
||||||
static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
|
static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
|
||||||
{SECURITY_MANDATORY_LOW_RID}};
|
{SECURITY_MANDATORY_LOW_RID}};
|
||||||
|
char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
|
||||||
|
SECURITY_DESCRIPTOR *sd2, *sd = (SECURITY_DESCRIPTOR *)&buffer_sd;
|
||||||
|
BOOL defaulted, present, ret, found;
|
||||||
|
ACL_SIZE_INFORMATION acl_size_info;
|
||||||
SYSTEM_MANDATORY_LABEL_ACE *ace;
|
SYSTEM_MANDATORY_LABEL_ACE *ace;
|
||||||
char buffer_acl[256];
|
char buffer_acl[256];
|
||||||
ACL *pAcl = (ACL *)&buffer_acl;
|
ACL *acl = (ACL *)&buffer_acl;
|
||||||
BOOL ret, found;
|
SECURITY_ATTRIBUTES sa;
|
||||||
DWORD index;
|
DWORD index, size;
|
||||||
|
HANDLE handle;
|
||||||
|
ACL *sacl;
|
||||||
|
|
||||||
if (!pAddMandatoryAce)
|
if (!pAddMandatoryAce)
|
||||||
{
|
{
|
||||||
|
@ -6175,21 +6181,49 @@ static void test_AddMandatoryAce(void)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = InitializeAcl(pAcl, 256, ACL_REVISION);
|
ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
|
||||||
|
ok(ret, "InitializeSecurityDescriptor failed with error %u\n", GetLastError());
|
||||||
|
|
||||||
|
sa.nLength = sizeof(sa);
|
||||||
|
sa.lpSecurityDescriptor = sd;
|
||||||
|
sa.bInheritHandle = FALSE;
|
||||||
|
|
||||||
|
handle = CreateEventA(&sa, TRUE, TRUE, "test_event");
|
||||||
|
ok(handle != NULL, "CreateEventA failed with error %u\n", GetLastError());
|
||||||
|
|
||||||
|
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
|
||||||
|
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
|
||||||
|
"Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
|
||||||
|
|
||||||
|
sd2 = HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
|
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
|
||||||
|
ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
|
||||||
|
|
||||||
|
sacl = (void *)0xdeadbeef;
|
||||||
|
present = TRUE;
|
||||||
|
ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
|
||||||
|
ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
|
||||||
|
todo_wine ok(!present, "SACL is present\n");
|
||||||
|
todo_wine ok(sacl == (void *)0xdeadbeef, "SACL is set\n");
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, sd2);
|
||||||
|
CloseHandle(handle);
|
||||||
|
|
||||||
|
ret = InitializeAcl(acl, 256, ACL_REVISION);
|
||||||
ok(ret, "InitializeAcl failed with %u\n", GetLastError());
|
ok(ret, "InitializeAcl failed with %u\n", GetLastError());
|
||||||
|
|
||||||
SetLastError(0xdeadbeef);
|
SetLastError(0xdeadbeef);
|
||||||
ret = pAddMandatoryAce(pAcl, ACL_REVISION, 0, 0x1234, &low_level);
|
ret = pAddMandatoryAce(acl, ACL_REVISION, 0, 0x1234, &low_level);
|
||||||
ok(!ret, "AddMandatoryAce succeeded\n");
|
ok(!ret, "AddMandatoryAce succeeded\n");
|
||||||
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
ok(GetLastError() == ERROR_INVALID_PARAMETER,
|
||||||
"Expected ERROR_INVALID_PARAMETER got %u\n", GetLastError());
|
"Expected ERROR_INVALID_PARAMETER got %u\n", GetLastError());
|
||||||
|
|
||||||
ret = pAddMandatoryAce(pAcl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_level);
|
ret = pAddMandatoryAce(acl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_level);
|
||||||
ok(ret, "AddMandatoryAce failed with %u\n", GetLastError());
|
ok(ret, "AddMandatoryAce failed with %u\n", GetLastError());
|
||||||
|
|
||||||
index = 0;
|
index = 0;
|
||||||
found = FALSE;
|
found = FALSE;
|
||||||
while (pGetAce( pAcl, index++, (void **)&ace ))
|
while (pGetAce(acl, index++, (void **)&ace))
|
||||||
{
|
{
|
||||||
if (ace->Header.AceType != SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue;
|
if (ace->Header.AceType != SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue;
|
||||||
ok(ace->Header.AceFlags == 0, "Expected flags 0, got %x\n", ace->Header.AceFlags);
|
ok(ace->Header.AceFlags == 0, "Expected flags 0, got %x\n", ace->Header.AceFlags);
|
||||||
|
@ -6199,6 +6233,42 @@ static void test_AddMandatoryAce(void)
|
||||||
found = TRUE;
|
found = TRUE;
|
||||||
}
|
}
|
||||||
ok(found, "Could not find mandatory label ace\n");
|
ok(found, "Could not find mandatory label ace\n");
|
||||||
|
|
||||||
|
ret = SetSecurityDescriptorSacl(sd, TRUE, acl, FALSE);
|
||||||
|
ok(ret, "SetSecurityDescriptorSacl failed with error %u\n", GetLastError());
|
||||||
|
|
||||||
|
handle = CreateEventA(&sa, TRUE, TRUE, "test_event");
|
||||||
|
ok(handle != NULL, "CreateEventA failed with error %u\n", GetLastError());
|
||||||
|
|
||||||
|
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
|
||||||
|
ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
|
||||||
|
"Unexpected GetKernelObjectSecurity return value %u, error %u\n", ret, GetLastError());
|
||||||
|
|
||||||
|
sd2 = HeapAlloc(GetProcessHeap(), 0, size);
|
||||||
|
ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
|
||||||
|
ok(ret, "GetKernelObjectSecurity failed with error %u\n", GetLastError());
|
||||||
|
|
||||||
|
sacl = (void *)0xdeadbeef;
|
||||||
|
present = FALSE;
|
||||||
|
defaulted = TRUE;
|
||||||
|
ret = GetSecurityDescriptorSacl(sd2, &present, &sacl, &defaulted);
|
||||||
|
ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
|
||||||
|
ok(present, "SACL not present\n");
|
||||||
|
ok(sacl != (void *)0xdeadbeef, "SACL not set\n");
|
||||||
|
ok(!defaulted, "SACL defaulted\n");
|
||||||
|
ret = pGetAclInformation(sacl, &acl_size_info, sizeof(acl_size_info), AclSizeInformation);
|
||||||
|
ok(ret, "GetAclInformation failed with error %u\n", GetLastError());
|
||||||
|
ok(acl_size_info.AceCount == 1, "SACL contains an unexpected ACE count %u\n", acl_size_info.AceCount);
|
||||||
|
|
||||||
|
ret = pGetAce(sacl, 0, (void **)&ace);
|
||||||
|
ok(ret, "GetAce failed with error %u\n", GetLastError());
|
||||||
|
ok (ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE, "Unexpected ACE type %#x\n", ace->Header.AceType);
|
||||||
|
ok(!ace->Header.AceFlags, "Unexpected ACE flags %#x\n", ace->Header.AceFlags);
|
||||||
|
ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, "Unexpected ACE mask %#x\n", ace->Mask);
|
||||||
|
ok(EqualSid(&ace->SidStart, &low_level), "Expected low integrity level\n");
|
||||||
|
|
||||||
|
HeapFree(GetProcessHeap(), 0, sd2);
|
||||||
|
CloseHandle(handle);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void test_system_security_access(void)
|
static void test_system_security_access(void)
|
||||||
|
|
|
@ -5276,6 +5276,7 @@ typedef struct _TAPE_GET_MEDIA_PARAMETERS {
|
||||||
#define GROUP_SECURITY_INFORMATION 0x00000002
|
#define GROUP_SECURITY_INFORMATION 0x00000002
|
||||||
#define DACL_SECURITY_INFORMATION 0x00000004
|
#define DACL_SECURITY_INFORMATION 0x00000004
|
||||||
#define SACL_SECURITY_INFORMATION 0x00000008
|
#define SACL_SECURITY_INFORMATION 0x00000008
|
||||||
|
#define LABEL_SECURITY_INFORMATION 0x00000010
|
||||||
|
|
||||||
#define REG_OPTION_RESERVED 0x00000000
|
#define REG_OPTION_RESERVED 0x00000000
|
||||||
#define REG_OPTION_NON_VOLATILE 0x00000000
|
#define REG_OPTION_NON_VOLATILE 0x00000000
|
||||||
|
@ -5283,11 +5284,11 @@ typedef struct _TAPE_GET_MEDIA_PARAMETERS {
|
||||||
#define REG_OPTION_CREATE_LINK 0x00000002
|
#define REG_OPTION_CREATE_LINK 0x00000002
|
||||||
#define REG_OPTION_BACKUP_RESTORE 0x00000004 /* FIXME */
|
#define REG_OPTION_BACKUP_RESTORE 0x00000004 /* FIXME */
|
||||||
#define REG_OPTION_OPEN_LINK 0x00000008
|
#define REG_OPTION_OPEN_LINK 0x00000008
|
||||||
#define REG_LEGAL_OPTION (REG_OPTION_RESERVED| \
|
#define REG_LEGAL_OPTION (REG_OPTION_RESERVED | \
|
||||||
REG_OPTION_NON_VOLATILE| \
|
REG_OPTION_NON_VOLATILE | \
|
||||||
REG_OPTION_VOLATILE| \
|
REG_OPTION_VOLATILE | \
|
||||||
REG_OPTION_CREATE_LINK| \
|
REG_OPTION_CREATE_LINK | \
|
||||||
REG_OPTION_BACKUP_RESTORE| \
|
REG_OPTION_BACKUP_RESTORE | \
|
||||||
REG_OPTION_OPEN_LINK)
|
REG_OPTION_OPEN_LINK)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -709,6 +709,7 @@ DECL_HANDLER(get_security_object)
|
||||||
int present;
|
int present;
|
||||||
const SID *owner, *group;
|
const SID *owner, *group;
|
||||||
const ACL *sacl, *dacl;
|
const ACL *sacl, *dacl;
|
||||||
|
ACL *label_acl = NULL;
|
||||||
|
|
||||||
if (req->security_info & SACL_SECURITY_INFORMATION)
|
if (req->security_info & SACL_SECURITY_INFORMATION)
|
||||||
access |= ACCESS_SYSTEM_SECURITY;
|
access |= ACCESS_SYSTEM_SECURITY;
|
||||||
|
@ -736,6 +737,12 @@ DECL_HANDLER(get_security_object)
|
||||||
sacl = sd_get_sacl( sd, &present );
|
sacl = sd_get_sacl( sd, &present );
|
||||||
if (req->security_info & SACL_SECURITY_INFORMATION && present)
|
if (req->security_info & SACL_SECURITY_INFORMATION && present)
|
||||||
req_sd.sacl_len = sd->sacl_len;
|
req_sd.sacl_len = sd->sacl_len;
|
||||||
|
else if (req->security_info & LABEL_SECURITY_INFORMATION && present && sacl)
|
||||||
|
{
|
||||||
|
if (!(label_acl = extract_security_labels( sacl ))) goto done;
|
||||||
|
req_sd.sacl_len = label_acl->AclSize;
|
||||||
|
sacl = label_acl;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
req_sd.sacl_len = 0;
|
req_sd.sacl_len = 0;
|
||||||
|
|
||||||
|
@ -766,7 +773,9 @@ DECL_HANDLER(get_security_object)
|
||||||
set_error(STATUS_BUFFER_TOO_SMALL);
|
set_error(STATUS_BUFFER_TOO_SMALL);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
done:
|
||||||
release_object( obj );
|
release_object( obj );
|
||||||
|
free( label_acl );
|
||||||
}
|
}
|
||||||
|
|
||||||
struct enum_handle_info
|
struct enum_handle_info
|
||||||
|
|
|
@ -96,6 +96,7 @@ static inline int thread_single_check_privilege( struct thread *thread, const LU
|
||||||
/* security descriptor helper functions */
|
/* security descriptor helper functions */
|
||||||
|
|
||||||
extern int sd_is_valid( const struct security_descriptor *sd, data_size_t size );
|
extern int sd_is_valid( const struct security_descriptor *sd, data_size_t size );
|
||||||
|
extern ACL *extract_security_labels( const ACL *sacl );
|
||||||
|
|
||||||
/* gets the discretionary access control list from a security descriptor */
|
/* gets the discretionary access control list from a security descriptor */
|
||||||
static inline const ACL *sd_get_dacl( const struct security_descriptor *sd, int *present )
|
static inline const ACL *sd_get_dacl( const struct security_descriptor *sd, int *present )
|
||||||
|
|
|
@ -336,6 +336,47 @@ int sd_is_valid( const struct security_descriptor *sd, data_size_t size )
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* extract security labels from SACL */
|
||||||
|
ACL *extract_security_labels( const ACL *sacl )
|
||||||
|
{
|
||||||
|
size_t size = sizeof(ACL);
|
||||||
|
const ACE_HEADER *ace;
|
||||||
|
ACE_HEADER *label_ace;
|
||||||
|
unsigned int i, count = 0;
|
||||||
|
ACL *label_acl;
|
||||||
|
|
||||||
|
ace = (const ACE_HEADER *)(sacl + 1);
|
||||||
|
for (i = 0; i < sacl->AceCount; i++, ace = ace_next( ace ))
|
||||||
|
{
|
||||||
|
if (ace->AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE)
|
||||||
|
{
|
||||||
|
size += ace->AceSize;
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
label_acl = mem_alloc( size );
|
||||||
|
if (!label_acl) return NULL;
|
||||||
|
|
||||||
|
label_acl->AclRevision = sacl->AclRevision;
|
||||||
|
label_acl->Sbz1 = 0;
|
||||||
|
label_acl->AclSize = size;
|
||||||
|
label_acl->AceCount = count;
|
||||||
|
label_acl->Sbz2 = 0;
|
||||||
|
label_ace = (ACE_HEADER *)(label_acl + 1);
|
||||||
|
|
||||||
|
ace = (const ACE_HEADER *)(sacl + 1);
|
||||||
|
for (i = 0; i < sacl->AceCount; i++, ace = ace_next( ace ))
|
||||||
|
{
|
||||||
|
if (ace->AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE)
|
||||||
|
{
|
||||||
|
memcpy( label_ace, ace, ace->AceSize );
|
||||||
|
label_ace = (ACE_HEADER *)ace_next( label_ace );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return label_acl;
|
||||||
|
}
|
||||||
|
|
||||||
/* maps from generic rights to specific rights as given by a mapping */
|
/* maps from generic rights to specific rights as given by a mapping */
|
||||||
static inline void map_generic_mask(unsigned int *mask, const GENERIC_MAPPING *mapping)
|
static inline void map_generic_mask(unsigned int *mask, const GENERIC_MAPPING *mapping)
|
||||||
{
|
{
|
||||||
|
|
Loading…
Reference in New Issue