Added patch to implement support for LABEL_SECURITY_INFORMATION.

This commit is contained in:
Sebastian Lackner 2017-01-14 05:38:36 +01:00
parent b2098faef8
commit f06f5c3b0c
11 changed files with 1554 additions and 0 deletions

View File

@ -290,6 +290,7 @@ patch_enable_all ()
enable_server_File_Permissions="$1"
enable_server_Inherited_ACLs="$1"
enable_server_Key_State="$1"
enable_server_LABEL_SECURITY_INFORMATION="$1"
enable_server_Map_EXDEV_Error="$1"
enable_server_Misc_ACL="$1"
enable_server_PeekMessage="$1"
@ -1069,6 +1070,9 @@ patch_enable ()
server-Key_State)
enable_server_Key_State="$2"
;;
server-LABEL_SECURITY_INFORMATION)
enable_server_LABEL_SECURITY_INFORMATION="$2"
;;
server-Map_EXDEV_Error)
enable_server_Map_EXDEV_Error="$2"
;;
@ -2246,6 +2250,25 @@ if test "$enable_server_Pipe_ObjectName" -eq 1; then
enable_kernel32_Named_Pipe=1
fi
if test "$enable_server_LABEL_SECURITY_INFORMATION" -eq 1; then
if test "$enable_advapi32_AddMandatoryAce" -gt 1; then
abort "Patchset advapi32-AddMandatoryAce disabled, but server-LABEL_SECURITY_INFORMATION depends on that."
fi
if test "$enable_advapi32_GetExplicitEntriesFromAclW" -gt 1; then
abort "Patchset advapi32-GetExplicitEntriesFromAclW disabled, but server-LABEL_SECURITY_INFORMATION depends on that."
fi
if test "$enable_server_Misc_ACL" -gt 1; then
abort "Patchset server-Misc_ACL disabled, but server-LABEL_SECURITY_INFORMATION depends on that."
fi
if test "$enable_server_Stored_ACLs" -gt 1; then
abort "Patchset server-Stored_ACLs disabled, but server-LABEL_SECURITY_INFORMATION depends on that."
fi
enable_advapi32_AddMandatoryAce=1
enable_advapi32_GetExplicitEntriesFromAclW=1
enable_server_Misc_ACL=1
enable_server_Stored_ACLs=1
fi
if test "$enable_server_Inherited_ACLs" -eq 1; then
if test "$enable_server_Stored_ACLs" -gt 1; then
abort "Patchset server-Stored_ACLs disabled, but server-Inherited_ACLs depends on that."
@ -6413,6 +6436,39 @@ if test "$enable_server_Key_State" -eq 1; then
) >> "$patchlist"
fi
# Patchset server-LABEL_SECURITY_INFORMATION
# |
# | This patchset has the following (direct or indirect) dependencies:
# | * advapi32-AddMandatoryAce, advapi32-GetExplicitEntriesFromAclW, server-Misc_ACL, ntdll-DOS_Attributes, server-
# | File_Permissions, server-Stored_ACLs
# |
# | Modified files:
# | * dlls/advapi32/tests/security.c, dlls/ntdll/nt.c, dlls/ntdll/sec.c, include/winnt.h, server/handle.c, server/object.c,
# | server/process.c, server/protocol.def, server/security.h, server/token.c
# |
if test "$enable_server_LABEL_SECURITY_INFORMATION" -eq 1; then
patch_apply server-LABEL_SECURITY_INFORMATION/0001-server-Implement-querying-the-security-label-of-a-se.patch
patch_apply server-LABEL_SECURITY_INFORMATION/0002-server-Implement-changing-the-label-of-a-security-de.patch
patch_apply server-LABEL_SECURITY_INFORMATION/0003-server-Do-not-set-SE_-D-S-ACL_PRESENT-if-no-D-S-ACL-.patch
patch_apply server-LABEL_SECURITY_INFORMATION/0004-server-Implement-setting-a-security-descriptor-when-.patch
patch_apply server-LABEL_SECURITY_INFORMATION/0005-advapi32-tests-Add-basic-tests-for-token-security-de.patch
patch_apply server-LABEL_SECURITY_INFORMATION/0006-advapi32-tests-Show-that-tokens-do-not-inherit-secur.patch
patch_apply server-LABEL_SECURITY_INFORMATION/0007-advapi32-tests-Show-that-tokens-do-not-inherit-dacls.patch
patch_apply server-LABEL_SECURITY_INFORMATION/0008-advapi32-tests-Show-that-tokens-do-not-inherit-sacls.patch
patch_apply server-LABEL_SECURITY_INFORMATION/0009-server-Assign-a-default-label-high-to-all-tokens.patch
(
echo '+ { "Michael Müller", "server: Implement querying the security label of a security descriptor.", 1 },';
echo '+ { "Michael Müller", "server: Implement changing the label of a security descriptor.", 1 },';
echo '+ { "Michael Müller", "server: Do not set SE_{D,S}ACL_PRESENT if no {D,S}ACL was set.", 1 },';
echo '+ { "Michael Müller", "server: Implement setting a security descriptor when duplicating tokens.", 1 },';
echo '+ { "Michael Müller", "advapi32/tests: Add basic tests for token security descriptors.", 1 },';
echo '+ { "Michael Müller", "advapi32/tests: Show that tokens do not inherit security descriptors during duplication.", 1 },';
echo '+ { "Michael Müller", "advapi32/tests: Show that tokens do not inherit dacls while creating child processes.", 1 },';
echo '+ { "Michael Müller", "advapi32/tests: Show that tokens do not inherit sacls / mandatory labels while creating child processes.", 1 },';
echo '+ { "Michael Müller", "server: Assign a default label (high) to all tokens.", 1 },';
) >> "$patchlist"
fi
# Patchset server-Map_EXDEV_Error
# |
# | Modified files:

View File

@ -0,0 +1,222 @@
From a05c00f17a61a2d34a5e439b5c4f835f011187b0 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Mon, 29 Aug 2016 20:35:51 +0200
Subject: server: Implement querying the security label of a security
descriptor.
---
dlls/advapi32/tests/security.c | 80 ++++++++++++++++++++++++++++++++++++++++--
include/winnt.h | 1 +
server/handle.c | 55 +++++++++++++++++++++++++++++
3 files changed, 134 insertions(+), 2 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 98f98721a0c..877250c1ebf 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -6435,10 +6435,15 @@ static void test_integrity(void)
static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
{SECURITY_MANDATORY_LOW_RID}};
SYSTEM_MANDATORY_LABEL_ACE *ace;
+ char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
+ SECURITY_DESCRIPTOR *sd2, *sd = (SECURITY_DESCRIPTOR *)&buffer_sd;
+ SECURITY_ATTRIBUTES sa;
char buffer_acl[256];
ACL *pAcl = (ACL*)&buffer_acl;
- BOOL ret, found;
- DWORD index;
+ ACL *sAcl;
+ BOOL defaulted, present, ret, found;
+ HANDLE handle;
+ DWORD index, size;
if (!pAddMandatoryAce)
{
@@ -6446,6 +6451,36 @@ static void test_integrity(void)
return;
}
+ ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
+ ok(ret, "InitializeSecurityDescriptor failed with %u\n", GetLastError());
+
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ 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,
+ "GetKernelObjectSecurity failed with %u\n", GetLastError());
+
+ sd2 = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed %u\n", GetLastError());
+
+ sAcl = (void *)0xdeadbeef;
+ present = TRUE;
+ defaulted = TRUE;
+ ret = GetSecurityDescriptorSacl(sd2, &present, &sAcl, &defaulted);
+ ok(ret, "GetSecurityDescriptorSacl failed with %u\n", GetLastError());
+ todo_wine ok(!present, "sAcl is present\n");
+ todo_wine ok(sAcl == (void *)0xdeadbeef, "sAcl is set\n");
+ ok(!defaulted, "sAcl defaulted\n");
+
+ HeapFree(GetProcessHeap(), 0, sd2);
+ CloseHandle(handle);
+
ret = InitializeAcl(pAcl, 256, ACL_REVISION);
ok(ret, "InitializeAcl failed with %u\n", GetLastError());
@@ -6470,6 +6505,47 @@ static void test_integrity(void)
}
}
ok(found, "Could not find mandatory label\n");
+
+ ret = SetSecurityDescriptorSacl(sd, TRUE, pAcl, FALSE);
+ ok(ret, "SetSecurityDescriptorSacl failed with %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,
+ "GetKernelObjectSecurity failed with %u\n", GetLastError());
+
+ sd2 = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed %u\n", GetLastError());
+
+ sAcl = (void *)0xdeadbeef;
+ present = FALSE;
+ defaulted = TRUE;
+ ret = GetSecurityDescriptorSacl(sd2, &present, &sAcl, &defaulted);
+ ok(ret, "GetSecurityDescriptorSacl failed with %u\n", GetLastError());
+ ok(present, "sAcl not present\n");
+ ok(sAcl != (void *)0xdeadbeef, "sAcl not set\n");
+ ok(!defaulted, "sAcl defaulted\n");
+
+ index = 0;
+ found = FALSE;
+ while (pGetAce( sAcl, index++, (void **)&ace ))
+ {
+ if (ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE)
+ {
+ found = TRUE;
+ ok(ace->Header.AceFlags == 0, "Expected 0 as flags, got %x\n", ace->Header.AceFlags);
+ ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP,
+ "Expected SYSTEM_MANDATORY_LABEL_NO_WRITE_UP as flag, got %x\n", ace->Mask);
+ ok(EqualSid(&ace->SidStart, &low_level), "Expected low integrity level\n");
+ }
+ }
+ ok(found, "Could not find mandatory label\n");
+
+ HeapFree(GetProcessHeap(), 0, sd2);
+ CloseHandle(handle);
}
static void test_AdjustTokenPrivileges(void)
diff --git a/include/winnt.h b/include/winnt.h
index 392f77b217d..97d6295bdef 100644
--- a/include/winnt.h
+++ b/include/winnt.h
@@ -5282,6 +5282,7 @@ typedef struct _TAPE_GET_MEDIA_PARAMETERS {
#define GROUP_SECURITY_INFORMATION 0x00000002
#define DACL_SECURITY_INFORMATION 0x00000004
#define SACL_SECURITY_INFORMATION 0x00000008
+#define LABEL_SECURITY_INFORMATION 0x00000010
#define REG_OPTION_RESERVED 0x00000000
#define REG_OPTION_NON_VOLATILE 0x00000000
diff --git a/server/handle.c b/server/handle.c
index 391f4688b6a..3d5485fcdf9 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -710,6 +710,52 @@ DECL_HANDLER(set_security_object)
release_object( obj );
}
+/* extract security labels from SACL */
+static int extract_security_label( ACL **out, const ACL *sacl )
+{
+ const ACE_HEADER *ace;
+ ACE_HEADER *label_ace;
+ size_t size = sizeof(ACL);
+ int i, count = 0;
+ ACL *label_acl;
+
+ *out = NULL;
+ if (!sacl) return 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)
+ {
+ size += ace->AceSize;
+ count++;
+ }
+ }
+
+ label_acl = mem_alloc( size );
+ if (!label_acl) return 0;
+
+ 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 );
+ }
+ }
+
+ *out = label_acl;
+ return 1;
+}
+
DECL_HANDLER(get_security_object)
{
const struct security_descriptor *sd;
@@ -719,6 +765,7 @@ DECL_HANDLER(get_security_object)
int present;
const SID *owner, *group;
const ACL *sacl, *dacl;
+ ACL *label_acl = NULL;
if (req->security_info & SACL_SECURITY_INFORMATION)
access |= ACCESS_SYSTEM_SECURITY;
@@ -746,6 +793,12 @@ DECL_HANDLER(get_security_object)
sacl = sd_get_sacl( sd, &present );
if (req->security_info & SACL_SECURITY_INFORMATION && present)
req_sd.sacl_len = sd->sacl_len;
+ else if (req->security_info & LABEL_SECURITY_INFORMATION && present)
+ {
+ if (!extract_security_label( &label_acl, sacl )) goto error;
+ req_sd.sacl_len = label_acl ? label_acl->AclSize : 0;
+ sacl = label_acl;
+ }
else
req_sd.sacl_len = 0;
@@ -776,7 +829,9 @@ DECL_HANDLER(get_security_object)
set_error(STATUS_BUFFER_TOO_SMALL);
}
+error:
release_object( obj );
+ free( label_acl );
}
struct enum_handle_info
--
2.11.0

View File

@ -0,0 +1,329 @@
From 703cd39ce88d6b50c0ca7da3ba7533ac3ce91950 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Tue, 30 Aug 2016 01:15:44 +0200
Subject: server: Implement changing the label of a security descriptor.
---
dlls/advapi32/tests/security.c | 113 ++++++++++++++++++++++++++++++++++-
dlls/ntdll/sec.c | 3 +-
server/handle.c | 131 ++++++++++++++++++++++++++++++++++++++++-
3 files changed, 243 insertions(+), 4 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 877250c1ebf..84a451eb834 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -6434,6 +6434,8 @@ static void test_integrity(void)
{
static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
{SECURITY_MANDATORY_LOW_RID}};
+ static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
+ {SECURITY_MANDATORY_MEDIUM_RID}};
SYSTEM_MANDATORY_LABEL_ACE *ace;
char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
SECURITY_DESCRIPTOR *sd2, *sd = (SECURITY_DESCRIPTOR *)&buffer_sd;
@@ -6441,7 +6443,7 @@ static void test_integrity(void)
char buffer_acl[256];
ACL *pAcl = (ACL*)&buffer_acl;
ACL *sAcl;
- BOOL defaulted, present, ret, found;
+ BOOL defaulted, present, ret, found, found2;
HANDLE handle;
DWORD index, size;
@@ -6545,6 +6547,115 @@ static void test_integrity(void)
ok(found, "Could not find mandatory label\n");
HeapFree(GetProcessHeap(), 0, sd2);
+
+ ret = pAddMandatoryAce(pAcl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, &medium_level);
+ ok(ret, "AddMandatoryAce failed with %u\n", GetLastError());
+
+ ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd);
+ ok(ret, "GetKernelObjectSecurity failed %u\n", GetLastError());
+
+ ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "GetKernelObjectSecurity failed with %u\n", GetLastError());
+
+ sd2 = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed %u\n", GetLastError());
+
+ sAcl = (void *)0xdeadbeef;
+ present = FALSE;
+ defaulted = TRUE;
+ ret = GetSecurityDescriptorSacl(sd2, &present, &sAcl, &defaulted);
+ ok(ret, "GetSecurityDescriptorSacl failed with %u\n", GetLastError());
+ ok(present, "sAcl not present\n");
+ ok(sAcl != (void *)0xdeadbeef, "sAcl not set\n");
+ ok(sAcl->AceCount == 2, "Expected 2 ACEs, got %d\n", sAcl->AceCount);
+ ok(!defaulted, "sAcl defaulted\n");
+
+ index = 0;
+ found = found2 = FALSE;
+ while (pGetAce( sAcl, index++, (void **)&ace ))
+ {
+ if (ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE)
+ {
+ if (EqualSid(&ace->SidStart, &low_level))
+ {
+ found = TRUE;
+ ok(ace->Header.AceFlags == 0, "Expected 0 as flags, got %x\n", ace->Header.AceFlags);
+ ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP,
+ "Expected SYSTEM_MANDATORY_LABEL_NO_WRITE_UP as flag, got %x\n", ace->Mask);
+ }
+ if (EqualSid(&ace->SidStart, &medium_level))
+ {
+ found2 = TRUE;
+ ok(ace->Header.AceFlags == 0, "Expected 0 as flags, got %x\n", ace->Header.AceFlags);
+ ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP,
+ "Expected SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP as flag, got %x\n", ace->Mask);
+ }
+ }
+ }
+ ok(found, "Could not find low mandatory label\n");
+ ok(found2, "Could not find medium mandatory label\n");
+
+ HeapFree( GetProcessHeap(), 0, sd2);
+
+ ret = SetSecurityDescriptorSacl(sd, FALSE, NULL, FALSE);
+ ok(ret, "SetSecurityDescriptorSacl failed with %u\n", GetLastError());
+
+ ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd);
+ ok(ret, "GetKernelObjectSecurity failed %u\n", GetLastError());
+
+ ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "GetKernelObjectSecurity failed with %u\n", GetLastError());
+
+ sd2 = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed %u\n", GetLastError());
+
+ sAcl = (void *)0xdeadbeef;
+ present = FALSE;
+ defaulted = TRUE;
+ ret = GetSecurityDescriptorSacl(sd2, &present, &sAcl, &defaulted);
+ ok(ret, "GetSecurityDescriptorSacl failed with %u\n", GetLastError());
+ ok(present, "sAcl not present\n");
+ ok(sAcl != (void *)0xdeadbeef, "sAcl not set\n");
+ ok(sAcl->AceCount == 0, "Expected 0 ACEs, got %d\n", sAcl->AceCount);
+ ok(!defaulted, "sAcl defaulted\n");
+
+ HeapFree(GetProcessHeap(), 0, sd2);
+
+ ret = InitializeAcl(pAcl, 256, ACL_REVISION);
+ ok(ret, "InitializeAcl failed with %u\n", GetLastError());
+
+ ret = pAddMandatoryAce(pAcl, ACL_REVISION3, 0, SYSTEM_MANDATORY_LABEL_NO_EXECUTE_UP, &medium_level);
+ ok(ret, "AddMandatoryAce failed with %u\n", GetLastError());
+
+ ret = SetSecurityDescriptorSacl(sd, TRUE, pAcl, FALSE);
+ ok(ret, "SetSecurityDescriptorSacl failed with %u\n", GetLastError());
+
+ ret = SetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd);
+ ok(ret, "GetKernelObjectSecurity failed %u\n", GetLastError());
+
+ ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "GetKernelObjectSecurity failed with %u\n", GetLastError());
+
+ sd2 = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed %u\n", GetLastError());
+
+ sAcl = (void *)0xdeadbeef;
+ present = FALSE;
+ defaulted = TRUE;
+ ret = GetSecurityDescriptorSacl(sd2, &present, &sAcl, &defaulted);
+ ok(ret, "GetSecurityDescriptorSacl failed with %u\n", GetLastError());
+ ok(present, "sAcl not present\n");
+ ok(sAcl != (void *)0xdeadbeef, "sAcl not set\n");
+ ok(sAcl->AclRevision == ACL_REVISION3, "Expected revision 3, got %d\n", sAcl->AclRevision);
+ ok(!defaulted, "sAcl defaulted\n");
+
+ HeapFree(GetProcessHeap(), 0, sd2);
CloseHandle(handle);
}
diff --git a/dlls/ntdll/sec.c b/dlls/ntdll/sec.c
index f588545f322..5cf6c788ffb 100644
--- a/dlls/ntdll/sec.c
+++ b/dlls/ntdll/sec.c
@@ -1782,7 +1782,8 @@ NTSTATUS WINAPI NtSetSecurityObject(HANDLE Handle,
return STATUS_INVALID_SECURITY_DESCR;
}
- if (SecurityInformation & SACL_SECURITY_INFORMATION)
+ if (SecurityInformation & SACL_SECURITY_INFORMATION ||
+ SecurityInformation & LABEL_SECURITY_INFORMATION)
{
status = RtlGetSaclSecurityDescriptor( SecurityDescriptor, &present, &sacl, &defaulted );
if (status != STATUS_SUCCESS) return status;
diff --git a/server/handle.c b/server/handle.c
index 3d5485fcdf9..a0e27b9507e 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -683,12 +683,89 @@ DECL_HANDLER(get_object_info)
release_object( obj );
}
+/* merge security labels into an existing SACL */
+static int merge_security_labels( ACL **out, const ACL *old_sacl, const ACL *new_sacl )
+{
+ const ACE_HEADER *ace;
+ ACE_HEADER *merged_ace;
+ size_t size = sizeof(ACL);
+ int i, count = 0;
+ BYTE revision = ACL_REVISION;
+ ACL *merged_acl;
+
+ *out = NULL;
+ if (!old_sacl && !new_sacl) return 1;
+
+ if (old_sacl)
+ {
+ revision = max( revision, old_sacl->AclRevision );
+ ace = (const ACE_HEADER *)(old_sacl + 1);
+ for (i = 0; i < old_sacl->AceCount; i++, ace = ace_next( ace ))
+ {
+ if (ace->AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue;
+ size += ace->AceSize;
+ count++;
+ }
+ }
+
+ if (new_sacl)
+ {
+ revision = max( revision, new_sacl->AclRevision );
+ ace = (const ACE_HEADER *)(new_sacl + 1);
+ for (i = 0; i < new_sacl->AceCount; i++, ace = ace_next( ace ))
+ {
+ /* FIXME: Should this be handled as error? */
+ if (ace->AceType != SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue;
+ size += ace->AceSize;
+ count++;
+ }
+ }
+
+ merged_acl = mem_alloc( size );
+ if (!merged_acl) return 0;
+
+ merged_acl->AclRevision = revision;
+ merged_acl->Sbz1 = 0;
+ merged_acl->AclSize = size;
+ merged_acl->AceCount = count;
+ merged_acl->Sbz2 = 0;
+ merged_ace = (ACE_HEADER *)(merged_acl + 1);
+
+ if (old_sacl)
+ {
+ ace = (const ACE_HEADER *)(old_sacl + 1);
+ for (i = 0; i < old_sacl->AceCount; i++, ace = ace_next( ace ))
+ {
+ if (ace->AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue;
+ memcpy( merged_ace, ace, ace->AceSize );
+ merged_ace = (ACE_HEADER *)ace_next( merged_ace );
+ }
+ }
+
+ if (new_sacl)
+ {
+ ace = (const ACE_HEADER *)(new_sacl + 1);
+ for (i = 0; i < new_sacl->AceCount; i++, ace = ace_next( ace ))
+ {
+ if (ace->AceType != SYSTEM_MANDATORY_LABEL_ACE_TYPE) continue;
+ memcpy( merged_ace, ace, ace->AceSize );
+ merged_ace = (ACE_HEADER *)ace_next( merged_ace );
+ }
+ }
+
+ *out = merged_acl;
+ return 1;
+}
+
DECL_HANDLER(set_security_object)
{
data_size_t sd_size = get_req_data_size();
const struct security_descriptor *sd = get_req_data();
+ struct security_descriptor *merged_sd = NULL;
+ ACL *merged_sacl = NULL;
struct object *obj;
unsigned int access = 0;
+ unsigned int security_info = req->security_info;
if (!sd_is_valid( sd, sd_size ))
{
@@ -697,7 +774,8 @@ DECL_HANDLER(set_security_object)
}
if (req->security_info & OWNER_SECURITY_INFORMATION ||
- req->security_info & GROUP_SECURITY_INFORMATION)
+ req->security_info & GROUP_SECURITY_INFORMATION ||
+ req->security_info & LABEL_SECURITY_INFORMATION)
access |= WRITE_OWNER;
if (req->security_info & SACL_SECURITY_INFORMATION)
access |= ACCESS_SYSTEM_SECURITY;
@@ -706,8 +784,57 @@ DECL_HANDLER(set_security_object)
if (!(obj = get_handle_obj( current->process, req->handle, access, NULL ))) return;
- obj->ops->set_sd( obj, sd, req->security_info );
+ /* check if we need to merge the security labels with the existing SACLs */
+ if ((security_info & LABEL_SECURITY_INFORMATION) &&
+ !(security_info & SACL_SECURITY_INFORMATION) &&
+ (sd->control & SE_SACL_PRESENT))
+ {
+ const struct security_descriptor *old_sd;
+ const ACL *old_sacl = NULL;
+ int present;
+ char *ptr;
+
+ if ((old_sd = obj->ops->get_sd( obj )))
+ {
+ old_sacl = sd_get_sacl( old_sd, &present );
+ if (!present) old_sacl = NULL;
+ }
+
+ if (!merge_security_labels( &merged_sacl, old_sacl, sd_get_sacl( sd, &present ) )) goto error;
+
+ /* allocate a new SD and replace SACL with merged version */
+ merged_sd = mem_alloc( sizeof(*merged_sd) + sd->owner_len + sd->group_len +
+ (merged_sacl ? merged_sacl->AclSize : 0) + sd->dacl_len );
+ if (!merged_sd) goto error;
+
+ merged_sd->control = sd->control;
+ merged_sd->owner_len = sd->owner_len;
+ merged_sd->group_len = sd->group_len;
+ merged_sd->sacl_len = merged_sacl ? merged_sacl->AclSize : 0;
+ merged_sd->dacl_len = sd->dacl_len;
+
+ ptr = (char *)(merged_sd + 1);
+ memcpy( ptr, sd_get_owner( sd ), sd->owner_len );
+ ptr += sd->owner_len;
+ memcpy( ptr, sd_get_group( sd ), sd->group_len );
+ ptr += sd->group_len;
+ if (merged_sacl)
+ {
+ memcpy( ptr, merged_sacl, merged_sacl->AclSize );
+ ptr += merged_sacl->AclSize;
+ }
+ memcpy( ptr, sd_get_dacl( sd, &present ), sd->dacl_len );
+
+ security_info |= SACL_SECURITY_INFORMATION;
+ sd = merged_sd;
+ }
+
+ obj->ops->set_sd( obj, sd, security_info );
+
+error:
release_object( obj );
+ free( merged_sacl );
+ free( merged_sd );
}
/* extract security labels from SACL */
--
2.11.0

View File

@ -0,0 +1,102 @@
From 048c4e74b36eacac239ab61997f756ed956ab7f2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Tue, 30 Aug 2016 02:10:32 +0200
Subject: server: Do not set SE_{D,S}ACL_PRESENT if no {D,S}ACL was set.
---
dlls/advapi32/tests/security.c | 6 +++---
server/handle.c | 2 --
server/object.c | 15 +++++++++++++--
3 files changed, 16 insertions(+), 7 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 84a451eb834..263d2f11544 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -6476,9 +6476,9 @@ static void test_integrity(void)
defaulted = TRUE;
ret = GetSecurityDescriptorSacl(sd2, &present, &sAcl, &defaulted);
ok(ret, "GetSecurityDescriptorSacl failed with %u\n", GetLastError());
- todo_wine ok(!present, "sAcl is present\n");
- todo_wine ok(sAcl == (void *)0xdeadbeef, "sAcl is set\n");
- ok(!defaulted, "sAcl defaulted\n");
+ ok(!present, "sAcl is present\n");
+ ok(sAcl == (void *)0xdeadbeef, "sAcl is set\n");
+ todo_wine ok(!defaulted, "sAcl defaulted\n");
HeapFree(GetProcessHeap(), 0, sd2);
CloseHandle(handle);
diff --git a/server/handle.c b/server/handle.c
index a0e27b9507e..57e0c060e03 100644
--- a/server/handle.c
+++ b/server/handle.c
@@ -916,7 +916,6 @@ DECL_HANDLER(get_security_object)
else
req_sd.group_len = 0;
- req_sd.control |= SE_SACL_PRESENT;
sacl = sd_get_sacl( sd, &present );
if (req->security_info & SACL_SECURITY_INFORMATION && present)
req_sd.sacl_len = sd->sacl_len;
@@ -929,7 +928,6 @@ DECL_HANDLER(get_security_object)
else
req_sd.sacl_len = 0;
- req_sd.control |= SE_DACL_PRESENT;
dacl = sd_get_dacl( sd, &present );
if (req->security_info & DACL_SECURITY_INFORMATION && present)
req_sd.dacl_len = sd->dacl_len;
diff --git a/server/object.c b/server/object.c
index b4af10e811c..703875db248 100644
--- a/server/object.c
+++ b/server/object.c
@@ -573,33 +573,44 @@ struct security_descriptor *set_sd_from_token_internal( const struct security_de
}
else new_sd.group_len = 0;
- new_sd.control |= SE_SACL_PRESENT;
sacl = sd_get_sacl( sd, &present );
if (set_info & SACL_SECURITY_INFORMATION && present)
+ {
+ new_sd.control |= SE_SACL_PRESENT;
new_sd.sacl_len = sd->sacl_len;
+ }
else
{
if (old_sd) sacl = sd_get_sacl( old_sd, &present );
if (old_sd && present)
+ {
+ new_sd.control |= SE_SACL_PRESENT;
new_sd.sacl_len = old_sd->sacl_len;
+ }
else
new_sd.sacl_len = 0;
}
- new_sd.control |= SE_DACL_PRESENT;
dacl = sd_get_dacl( sd, &present );
if (set_info & DACL_SECURITY_INFORMATION && present)
+ {
+ new_sd.control |= SE_DACL_PRESENT;
new_sd.dacl_len = sd->dacl_len;
+ }
else
{
if (old_sd) dacl = sd_get_dacl( old_sd, &present );
if (old_sd && present)
+ {
+ new_sd.control |= SE_DACL_PRESENT;
new_sd.dacl_len = old_sd->dacl_len;
+ }
else if (token)
{
dacl = token_get_default_dacl( token );
+ new_sd.control |= SE_DACL_PRESENT;
new_sd.dacl_len = dacl->AclSize;
}
else new_sd.dacl_len = 0;
--
2.11.0

View File

@ -0,0 +1,147 @@
From 402dca4fe8a333c8d76035c6b81c549be07882c8 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 12 Jan 2017 05:23:57 +0100
Subject: server: Implement setting a security descriptor when duplicating
tokens.
---
dlls/ntdll/nt.c | 7 ++++++-
server/process.c | 2 +-
server/protocol.def | 2 +-
server/security.h | 2 +-
server/token.c | 20 +++++++++++++++++---
5 files changed, 26 insertions(+), 7 deletions(-)
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c
index 9347170a593..cc5c653d23e 100644
--- a/dlls/ntdll/nt.c
+++ b/dlls/ntdll/nt.c
@@ -87,11 +87,15 @@ NTSTATUS WINAPI NtDuplicateToken(
OUT PHANDLE NewToken)
{
NTSTATUS status;
+ data_size_t len;
+ struct object_attributes *objattr;
TRACE("(%p,0x%08x,%s,0x%08x,0x%08x,%p)\n",
ExistingToken, DesiredAccess, debugstr_ObjectAttributes(ObjectAttributes),
ImpersonationLevel, TokenType, NewToken);
+ if ((status = alloc_object_attributes( ObjectAttributes, &objattr, &len ))) return status;
+
if (ObjectAttributes && ObjectAttributes->SecurityQualityOfService)
{
SECURITY_QUALITY_OF_SERVICE *SecurityQOS = ObjectAttributes->SecurityQualityOfService;
@@ -106,14 +110,15 @@ NTSTATUS WINAPI NtDuplicateToken(
{
req->handle = wine_server_obj_handle( ExistingToken );
req->access = DesiredAccess;
- req->attributes = ObjectAttributes ? ObjectAttributes->Attributes : 0;
req->primary = (TokenType == TokenPrimary);
req->impersonation_level = ImpersonationLevel;
+ wine_server_add_data( req, objattr, len );
status = wine_server_call( req );
if (!status) *NewToken = wine_server_ptr_handle( reply->new_handle );
}
SERVER_END_REQ;
+ RtlFreeHeap( GetProcessHeap(), 0, objattr );
return status;
}
diff --git a/server/process.c b/server/process.c
index ca5982fe061..f476cfaf0fe 100644
--- a/server/process.c
+++ b/server/process.c
@@ -569,7 +569,7 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit
: alloc_handle_table( process, 0 );
/* Note: for security reasons, starting a new process does not attempt
* to use the current impersonation token for the new process */
- process->token = token_duplicate( parent->token, TRUE, 0 );
+ process->token = token_duplicate( parent->token, TRUE, 0, NULL );
process->affinity = parent->affinity;
}
if (!process->handles || !process->token) goto error;
diff --git a/server/protocol.def b/server/protocol.def
index 97cf5adf298..3da579650fa 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3361,9 +3361,9 @@ enum caret_state
@REQ(duplicate_token)
obj_handle_t handle; /* handle to the token to duplicate */
unsigned int access; /* access rights to the new token */
- unsigned int attributes; /* object attributes */
int primary; /* is the new token to be a primary one? */
int impersonation_level; /* impersonation level of the new token */
+ VARARG(objattr,object_attributes); /* object attributes */
@REPLY
obj_handle_t new_handle; /* duplicated handle */
@END
diff --git a/server/security.h b/server/security.h
index bdb7d42f09d..0342f643187 100644
--- a/server/security.h
+++ b/server/security.h
@@ -54,7 +54,7 @@ extern const PSID security_domain_users_sid;
extern struct token *token_create_admin(void);
extern struct token *token_duplicate( struct token *src_token, unsigned primary,
- int impersonation_level );
+ int impersonation_level, const struct security_descriptor *sd );
extern int token_check_privileges( struct token *token, int all_required,
const LUID_AND_ATTRIBUTES *reqprivs,
unsigned int count, LUID_AND_ATTRIBUTES *usedprivs);
diff --git a/server/token.c b/server/token.c
index b903420bbe3..74a97bb1319 100644
--- a/server/token.c
+++ b/server/token.c
@@ -521,7 +521,7 @@ static struct token *create_token( unsigned primary, const SID *user,
}
struct token *token_duplicate( struct token *src_token, unsigned primary,
- int impersonation_level )
+ int impersonation_level, const struct security_descriptor *sd )
{
const luid_t *modified_id =
primary || (impersonation_level == src_token->impersonation_level) ?
@@ -571,6 +571,15 @@ struct token *token_duplicate( struct token *src_token, unsigned primary,
return NULL;
}
+ if (sd)
+ {
+ default_set_sd( &token->obj, sd,
+ OWNER_SECURITY_INFORMATION |
+ GROUP_SECURITY_INFORMATION |
+ DACL_SECURITY_INFORMATION |
+ SACL_SECURITY_INFORMATION );
+ }
+
return token;
}
@@ -1141,15 +1150,20 @@ DECL_HANDLER(get_token_privileges)
DECL_HANDLER(duplicate_token)
{
struct token *src_token;
+ struct unicode_str name;
+ const struct security_descriptor *sd;
+ const struct object_attributes *objattr = get_req_object_attributes( &sd, &name, NULL );
+
+ if (!objattr) return;
if ((src_token = (struct token *)get_handle_obj( current->process, req->handle,
TOKEN_DUPLICATE,
&token_ops )))
{
- struct token *token = token_duplicate( src_token, req->primary, req->impersonation_level );
+ struct token *token = token_duplicate( src_token, req->primary, req->impersonation_level, sd );
if (token)
{
- reply->new_handle = alloc_handle( current->process, token, req->access, req->attributes);
+ reply->new_handle = alloc_handle_no_access_check( current->process, token, req->access, objattr->attributes );
release_object( token );
}
release_object( src_token );
--
2.11.0

View File

@ -0,0 +1,129 @@
From 5ee9eaecad03eda9e6eb45abc23ce20f49f17c13 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 12 Jan 2017 05:28:30 +0100
Subject: advapi32/tests: Add basic tests for token security descriptors.
---
dlls/advapi32/tests/security.c | 87 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 86 insertions(+), 1 deletion(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 263d2f11544..8af1d0604a4 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -217,6 +217,7 @@ static void init(void)
pGetWindowsAccountDomainSid = (void *)GetProcAddress(hmod, "GetWindowsAccountDomainSid");
pGetSidIdentifierAuthority = (void *)GetProcAddress(hmod, "GetSidIdentifierAuthority");
pGetExplicitEntriesFromAclW = (void *)GetProcAddress(hmod, "GetExplicitEntriesFromAclW");
+ pDuplicateTokenEx = (void *)GetProcAddress(hmod, "DuplicateTokenEx");
myARGC = winetest_get_mainargs( &myARGV );
}
@@ -3117,7 +3118,6 @@ static void test_impersonation_level(void)
HKEY hkey;
DWORD error;
- pDuplicateTokenEx = (void *)GetProcAddress(hmod, "DuplicateTokenEx");
if( !pDuplicateTokenEx ) {
win_skip("DuplicateTokenEx is not available\n");
return;
@@ -7136,6 +7136,90 @@ static void test_GetExplicitEntriesFromAclW(void)
HeapFree(GetProcessHeap(), 0, old_acl);
}
+static void test_token_security_descriptor(void)
+{
+ ACCESS_ALLOWED_ACE *ace;
+ char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
+ SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&buffer_sd, *sd2;
+ char buffer_acl[256];
+ ACL *pAcl = (ACL *)&buffer_acl, *pAcl2;
+ BOOL defaulted, present, ret, found;
+ HANDLE token, token2;
+ SECURITY_ATTRIBUTES sa;
+ DWORD size, index;
+ PSID psid;
+
+ if (!pDuplicateTokenEx || !pConvertStringSidToSidA || !pAddAccessAllowedAceEx || !pGetAce || !pSetEntriesInAclW)
+ {
+ win_skip("Some functions not available\n");
+ return;
+ }
+
+ /* Test whether we can create tokens with security descriptors */
+ ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token);
+ ok(ret, "OpenProcessToken failed with error %u\n", GetLastError());
+
+ ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
+ ok(ret, "InitializeSecurityDescriptor failed with %u\n", GetLastError());
+
+ ret = InitializeAcl(pAcl, 256, ACL_REVISION);
+ ok(ret, "InitializeAcl failed with %u\n", GetLastError());
+
+ ret = pConvertStringSidToSidA("S-1-5-6", &psid);
+ ok(ret, "ConvertStringSidToSidA failed with %u\n", GetLastError());
+
+ ret = pAddAccessAllowedAceEx(pAcl, ACL_REVISION, NO_PROPAGATE_INHERIT_ACE, GENERIC_ALL, psid);
+ ok(ret, "AddAccessAllowedAceEx failed with %u\n", GetLastError());
+
+ ret = SetSecurityDescriptorDacl(sd, TRUE, pAcl, FALSE);
+ ok(ret, "SetSecurityDescriptorDacl failed with %u\n", GetLastError());
+
+ sa.nLength = sizeof(SECURITY_ATTRIBUTES);
+ sa.lpSecurityDescriptor = sd;
+ sa.bInheritHandle = FALSE;
+
+ ret = pDuplicateTokenEx(token, MAXIMUM_ALLOWED, &sa, SecurityImpersonation, TokenImpersonation, &token2);
+ ok(ret, "DuplicateTokenEx failed with %u\n", GetLastError());
+
+ ret = GetKernelObjectSecurity(token2, DACL_SECURITY_INFORMATION, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "GetKernelObjectSecurity failed with %u\n", GetLastError());
+
+ sd2 = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetKernelObjectSecurity(token2, DACL_SECURITY_INFORMATION, sd2, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed %u\n", GetLastError());
+
+ pAcl2 = (void *)0xdeadbeef;
+ present = FALSE;
+ defaulted = TRUE;
+ ret = GetSecurityDescriptorDacl(sd2, &present, &pAcl2, &defaulted);
+ ok(ret, "GetSecurityDescriptorDacl failed with %u\n", GetLastError());
+ ok(present, "pAcl2 not present\n");
+ ok(pAcl2 != (void *)0xdeadbeef, "pAcl2 not set\n");
+ ok(pAcl2->AceCount == 1, "Expected 1 ACEs, got %d\n", pAcl2->AceCount);
+ ok(!defaulted, "pAcl2 defaulted\n");
+
+ index = 0;
+ found = FALSE;
+ while (pGetAce( pAcl2, index++, (void **)&ace ))
+ {
+ if (ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE && EqualSid(&ace->SidStart, psid))
+ {
+ found = TRUE;
+ ok(ace->Header.AceFlags == NO_PROPAGATE_INHERIT_ACE,
+ "Expected NO_PROPAGATE_INHERIT_ACE as flags, got %x\n", ace->Header.AceFlags);
+ }
+ }
+ ok(found, "Could not find access allowed ace\n");
+
+ HeapFree( GetProcessHeap(), 0, sd2);
+
+ LocalFree(psid);
+
+ CloseHandle(token2);
+ CloseHandle(token);
+}
+
START_TEST(security)
{
init();
@@ -7185,4 +7269,5 @@ START_TEST(security)
test_GetSidIdentifierAuthority();
test_pseudo_tokens();
test_GetExplicitEntriesFromAclW();
+ test_token_security_descriptor();
}
--
2.11.0

View File

@ -0,0 +1,75 @@
From a4cefc05b12f5461daf5dcaaeaa144dc15db8b39 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 12 Jan 2017 05:31:31 +0100
Subject: advapi32/tests: Show that tokens do not inherit security descriptors
during duplication.
---
dlls/advapi32/tests/security.c | 42 +++++++++++++++++++++++++++++++++++++++++-
1 file changed, 41 insertions(+), 1 deletion(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 8af1d0604a4..a2d0538b491 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -7144,7 +7144,7 @@ static void test_token_security_descriptor(void)
char buffer_acl[256];
ACL *pAcl = (ACL *)&buffer_acl, *pAcl2;
BOOL defaulted, present, ret, found;
- HANDLE token, token2;
+ HANDLE token, token2, token3;
SECURITY_ATTRIBUTES sa;
DWORD size, index;
PSID psid;
@@ -7214,8 +7214,48 @@ static void test_token_security_descriptor(void)
HeapFree( GetProcessHeap(), 0, sd2);
+ /* Duplicate token without security attributes.
+ * Tokens do not inherit the security descriptor when calling DuplicateToken,
+ * see https://blogs.msdn.microsoft.com/oldnewthing/20160512-00/?p=93447
+ */
+ ret = pDuplicateTokenEx(token2, MAXIMUM_ALLOWED, NULL, SecurityImpersonation, TokenImpersonation, &token3);
+ ok(ret, "DuplicateTokenEx failed with %u\n", GetLastError());
+
+ ret = GetKernelObjectSecurity(token3, DACL_SECURITY_INFORMATION, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "GetKernelObjectSecurity failed with %u\n", GetLastError());
+
+ sd2 = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetKernelObjectSecurity(token3, DACL_SECURITY_INFORMATION, sd2, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed %u\n", GetLastError());
+
+ pAcl2 = (void *)0xdeadbeef;
+ present = FALSE;
+ defaulted = TRUE;
+ ret = GetSecurityDescriptorDacl(sd2, &present, &pAcl2, &defaulted);
+ ok(ret, "GetSecurityDescriptorDacl failed with %u\n", GetLastError());
+ todo_wine
+ ok(present, "pAcl2 not present\n");
+ ok(pAcl2 != (void *)0xdeadbeef, "pAcl2 not set\n");
+ ok(!defaulted, "pAcl2 defaulted\n");
+
+ if (pAcl2)
+ {
+ index = 0;
+ found = FALSE;
+ while (pGetAce( pAcl2, index++, (void **)&ace ))
+ {
+ if (ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE && EqualSid(&ace->SidStart, psid))
+ found = TRUE;
+ }
+ ok(!found, "Access allowed ace got inherited!\n");
+ }
+
+ HeapFree(GetProcessHeap(), 0, sd2);
+
LocalFree(psid);
+ CloseHandle(token3);
CloseHandle(token2);
CloseHandle(token);
}
--
2.11.0

View File

@ -0,0 +1,187 @@
From df7287c73f6031de82dc674ea6338037537f0012 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 12 Jan 2017 05:37:42 +0100
Subject: advapi32/tests: Show that tokens do not inherit dacls while creating
child processes.
---
dlls/advapi32/tests/security.c | 133 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 129 insertions(+), 4 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index a2d0538b491..05b0c73edd6 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -7141,12 +7141,15 @@ static void test_token_security_descriptor(void)
ACCESS_ALLOWED_ACE *ace;
char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&buffer_sd, *sd2;
- char buffer_acl[256];
- ACL *pAcl = (ACL *)&buffer_acl, *pAcl2;
+ char buffer_acl[256], buffer[MAX_PATH];
+ ACL *pAcl = (ACL *)&buffer_acl, *pAcl2, *pAclChild;
BOOL defaulted, present, ret, found;
HANDLE token, token2, token3;
+ EXPLICIT_ACCESSW exp_access;
+ PROCESS_INFORMATION info;
SECURITY_ATTRIBUTES sa;
- DWORD size, index;
+ DWORD size, index, retd;
+ STARTUPINFOA startup;
PSID psid;
if (!pDuplicateTokenEx || !pConvertStringSidToSidA || !pAddAccessAllowedAceEx || !pGetAce || !pSetEntriesInAclW)
@@ -7253,6 +7256,76 @@ static void test_token_security_descriptor(void)
HeapFree(GetProcessHeap(), 0, sd2);
+ /* When creating a child process, the process does only inherit the
+ * Token of the parent, but not the DACL of the token.
+ */
+ ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "GetKernelObjectSecurity failed with %u\n", GetLastError());
+
+ sd2 = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd2, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed %u\n", GetLastError());
+
+ pAcl2 = (void *)0xdeadbeef;
+ present = FALSE;
+ defaulted = TRUE;
+ ret = GetSecurityDescriptorDacl(sd2, &present, &pAcl2, &defaulted);
+ ok(ret, "GetSecurityDescriptorDacl failed with %u\n", GetLastError());
+ todo_wine
+ ok(present, "pAcl2 not present\n");
+ ok(pAcl2 != (void *)0xdeadbeef, "pAcl2 not set\n");
+ ok(!defaulted, "pAcl2 defaulted\n");
+
+ /* check that the ace we add for testing does not already exist! */
+ if (pAcl2)
+ {
+ index = 0;
+ found = FALSE;
+ while (pGetAce( pAcl2, index++, (void **)&ace ))
+ {
+ if (ace->Header.AceType == ACCESS_ALLOWED_ACE_TYPE && EqualSid(&ace->SidStart, psid))
+ found = TRUE;
+ }
+ ok(!found, "Test ace does already exist!\n");
+ }
+
+ exp_access.grfAccessPermissions = GENERIC_ALL;
+ exp_access.grfAccessMode = GRANT_ACCESS;
+ exp_access.grfInheritance = NO_PROPAGATE_INHERIT_ACE;
+ exp_access.Trustee.pMultipleTrustee = NULL;
+ exp_access.Trustee.TrusteeForm = TRUSTEE_IS_SID;
+ exp_access.Trustee.MultipleTrusteeOperation = NO_MULTIPLE_TRUSTEE;
+ exp_access.Trustee.TrusteeType = TRUSTEE_IS_WELL_KNOWN_GROUP;
+ exp_access.Trustee.ptstrName = (void*)psid;
+
+ retd = pSetEntriesInAclW(1, &exp_access, pAcl2, &pAclChild);
+ ok(retd == ERROR_SUCCESS, "Expected ERROR_SUCCESS, got %u\n", retd);
+
+ memset(sd, 0, sizeof(buffer_sd));
+ ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
+ ok(ret, "InitializeSecurityDescriptor failed with %u\n", GetLastError());
+
+ ret = SetSecurityDescriptorDacl(sd, TRUE, pAclChild, FALSE);
+ ok(ret, "SetSecurityDescriptorDacl failed with %u\n", GetLastError());
+
+ ret = SetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd);
+ ok(ret, "SetKernelObjectSecurity failed with %u\n", GetLastError());
+
+ /* start child process with our modified token */
+ memset(&startup, 0, sizeof(startup));
+ startup.cb = sizeof(startup);
+ startup.dwFlags = STARTF_USESHOWWINDOW;
+ startup.wShowWindow = SW_SHOWNORMAL;
+
+ sprintf(buffer, "%s tests/security.c test_token_sd", myARGV[0]);
+ ret = CreateProcessA(NULL, buffer, NULL, NULL, FALSE, 0, NULL, NULL, &startup, &info);
+ ok(ret, "CreateProcess failed with error %u\n", GetLastError());
+ winetest_wait_child_process(info.hProcess);
+ CloseHandle(info.hProcess);
+ CloseHandle(info.hThread);
+
+ LocalFree(pAclChild);
LocalFree(psid);
CloseHandle(token3);
@@ -7260,6 +7333,53 @@ static void test_token_security_descriptor(void)
CloseHandle(token);
}
+static void test_child_token_sd(void)
+{
+ BOOL ret, present, defaulted, found;
+ ACCESS_ALLOWED_ACE *ace_acc;
+ SECURITY_DESCRIPTOR *sd;
+ DWORD size, index;
+ HANDLE token;
+ ACL *pAcl;
+ PSID psid;
+
+ ret = pConvertStringSidToSidA("S-1-5-6", &psid);
+ ok(ret, "ConvertStringSidToSidA failed with %u\n", GetLastError());
+
+ ret = OpenProcessToken(GetCurrentProcess(), MAXIMUM_ALLOWED, &token);
+ ok(ret, "OpenProcessToken failed with error %u\n", GetLastError());
+
+ ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "GetKernelObjectSecurity failed with %u\n", GetLastError());
+
+ sd = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed %u\n", GetLastError());
+
+ pAcl = NULL;
+ present = FALSE;
+ defaulted = TRUE;
+ ret = GetSecurityDescriptorDacl(sd, &present, &pAcl, &defaulted);
+ ok(ret, "GetSecurityDescriptorSacl failed with %u\n", GetLastError());
+
+ index = 0;
+ found = FALSE;
+ if (present && pAcl)
+ {
+ ok(pAcl->AceCount > 0, "Expected at least one ACE\n");
+ while (pGetAce( pAcl, index++, (void **)&ace_acc ))
+ {
+ if (ace_acc->Header.AceType == ACCESS_ALLOWED_ACE_TYPE && EqualSid(&ace_acc->SidStart, psid))
+ found = TRUE;
+ }
+ }
+ ok(!found, "The ACE should not haven been inherited from the parent\n");
+
+ LocalFree(psid);
+ HeapFree(GetProcessHeap(), 0, sd);
+}
+
START_TEST(security)
{
init();
@@ -7267,7 +7387,10 @@ START_TEST(security)
if (myARGC >= 3)
{
- test_process_security_child();
+ if (!strcmp(myARGV[2], "test_token_sd"))
+ test_child_token_sd();
+ else
+ test_process_security_child();
return;
}
test_kernel_objects_security();
@@ -7309,5 +7432,7 @@ START_TEST(security)
test_GetSidIdentifierAuthority();
test_pseudo_tokens();
test_GetExplicitEntriesFromAclW();
+
+ /* must be the last test, modifies process token */
test_token_security_descriptor();
}
--
2.11.0

View File

@ -0,0 +1,106 @@
From cbb1140c5de91c1e82414729b72918fb1a9ffd90 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 12 Jan 2017 05:45:33 +0100
Subject: advapi32/tests: Show that tokens do not inherit sacls / mandatory
labels while creating child processes.
---
dlls/advapi32/tests/security.c | 61 ++++++++++++++++++++++++++++++++++++++++++
1 file changed, 61 insertions(+)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 05b0c73edd6..8f0cff78695 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -7138,6 +7138,8 @@ static void test_GetExplicitEntriesFromAclW(void)
static void test_token_security_descriptor(void)
{
+ static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
+ {SECURITY_MANDATORY_LOW_RID}};
ACCESS_ALLOWED_ACE *ace;
char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
SECURITY_DESCRIPTOR *sd = (SECURITY_DESCRIPTOR *)&buffer_sd, *sd2;
@@ -7312,6 +7314,28 @@ static void test_token_security_descriptor(void)
ret = SetKernelObjectSecurity(token, DACL_SECURITY_INFORMATION, sd);
ok(ret, "SetKernelObjectSecurity failed with %u\n", GetLastError());
+ /* The security label is also not inherited */
+ if (pAddMandatoryAce)
+ {
+ ret = InitializeAcl(pAcl, 256, ACL_REVISION);
+ ok(ret, "InitializeAcl failed with %u\n", GetLastError());
+
+ ret = pAddMandatoryAce(pAcl, ACL_REVISION, 0, SYSTEM_MANDATORY_LABEL_NO_WRITE_UP, &low_level);
+ ok(ret, "AddMandatoryAce failed with %u\n", GetLastError());
+
+ memset(sd, 0, sizeof(buffer_sd));
+ ret = InitializeSecurityDescriptor(sd, SECURITY_DESCRIPTOR_REVISION);
+ ok(ret, "InitializeSecurityDescriptor failed with %u\n", GetLastError());
+
+ ret = SetSecurityDescriptorSacl(sd, TRUE, pAcl, FALSE);
+ ok(ret, "SetSecurityDescriptorSacl failed with %u\n", GetLastError());
+
+ ret = SetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd);
+ ok(ret, "SetKernelObjectSecurity failed with %u\n", GetLastError());
+ }
+ else
+ win_skip("SYSTEM_MANDATORY_LABEL not supported\n");
+
/* start child process with our modified token */
memset(&startup, 0, sizeof(startup));
startup.cb = sizeof(startup);
@@ -7335,6 +7359,9 @@ static void test_token_security_descriptor(void)
static void test_child_token_sd(void)
{
+ static SID low_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
+ {SECURITY_MANDATORY_LOW_RID}};
+ SYSTEM_MANDATORY_LABEL_ACE *ace_label;
BOOL ret, present, defaulted, found;
ACCESS_ALLOWED_ACE *ace_acc;
SECURITY_DESCRIPTOR *sd;
@@ -7378,6 +7405,40 @@ static void test_child_token_sd(void)
LocalFree(psid);
HeapFree(GetProcessHeap(), 0, sd);
+
+ if (!pAddMandatoryAce)
+ {
+ win_skip("SYSTEM_MANDATORY_LABEL not supported\n");
+ return;
+ }
+
+ ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "GetKernelObjectSecurity failed with %u\n", GetLastError());
+
+ sd = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetKernelObjectSecurity(token, LABEL_SECURITY_INFORMATION, sd, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed %u\n", GetLastError());
+
+ pAcl = NULL;
+ present = FALSE;
+ defaulted = TRUE;
+ ret = GetSecurityDescriptorSacl(sd, &present, &pAcl, &defaulted);
+ ok(ret, "GetSecurityDescriptorSacl failed with %u\n", GetLastError());
+
+ index = 0;
+ found = FALSE;
+ if (present && pAcl)
+ {
+ while (pGetAce( pAcl, index++, (void **)&ace_label ))
+ {
+ if (ace_label->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE && EqualSid(&ace_label->SidStart, &low_level))
+ found = TRUE;
+ }
+ }
+ ok(!found, "Low integrity level should not have been inherited\n");
+
+ HeapFree(GetProcessHeap(), 0, sd);
}
START_TEST(security)
--
2.11.0

View File

@ -0,0 +1,196 @@
From 43ddf2395d512c436fb8912c81d8596f6a16aaab Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Thu, 12 Jan 2017 05:58:02 +0100
Subject: server: Assign a default label (high) to all tokens.
---
dlls/advapi32/tests/security.c | 42 ++++++++++++++++++++++++++++++++-
server/process.c | 7 ++++++
server/security.h | 2 ++
server/token.c | 53 ++++++++++++++++++++++++++++++++++++++++++
4 files changed, 103 insertions(+), 1 deletion(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 8f0cff78695..44321553226 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -6436,6 +6436,8 @@ static void test_integrity(void)
{SECURITY_MANDATORY_LOW_RID}};
static SID medium_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
{SECURITY_MANDATORY_MEDIUM_RID}};
+ static SID high_level = {SID_REVISION, 1, {SECURITY_MANDATORY_LABEL_AUTHORITY},
+ {SECURITY_MANDATORY_HIGH_RID}};
SYSTEM_MANDATORY_LABEL_ACE *ace;
char buffer_sd[SECURITY_DESCRIPTOR_MIN_LENGTH];
SECURITY_DESCRIPTOR *sd2, *sd = (SECURITY_DESCRIPTOR *)&buffer_sd;
@@ -6657,6 +6659,45 @@ static void test_integrity(void)
HeapFree(GetProcessHeap(), 0, sd2);
CloseHandle(handle);
+
+ ret = OpenProcessToken(GetCurrentProcess(), READ_CONTROL, &handle);
+ ok(ret, "got %d with %d (expected TRUE)\n", ret, GetLastError());
+
+ ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, NULL, 0, &size);
+ ok(!ret && GetLastError() == ERROR_INSUFFICIENT_BUFFER,
+ "GetKernelObjectSecurity failed with %u\n", GetLastError());
+
+ sd2 = HeapAlloc(GetProcessHeap(), 0, size);
+ ret = GetKernelObjectSecurity(handle, LABEL_SECURITY_INFORMATION, sd2, size, &size);
+ ok(ret, "GetKernelObjectSecurity failed %u\n", GetLastError());
+
+ sAcl = (void *)0xdeadbeef;
+ present = FALSE;
+ defaulted = TRUE;
+ ret = GetSecurityDescriptorSacl(sd2, &present, &sAcl, &defaulted);
+ ok(ret, "GetSecurityDescriptorSacl failed with %u\n", GetLastError());
+ ok(present, "sAcl not present\n");
+ ok(sAcl != (void *)0xdeadbeef, "sAcl not set\n");
+ ok(sAcl->AceCount == 1, "Expected 1 ACEs, got %d\n", sAcl->AceCount);
+ ok(!defaulted, "sAcl defaulted\n");
+
+ index = 0;
+ found = FALSE;
+ while (pGetAce( sAcl, index++, (void **)&ace ))
+ {
+ if (ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE &&
+ (EqualSid(&ace->SidStart, &medium_level) || EqualSid(&ace->SidStart, &high_level)))
+ {
+ found = TRUE;
+ ok(ace->Header.AceFlags == 0, "Expected 0 as flags, got %x\n", ace->Header.AceFlags);
+ ok(ace->Mask == SYSTEM_MANDATORY_LABEL_NO_WRITE_UP,
+ "Expected SYSTEM_MANDATORY_LABEL_NO_WRITE_UP as flag, got %x\n", ace->Mask);
+ }
+ }
+ ok(found, "Could not find medium/high mandatory label\n");
+
+ HeapFree(GetProcessHeap(), 0, sd2);
+ CloseHandle(handle);
}
static void test_AdjustTokenPrivileges(void)
@@ -7274,7 +7315,6 @@ static void test_token_security_descriptor(void)
defaulted = TRUE;
ret = GetSecurityDescriptorDacl(sd2, &present, &pAcl2, &defaulted);
ok(ret, "GetSecurityDescriptorDacl failed with %u\n", GetLastError());
- todo_wine
ok(present, "pAcl2 not present\n");
ok(pAcl2 != (void *)0xdeadbeef, "pAcl2 not set\n");
ok(!defaulted, "pAcl2 defaulted\n");
diff --git a/server/process.c b/server/process.c
index f476cfaf0fe..eaf61eaea99 100644
--- a/server/process.c
+++ b/server/process.c
@@ -574,6 +574,13 @@ struct thread *create_process( int fd, struct thread *parent_thread, int inherit
}
if (!process->handles || !process->token) goto error;
+ /* Assign high security label to token. The default would be medium, but wine provides
+ * admin access to all applications, so high makes more sense. For further information:
+ * "Default integrity level" at https://msdn.microsoft.com/en-us/library/bb625963.aspx
+ */
+ if (!token_assign_label( process->token, security_high_label_sid ))
+ goto error;
+
/* create the main thread */
if (pipe( request_pipe ) == -1)
{
diff --git a/server/security.h b/server/security.h
index 0342f643187..ee927f91a3d 100644
--- a/server/security.h
+++ b/server/security.h
@@ -48,11 +48,13 @@ extern const PSID security_local_system_sid;
extern const PSID security_builtin_users_sid;
extern const PSID security_builtin_admins_sid;
extern const PSID security_domain_users_sid;
+extern const PSID security_high_label_sid;
/* token functions */
extern struct token *token_create_admin(void);
+extern int token_assign_label( struct token *token, PSID label );
extern struct token *token_duplicate( struct token *src_token, unsigned primary,
int impersonation_level, const struct security_descriptor *sd );
extern int token_check_privileges( struct token *token, int all_required,
diff --git a/server/token.c b/server/token.c
index 74a97bb1319..99a62de0ffa 100644
--- a/server/token.c
+++ b/server/token.c
@@ -70,6 +70,7 @@ static const SID interactive_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY },
static const SID anonymous_logon_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_ANONYMOUS_LOGON_RID } };
static const SID authenticated_user_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_AUTHENTICATED_USER_RID } };
static const SID local_system_sid = { SID_REVISION, 1, { SECURITY_NT_AUTHORITY }, { SECURITY_LOCAL_SYSTEM_RID } };
+static const SID high_label_sid = { SID_REVISION, 1, { SECURITY_MANDATORY_LABEL_AUTHORITY }, { SECURITY_MANDATORY_HIGH_RID } };
static const struct /* same fields as struct SID */
{
BYTE Revision;
@@ -108,6 +109,7 @@ 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;
const PSID security_domain_users_sid = (PSID)&domain_users_sid;
+const PSID security_high_label_sid = (PSID)&high_label_sid;
static luid_t prev_luid_value = { 1000, 0 };
@@ -631,6 +633,57 @@ struct sid_data
unsigned int subauth[MAX_SUBAUTH_COUNT];
};
+static struct security_descriptor *create_security_label_sd( PSID label_sid )
+{
+ size_t sid_len = security_sid_len( label_sid );
+ size_t sacl_size = sizeof(ACL) + FIELD_OFFSET(SYSTEM_MANDATORY_LABEL_ACE, SidStart) + sid_len;
+ size_t sd_size = sizeof(struct security_descriptor) + sacl_size;
+ SYSTEM_MANDATORY_LABEL_ACE *smla;
+ struct security_descriptor *sd;
+ ACL *sacl;
+
+ sd = mem_alloc( sd_size );
+ if (!sd) return NULL;
+
+ sd->control = SE_SACL_PRESENT;
+ sd->owner_len = 0;
+ sd->group_len = 0;
+ sd->sacl_len = sacl_size;
+ sd->dacl_len = 0;
+
+ sacl = (ACL *)(sd + 1);
+ sacl->AclRevision = ACL_REVISION;
+ sacl->Sbz1 = 0;
+ sacl->AclSize = sacl_size;
+ sacl->AceCount = 1;
+ sacl->Sbz2 = 0;
+
+ smla = (SYSTEM_MANDATORY_LABEL_ACE *)(sacl + 1);
+ smla->Header.AceType = SYSTEM_MANDATORY_LABEL_ACE_TYPE;
+ smla->Header.AceFlags = 0;
+ smla->Header.AceSize = FIELD_OFFSET(SYSTEM_MANDATORY_LABEL_ACE, SidStart) + sid_len;
+ smla->Mask = SYSTEM_MANDATORY_LABEL_NO_WRITE_UP;
+ memcpy( &smla->SidStart, label_sid, sid_len );
+
+ assert( sd_is_valid( sd, sd_size ) );
+ return sd;
+}
+
+int token_assign_label( struct token *token, PSID label )
+{
+ struct security_descriptor *sd;
+ int ret = 0;
+
+ if ((sd = create_security_label_sd( label )))
+ {
+ /* FIXME: this overwrites the complete SACL, not only the label */
+ ret = set_sd_defaults_from_token( &token->obj, sd, SACL_SECURITY_INFORMATION, token );
+ free( sd );
+ }
+
+ return ret;
+}
+
struct token *token_create_admin( void )
{
struct token *token = NULL;
--
2.11.0

View File

@ -0,0 +1,5 @@
Fixes: Implement support for LABEL_SECURITY_INFORMATION
Depends: advapi32-AddMandatoryAce
Depends: advapi32-GetExplicitEntriesFromAclW
Depends: server-Stored_ACLs
Depends: server-Misc_ACL