server: fix for default_set_sd which contained a number of issues related to setting defaults from tokens.
Joris van der Wel
joris at jorisvanderwel.com
Tue Jun 24 17:04:20 CDT 2014
server: fix for default_set_sd which contained a number of issues related
to setting defaults from tokens.
* SetSecurityInfo should not reset owner and group to default if
SECURITY_INFORMATION does not contain OWNER_SECURITY_INFORMATION or
GROUP_SECURITY_INFORMATION
* The create functions for objects (create_event, create_mapping,
create_mutex, create_semaphore) should set defaults if the security
descriptor is NULL (it already did this properly if the security descriptor
is empty).
* For certain objects: The impersonation token of the thread should also be
used to determine the default owner, dacl, not just the primary token.
* Any of the 4 SE_*_DEFAULTED controls should not be stored on the object,
their usage is transient
Tested on Wine, XP sp3, Vista sp2 and 8.1 update 1
---
dlls/advapi32/tests/security.c | 225
+++++++++++++++++++++++++++++++++--------
server/event.c | 50 ++++-----
server/mapping.c | 8 +-
server/mutex.c | 40 ++++----
server/object.c | 92 ++++++++++++-----
server/object.h | 7 +-
server/semaphore.c | 40 ++++----
server/timer.c | 32 +++---
8 files changed, 340 insertions(+), 154 deletions(-)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20140625/066de437/attachment-0001.html>
-------------- next part --------------
From 4424e62abbaac3ffe4073a38740e4eb6ee60316a Mon Sep 17 00:00:00 2001
From: Joris van der Wel <joris at jorisvanderwel.com>
Date: Tue, 24 Jun 2014 22:51:40 +0200
Subject: server: fix for default_set_sd which contained a number of issues
related to setting defaults from tokens.
* SetSecurityInfo should not reset owner and group to default if SECURITY_INFORMATION does not contain OWNER_SECURITY_INFORMATION or GROUP_SECURITY_INFORMATION
* The create functions for objects (create_event, create_mapping, create_mutex, create_semaphore) should set defaults if the security descriptor is NULL (it already did this properly if the security descriptor is empty).
* For certain objects: The impersonation token of the thread should also be used to determine the default owner, dacl, not just the primary token.
* Any of the 4 SE_*_DEFAULTED controls should not be stored on the object, their usage is transient
---
dlls/advapi32/tests/security.c | 225 +++++++++++++++++++++++++++++++++--------
server/event.c | 50 ++++-----
server/mapping.c | 8 +-
server/mutex.c | 40 ++++----
server/object.c | 92 ++++++++++++-----
server/object.h | 7 +-
server/semaphore.c | 40 ++++----
server/timer.c | 32 +++---
8 files changed, 340 insertions(+), 154 deletions(-)
diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 05da0ae..ac9e15e 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -208,6 +208,32 @@ static void init(void)
myARGC = winetest_get_mainargs( &myARGV );
}
+static SECURITY_DESCRIPTOR* test_get_security_descriptor(HANDLE handle, int line)
+{
+ /* use HeapFree(GetProcessHeap(), 0, sd); when done */
+ DWORD ret, length, needed;
+ SECURITY_DESCRIPTOR *sd;
+
+ needed = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+ ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+ NULL, 0, &needed);
+ ok_(__FILE__, line)(!ret, "GetKernelObjectSecurity should fail\n");
+ ok_(__FILE__, line)(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
+ ok_(__FILE__, line)(needed != 0xdeadbeef, "GetKernelObjectSecurity should return required buffer length\n");
+
+ length = needed;
+ sd = HeapAlloc(GetProcessHeap(), 0, length);
+
+ needed = 0xdeadbeef;
+ SetLastError(0xdeadbeef);
+ ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
+ sd, length, &needed);
+ ok_(__FILE__, line)(ret, "GetKernelObjectSecurity error %d\n", GetLastError());
+ ok_(__FILE__, line)(needed == length || needed == 0 /* file, pipe */, "GetKernelObjectSecurity should return %u instead of %u\n", length, needed);
+ return sd;
+}
+
static void test_sid(void)
{
struct sidRef refs[] = {
@@ -2464,6 +2490,88 @@ static void test_granted_access(HANDLE handle, ACCESS_MASK access,
"with %s, instead of %d\n", #e, err); \
}while(0)
+#define CHECK_DACL_IS_NULL(o) \
+ do{ \
+ SECURITY_DESCRIPTOR *queriedSD = NULL; \
+ PACL queriedAcl = NULL; \
+ BOOL dacl_present; \
+ BOOL dacl_defaulted; \
+ SECURITY_DESCRIPTOR_CONTROL control; \
+ DWORD revision; \
+ queriedSD = test_get_security_descriptor( o, __LINE__ ); \
+ queriedAcl = (PACL)0xdeadbeef; \
+ res = GetSecurityDescriptorDacl(queriedSD, &dacl_present, &queriedAcl, &dacl_defaulted); \
+ ok(res, "GetSecurityDescriptorDacl failed with error %d\n", GetLastError()); \
+ res = GetSecurityDescriptorControl(queriedSD, &control, &revision); \
+ ok(res, "GetSecurityDescriptorControl failed with error %d\n", GetLastError()); \
+ ok(dacl_present, "DACL should be present (even though the DACL is NULL)\n"); \
+ ok(queriedAcl == NULL, "Setting a NULL DACL, should also return a NULL DACL\n"); \
+ ok(!dacl_defaulted, "Defaulted is true\n"); \
+ ok((control & SE_DACL_DEFAULTED) == 0, "SE_DACL_DEFAULTED is set\n"); \
+ HeapFree(GetProcessHeap(), 0, queriedSD); \
+ }while(0)
+
+#define CHECK_DACL_IS_SET(o) \
+ do{ \
+ SECURITY_DESCRIPTOR *queriedSD = NULL; \
+ PACL queriedAcl = NULL; \
+ BOOL dacl_present; \
+ BOOL dacl_defaulted; \
+ SECURITY_DESCRIPTOR_CONTROL control; \
+ DWORD revision; \
+ queriedSD = test_get_security_descriptor( o, __LINE__ ); \
+ queriedAcl = (PACL)0xdeadbeef; \
+ res = GetSecurityDescriptorDacl(queriedSD, &dacl_present, &queriedAcl, &dacl_defaulted); \
+ ok(res, "GetSecurityDescriptorDacl failed with error %d\n", GetLastError()); \
+ res = GetSecurityDescriptorControl(queriedSD, &control, &revision); \
+ ok(res, "GetSecurityDescriptorControl failed with error %d\n", GetLastError()); \
+ ok(dacl_present, "DACL should be present\n"); \
+ ok(queriedAcl != NULL, "DACL is NULL\n"); \
+ ok(!dacl_defaulted, "Defaulted is true\n"); \
+ ok((control & SE_DACL_DEFAULTED) == 0, "SE_DACL_DEFAULTED is set\n"); \
+ HeapFree(GetProcessHeap(), 0, queriedSD); \
+ }while(0)
+
+#define CHECK_GROUP( o, expected ) \
+ do {\
+ SECURITY_DESCRIPTOR *queriedSD = NULL; \
+ PSID group; \
+ BOOL group_defaulted; \
+ SECURITY_DESCRIPTOR_CONTROL control; \
+ DWORD revision; \
+ LPSTR sid_str = NULL; \
+ queriedSD = test_get_security_descriptor( o, __LINE__ ); \
+ res = GetSecurityDescriptorGroup(queriedSD, &group, &group_defaulted); \
+ ok(res, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); \
+ res = pConvertSidToStringSidA( group, &sid_str ); \
+ ok(res, "ConvertSidToStringSidA failed with error %d\n", GetLastError()); \
+ res = GetSecurityDescriptorControl(queriedSD, &control, &revision); \
+ ok(res, "GetSecurityDescriptorControl failed with error %d\n", GetLastError()); \
+ ok(EqualSid(group, expected), "Group SIDs are not equal, actual value is %s\n", sid_str); \
+ ok(!group_defaulted, "Defaulted is true\n"); \
+ ok((control & SE_GROUP_DEFAULTED) == 0, "SE_GROUP_DEFAULTED is set\n"); \
+ HeapFree(GetProcessHeap(), 0, queriedSD); \
+ LocalFree(sid_str); \
+ }while(0)
+
+#define CHECK_GROUP_IS_SET( o ) \
+do {\
+ SECURITY_DESCRIPTOR *queriedSD = NULL; \
+ PSID group; \
+ BOOL group_defaulted; \
+ SECURITY_DESCRIPTOR_CONTROL control; \
+ DWORD revision; \
+ queriedSD = test_get_security_descriptor( o, __LINE__ ); \
+ res = GetSecurityDescriptorGroup(queriedSD, &group, &group_defaulted); \
+ ok(res, "GetSecurityDescriptorGroup failed with error %d\n", GetLastError()); \
+ res = GetSecurityDescriptorControl(queriedSD, &control, &revision); \
+ ok(res, "GetSecurityDescriptorControl failed with error %d\n", GetLastError()); \
+ ok(group != NULL, "Group SID is NULL\n"); \
+ ok(!group_defaulted, "Defaulted is true"); \
+ ok((control & SE_GROUP_DEFAULTED) == 0, "SE_GROUP_DEFAULTED is set\n"); \
+ HeapFree(GetProcessHeap(), 0, queriedSD); \
+}while(0)
+
static void test_process_security(void)
{
BOOL res;
@@ -2475,9 +2583,11 @@ static void test_process_security(void)
char buffer[MAX_PATH];
PROCESS_INFORMATION info;
STARTUPINFOA startup;
- SECURITY_ATTRIBUTES psa;
+ SECURITY_ATTRIBUTES sa;
HANDLE token, event;
DWORD size;
+ SID_IDENTIFIER_AUTHORITY SIDAuthWorld = { SECURITY_WORLD_SID_AUTHORITY };
+ PSID EveryoneSid = NULL;
Acl = HeapAlloc(GetProcessHeap(), 0, 256);
res = InitializeAcl(Acl, 256, ACL_REVISION);
@@ -2488,6 +2598,9 @@ static void test_process_security(void)
return;
}
ok(res, "InitializeAcl failed with error %d\n", GetLastError());
+
+ res = AllocateAndInitializeSid( &SIDAuthWorld, 1, SECURITY_WORLD_RID, 0, 0, 0, 0, 0, 0, 0, &EveryoneSid);
+ ok(res, "AllocateAndInitializeSid failed with error %d\n", GetLastError());
/* get owner from the token we might be running as a user not admin */
res = OpenProcessToken( GetCurrentProcess(), MAXIMUM_ALLOWED, &token );
@@ -2538,29 +2651,69 @@ static void test_process_security(void)
event = CreateEventA( NULL, TRUE, TRUE, "test_event" );
ok(event != NULL, "CreateEvent %d\n", GetLastError());
+ /* lpEventAttributes is NULL and therefore no security descriptor has been set yet.
+ * The dacl should have been set according to the primary token of the creating
+ * process (TOKEN_DEFAULT_DACL)
+ */
+ CHECK_DACL_IS_SET( event );
+ CHECK_GROUP_IS_SET( event );
SecurityDescriptor->Revision = 0;
CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_UNKNOWN_REVISION );
+ CHECK_DACL_IS_SET( event );
+ CHECK_GROUP_IS_SET( event );
SecurityDescriptor->Revision = SECURITY_DESCRIPTOR_REVISION;
CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_INVALID_SECURITY_DESCR );
CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_INVALID_SECURITY_DESCR );
CHECK_SET_SECURITY( event, SACL_SECURITY_INFORMATION, ERROR_ACCESS_DENIED );
+ CHECK_DACL_IS_SET( event );
+ CHECK_GROUP_IS_SET( event );
CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS );
- /* NULL DACL is valid and means default DACL from token */
+ /* NULL DACL is valid and means that everyone has access */
+ CHECK_DACL_IS_NULL( event );
+ CHECK_GROUP_IS_SET( event );
+
SecurityDescriptor->Control |= SE_DACL_PRESENT;
CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS );
+ CHECK_DACL_IS_NULL( event );
+ CHECK_GROUP_IS_SET( event );
/* Set owner and group and dacl */
res = SetSecurityDescriptorOwner(SecurityDescriptor, AdminSid, FALSE);
ok(res, "SetSecurityDescriptorOwner failed with error %d\n", GetLastError());
CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_SUCCESS );
+ CHECK_DACL_IS_NULL( event ); /* DACL should remain NULL for now */
+ CHECK_GROUP_IS_SET( event );
res = SetSecurityDescriptorGroup(SecurityDescriptor, UsersSid, FALSE);
ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError());
+ CHECK_DACL_IS_NULL( event ); /* DACL should remain NULL for now */
CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_SUCCESS );
+ CHECK_GROUP( event, UsersSid );
res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE);
ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS );
+ CHECK_DACL_IS_SET( event );
+ CHECK_GROUP( event, UsersSid );
+ /* set the user again, the previous DACL should remain set even though
+ the security descriptor has a different DACL
+ (DACL_SECURITY_INFORMATION is not given) */
+ res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, NULL, FALSE);
+ ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
+ CHECK_SET_SECURITY( event, OWNER_SECURITY_INFORMATION, ERROR_SUCCESS );
+ CHECK_DACL_IS_SET( event );
+
+ /* set a different group, it should remain set even if we change the dacl */
+ res = SetSecurityDescriptorGroup(SecurityDescriptor, EveryoneSid, FALSE);
+ ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError());
+ CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_SUCCESS );
+ CHECK_GROUP( event, EveryoneSid );
+ CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS );
+ CHECK_DACL_IS_NULL( event );
+ CHECK_GROUP( event, EveryoneSid );
+
+ res = SetSecurityDescriptorDacl(SecurityDescriptor, TRUE, Acl, FALSE);
+ ok(res, "SetSecurityDescriptorDacl failed with error %d\n", GetLastError());
sprintf(buffer, "%s tests/security.c test", myARGV[0]);
memset(&startup, 0, sizeof(startup));
@@ -2568,12 +2721,12 @@ static void test_process_security(void)
startup.dwFlags = STARTF_USESHOWWINDOW;
startup.wShowWindow = SW_SHOWNORMAL;
- psa.nLength = sizeof(psa);
- psa.lpSecurityDescriptor = SecurityDescriptor;
- psa.bInheritHandle = TRUE;
+ sa.nLength = sizeof(sa);
+ sa.lpSecurityDescriptor = SecurityDescriptor;
+ sa.bInheritHandle = TRUE;
/* Doesn't matter what ACL say we should get full access for ourselves */
- res = CreateProcessA( NULL, buffer, &psa, NULL, FALSE, 0, NULL, NULL, &startup, &info );
+ res = CreateProcessA( NULL, buffer, &sa, NULL, FALSE, 0, NULL, NULL, &startup, &info );
ok(res, "CreateProcess with err:%d\n", GetLastError());
TEST_GRANTED_ACCESS2( info.hProcess, PROCESS_ALL_ACCESS_NT4,
STANDARD_RIGHTS_ALL | SPECIFIC_RIGHTS_ALL );
@@ -2586,6 +2739,7 @@ static void test_process_security(void)
HeapFree(GetProcessHeap(), 0, owner);
HeapFree(GetProcessHeap(), 0, Acl);
HeapFree(GetProcessHeap(), 0, SecurityDescriptor);
+ FreeSid(EveryoneSid);
}
static void test_process_security_child(void)
@@ -4390,7 +4544,7 @@ static void test_CreateRestrictedToken(void)
CloseHandle(process_token);
}
-static void validate_default_security_descriptor(SECURITY_DESCRIPTOR *sd)
+static void validate_default_security_descriptor(SECURITY_DESCRIPTOR *sd, const char *todo_platform)
{
BOOL ret, present, defaulted;
ACL *acl;
@@ -4405,9 +4559,9 @@ static void validate_default_security_descriptor(SECURITY_DESCRIPTOR *sd)
SetLastError(0xdeadbeef);
ret = GetSecurityDescriptorDacl(sd, &present, &acl, &defaulted);
ok(ret, "GetSecurityDescriptorDacl error %d\n", GetLastError());
-todo_wine
+todo(todo_platform)
ok(present == 1, "acl is not present\n");
-todo_wine
+todo(todo_platform)
ok(acl != (void *)0xdeadbeef && acl != NULL, "acl pointer is not set\n");
ok(defaulted == 0, "defaulted is set to TRUE\n");
@@ -4416,7 +4570,7 @@ todo_wine
SetLastError(0xdeadbeef);
ret = GetSecurityDescriptorOwner(sd, &sid, &defaulted);
ok(ret, "GetSecurityDescriptorOwner error %d\n", GetLastError());
-todo_wine
+todo(todo_platform)
ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n");
ok(defaulted == 0, "defaulted is set to TRUE\n");
@@ -4425,44 +4579,27 @@ todo_wine
SetLastError(0xdeadbeef);
ret = GetSecurityDescriptorGroup(sd, &sid, &defaulted);
ok(ret, "GetSecurityDescriptorGroup error %d\n", GetLastError());
-todo_wine
+todo(todo_platform)
ok(sid != (void *)0xdeadbeef && sid != NULL, "sid pointer is not set\n");
ok(defaulted == 0, "defaulted is set to TRUE\n");
}
-static void test_default_handle_security(HANDLE token, HANDLE handle, GENERIC_MAPPING *mapping)
+static void test_default_handle_security(HANDLE token, HANDLE handle, GENERIC_MAPPING *mapping, const char *todo_platform)
{
- DWORD ret, length, needed, granted, priv_set_len;
+ DWORD ret, granted, priv_set_len;
BOOL status;
PRIVILEGE_SET priv_set;
SECURITY_DESCRIPTOR *sd;
- needed = 0xdeadbeef;
- SetLastError(0xdeadbeef);
- ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
- NULL, 0, &needed);
- ok(!ret, "GetKernelObjectSecurity should fail\n");
- ok(GetLastError() == ERROR_INSUFFICIENT_BUFFER, "expected ERROR_INSUFFICIENT_BUFFER, got %d\n", GetLastError());
- ok(needed != 0xdeadbeef, "GetKernelObjectSecurity should return required buffer length\n");
-
- length = needed;
- sd = HeapAlloc(GetProcessHeap(), 0, length);
-
- needed = 0xdeadbeef;
- SetLastError(0xdeadbeef);
- ret = GetKernelObjectSecurity(handle, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION | DACL_SECURITY_INFORMATION,
- sd, length, &needed);
- ok(ret, "GetKernelObjectSecurity error %d\n", GetLastError());
- ok(needed == length || needed == 0 /* file, pipe */, "GetKernelObjectSecurity should return %u instead of %u\n", length, needed);
-
- validate_default_security_descriptor(sd);
+ sd = test_get_security_descriptor(handle, __LINE__);
+ validate_default_security_descriptor(sd, todo_platform);
priv_set_len = sizeof(priv_set);
granted = 0xdeadbeef;
status = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = AccessCheck(sd, token, MAXIMUM_ALLOWED, mapping, &priv_set, &priv_set_len, &granted, &status);
-todo_wine {
+todo(todo_platform) {
ok(ret, "AccessCheck error %d\n", GetLastError());
ok(status == 1, "expected 1, got %d\n", status);
ok(granted == mapping->GenericAll, "expected all access %#x, got %#x\n", mapping->GenericAll, granted);
@@ -4472,7 +4609,7 @@ todo_wine {
status = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = AccessCheck(sd, token, 0, mapping, &priv_set, &priv_set_len, &granted, &status);
-todo_wine {
+todo(todo_platform) {
ok(ret, "AccessCheck error %d\n", GetLastError());
ok(status == 0 || broken(status == 1) /* NT4 */, "expected 0, got %d\n", status);
ok(granted == 0 || broken(granted == mapping->GenericRead) /* NT4 */, "expected 0, got %#x\n", granted);
@@ -4482,7 +4619,7 @@ todo_wine {
status = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = AccessCheck(sd, token, ACCESS_SYSTEM_SECURITY, mapping, &priv_set, &priv_set_len, &granted, &status);
-todo_wine {
+todo(todo_platform) {
ok(ret, "AccessCheck error %d\n", GetLastError());
ok(status == 0, "expected 0, got %d\n", status);
ok(granted == 0, "expected 0, got %#x\n", granted);
@@ -4492,7 +4629,7 @@ todo_wine {
status = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = AccessCheck(sd, token, mapping->GenericRead, mapping, &priv_set, &priv_set_len, &granted, &status);
-todo_wine {
+todo(todo_platform) {
ok(ret, "AccessCheck error %d\n", GetLastError());
ok(status == 1, "expected 1, got %d\n", status);
ok(granted == mapping->GenericRead, "expected read access %#x, got %#x\n", mapping->GenericRead, granted);
@@ -4502,7 +4639,7 @@ todo_wine {
status = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = AccessCheck(sd, token, mapping->GenericWrite, mapping, &priv_set, &priv_set_len, &granted, &status);
-todo_wine {
+todo(todo_platform) {
ok(ret, "AccessCheck error %d\n", GetLastError());
ok(status == 1, "expected 1, got %d\n", status);
ok(granted == mapping->GenericWrite, "expected write access %#x, got %#x\n", mapping->GenericWrite, granted);
@@ -4512,7 +4649,7 @@ todo_wine {
status = 0xdeadbeef;
SetLastError(0xdeadbeef);
ret = AccessCheck(sd, token, mapping->GenericExecute, mapping, &priv_set, &priv_set_len, &granted, &status);
-todo_wine {
+todo(todo_platform) {
ok(ret, "AccessCheck error %d\n", GetLastError());
ok(status == 1, "expected 1, got %d\n", status);
ok(granted == mapping->GenericExecute, "expected execute access %#x, got %#x\n", mapping->GenericExecute, granted);
@@ -4585,7 +4722,7 @@ todo_wine
ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError());
}
- test_default_handle_security(token, mutex, &mapping);
+ test_default_handle_security(token, mutex, &mapping, "none");
CloseHandle (mutex);
}
@@ -4642,7 +4779,7 @@ todo_wine
ok(GetLastError() == ERROR_ACCESS_DENIED, "wrong error %u\n", GetLastError());
}
- test_default_handle_security(token, event, &mapping);
+ test_default_handle_security(token, event, &mapping, "none");
CloseHandle(event);
}
@@ -4692,7 +4829,7 @@ static void test_semaphore_security(HANDLE token)
CloseHandle(dup);
}
- test_default_handle_security(token, sem, &mapping);
+ test_default_handle_security(token, sem, &mapping, "none");
CloseHandle(sem);
}
@@ -4753,7 +4890,7 @@ static void test_named_pipe_security(HANDLE token)
0, 0, NMPWAIT_USE_DEFAULT_WAIT, NULL);
ok(pipe != INVALID_HANDLE_VALUE, "CreateNamedPipe error %d\n", GetLastError());
- test_default_handle_security(token, pipe, &mapping);
+ test_default_handle_security(token, pipe, &mapping, "wine");
SetLastError(0xdeadbeef);
file = CreateFileA(WINE_TEST_PIPE, FILE_ALL_ACCESS, 0, NULL, OPEN_EXISTING, 0, 0);
@@ -5341,7 +5478,7 @@ static void test_default_dacl_owner_sid(void)
ret = GetSecurityDescriptorOwner( sd, &owner, &defaulted );
ok( ret, "error %u\n", GetLastError() );
ok( owner != (void *)0xdeadbeef, "owner not set\n" );
- todo_wine ok( !defaulted, "owner defaulted\n" );
+ ok( !defaulted, "owner defaulted\n" );
dacl = (void *)0xdeadbeef;
present = FALSE;
@@ -5350,7 +5487,7 @@ static void test_default_dacl_owner_sid(void)
ok( ret, "error %u\n", GetLastError() );
ok( present, "dacl not present\n" );
ok( dacl != (void *)0xdeadbeef, "dacl not set\n" );
- todo_wine ok( !defaulted, "dacl defaulted\n" );
+ ok( !defaulted, "dacl defaulted\n" );
index = 0;
found = FALSE;
diff --git a/server/event.c b/server/event.c
index 4d3c562..2871ad9 100644
--- a/server/event.c
+++ b/server/event.c
@@ -52,22 +52,22 @@ static int event_signal( struct object *obj, unsigned int access);
static const struct object_ops event_ops =
{
- sizeof(struct event), /* size */
- event_dump, /* dump */
- event_get_type, /* get_type */
- add_queue, /* add_queue */
- remove_queue, /* remove_queue */
- event_signaled, /* signaled */
- event_satisfied, /* satisfied */
- event_signal, /* signal */
- no_get_fd, /* get_fd */
- event_map_access, /* map_access */
- default_get_sd, /* get_sd */
- default_set_sd, /* set_sd */
- no_lookup_name, /* lookup_name */
- no_open_file, /* open_file */
- no_close_handle, /* close_handle */
- no_destroy /* destroy */
+ sizeof(struct event), /* size */
+ event_dump, /* dump */
+ event_get_type, /* get_type */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ event_signaled, /* signaled */
+ event_satisfied, /* satisfied */
+ event_signal, /* signal */
+ no_get_fd, /* get_fd */
+ event_map_access, /* map_access */
+ default_get_sd, /* get_sd */
+ default_set_sd_impersonation, /* set_sd */
+ no_lookup_name, /* lookup_name */
+ no_open_file, /* open_file */
+ no_close_handle, /* close_handle */
+ no_destroy /* destroy */
};
@@ -94,7 +94,7 @@ static const struct object_ops keyed_event_ops =
no_get_fd, /* get_fd */
keyed_event_map_access, /* map_access */
default_get_sd, /* get_sd */
- default_set_sd, /* set_sd */
+ default_set_sd_impersonation,/* set_sd */
no_lookup_name, /* lookup_name */
no_open_file, /* open_file */
no_close_handle, /* close_handle */
@@ -115,10 +115,10 @@ struct event *create_event( struct directory *root, const struct unicode_str *na
/* initialize it if it didn't already exist */
event->manual_reset = manual_reset;
event->signaled = initial_state;
- if (sd) default_set_sd( &event->obj, sd, OWNER_SECURITY_INFORMATION|
- GROUP_SECURITY_INFORMATION|
- DACL_SECURITY_INFORMATION|
- SACL_SECURITY_INFORMATION );
+ default_set_sd_impersonation( &event->obj, sd, OWNER_SECURITY_INFORMATION|
+ GROUP_SECURITY_INFORMATION|
+ DACL_SECURITY_INFORMATION|
+ SACL_SECURITY_INFORMATION );
}
}
return event;
@@ -214,10 +214,10 @@ struct keyed_event *create_keyed_event( struct directory *root, const struct uni
if (get_error() != STATUS_OBJECT_NAME_EXISTS)
{
/* initialize it if it didn't already exist */
- if (sd) default_set_sd( &event->obj, sd, OWNER_SECURITY_INFORMATION|
- GROUP_SECURITY_INFORMATION|
- DACL_SECURITY_INFORMATION|
- SACL_SECURITY_INFORMATION );
+ default_set_sd_impersonation( &event->obj, sd, OWNER_SECURITY_INFORMATION|
+ GROUP_SECURITY_INFORMATION|
+ DACL_SECURITY_INFORMATION|
+ SACL_SECURITY_INFORMATION );
}
}
return event;
diff --git a/server/mapping.c b/server/mapping.c
index 64b3003..4efb92a 100644
--- a/server/mapping.c
+++ b/server/mapping.c
@@ -484,10 +484,10 @@ static struct object *create_mapping( struct directory *root, const struct unico
if (get_error() == STATUS_OBJECT_NAME_EXISTS)
return &mapping->obj; /* Nothing else to do */
- if (sd) default_set_sd( &mapping->obj, sd, OWNER_SECURITY_INFORMATION|
- GROUP_SECURITY_INFORMATION|
- DACL_SECURITY_INFORMATION|
- SACL_SECURITY_INFORMATION );
+ default_set_sd( &mapping->obj, sd, OWNER_SECURITY_INFORMATION|
+ GROUP_SECURITY_INFORMATION|
+ DACL_SECURITY_INFORMATION|
+ SACL_SECURITY_INFORMATION );
mapping->header_size = 0;
mapping->base = 0;
mapping->fd = NULL;
diff --git a/server/mutex.c b/server/mutex.c
index 910fbca..89eb769 100644
--- a/server/mutex.c
+++ b/server/mutex.c
@@ -55,22 +55,22 @@ static int mutex_signal( struct object *obj, unsigned int access );
static const struct object_ops mutex_ops =
{
- sizeof(struct mutex), /* size */
- mutex_dump, /* dump */
- mutex_get_type, /* get_type */
- add_queue, /* add_queue */
- remove_queue, /* remove_queue */
- mutex_signaled, /* signaled */
- mutex_satisfied, /* satisfied */
- mutex_signal, /* signal */
- no_get_fd, /* get_fd */
- mutex_map_access, /* map_access */
- default_get_sd, /* get_sd */
- default_set_sd, /* set_sd */
- no_lookup_name, /* lookup_name */
- no_open_file, /* open_file */
- no_close_handle, /* close_handle */
- mutex_destroy /* destroy */
+ sizeof(struct mutex), /* size */
+ mutex_dump, /* dump */
+ mutex_get_type, /* get_type */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ mutex_signaled, /* signaled */
+ mutex_satisfied, /* satisfied */
+ mutex_signal, /* signal */
+ no_get_fd, /* get_fd */
+ mutex_map_access, /* map_access */
+ default_get_sd, /* get_sd */
+ default_set_sd_impersonation, /* set_sd */
+ no_lookup_name, /* lookup_name */
+ no_open_file, /* open_file */
+ no_close_handle, /* close_handle */
+ mutex_destroy /* destroy */
};
@@ -111,10 +111,10 @@ static struct mutex *create_mutex( struct directory *root, const struct unicode_
mutex->owner = NULL;
mutex->abandoned = 0;
if (owned) do_grab( mutex, current );
- if (sd) default_set_sd( &mutex->obj, sd, OWNER_SECURITY_INFORMATION|
- GROUP_SECURITY_INFORMATION|
- DACL_SECURITY_INFORMATION|
- SACL_SECURITY_INFORMATION );
+ default_set_sd_impersonation( &mutex->obj, sd, OWNER_SECURITY_INFORMATION|
+ GROUP_SECURITY_INFORMATION|
+ DACL_SECURITY_INFORMATION|
+ SACL_SECURITY_INFORMATION );
}
}
return mutex;
diff --git a/server/object.c b/server/object.c
index c206747..afcb101 100644
--- a/server/object.c
+++ b/server/object.c
@@ -423,10 +423,10 @@ struct security_descriptor *default_get_sd( struct object *obj )
return obj->sd;
}
-int default_set_sd( struct object *obj, const struct security_descriptor *sd,
- unsigned int set_info )
+int set_sd_defaulting_token( struct object *obj, const struct security_descriptor *sd,
+ unsigned int set_info, struct token *token )
{
- struct security_descriptor new_sd, *new_sd_ptr;
+ struct security_descriptor new_sd = {0}, *new_sd_ptr;
int present;
const SID *owner, *group;
const ACL *sacl, *dacl;
@@ -434,60 +434,91 @@ int default_set_sd( struct object *obj, const struct security_descriptor *sd,
if (!set_info) return 1;
- new_sd.control = sd->control & ~SE_SELF_RELATIVE;
+ new_sd.control = sd ? sd->control & ~SE_SELF_RELATIVE : 0;
+
+ /* note: SE_*_DEFAULTED is never stored */
- owner = sd_get_owner( sd );
+ owner = sd ? sd_get_owner( sd ) : NULL;
if (set_info & OWNER_SECURITY_INFORMATION && owner)
+ {
new_sd.owner_len = sd->owner_len;
+ }
else
{
- owner = token_get_user( current->process->token );
- new_sd.owner_len = security_sid_len( owner );
- new_sd.control |= SE_OWNER_DEFAULTED;
+ owner = obj->sd ? sd_get_owner( obj->sd ) : NULL;
+
+ if (owner)
+ {
+ new_sd.owner_len = obj->sd->owner_len;
+ }
+ else if (token)
+ {
+ owner = token_get_user( token );
+ new_sd.owner_len = security_sid_len( owner );
+ }
}
- group = sd_get_group( sd );
+ group = sd ? sd_get_group( sd ) : NULL;
if (set_info & GROUP_SECURITY_INFORMATION && group)
+ {
new_sd.group_len = sd->group_len;
+ }
else
{
- group = token_get_primary_group( current->process->token );
- new_sd.group_len = security_sid_len( group );
- new_sd.control |= SE_GROUP_DEFAULTED;
+ group = obj->sd ? sd_get_group( obj->sd ) : NULL;
+ if (group)
+ {
+ new_sd.group_len = obj->sd->group_len;
+ }
+ else if (token)
+ {
+ group = token_get_primary_group( token );
+ new_sd.group_len = security_sid_len( group );
+ }
}
-
+
new_sd.control |= SE_SACL_PRESENT;
- sacl = sd_get_sacl( sd, &present );
+ present = 0;
+ sacl = sd ? sd_get_sacl( sd, &present ) : NULL;
if (set_info & SACL_SECURITY_INFORMATION && present)
+ {
new_sd.sacl_len = sd->sacl_len;
+ }
else
{
- if (obj->sd) sacl = sd_get_sacl( obj->sd, &present );
+ present = 0;
+ sacl = obj->sd ? sd_get_sacl( obj->sd, &present ) : NULL;
- if (obj->sd && present)
+ if (present)
+ {
new_sd.sacl_len = obj->sd->sacl_len;
+ }
else
{
new_sd.sacl_len = 0;
- new_sd.control |= SE_SACL_DEFAULTED;
}
}
-
+
new_sd.control |= SE_DACL_PRESENT;
- dacl = sd_get_dacl( sd, &present );
+ present = 0;
+ dacl = sd ? sd_get_dacl( sd, &present ) : NULL;
if (set_info & DACL_SECURITY_INFORMATION && present)
+ {
new_sd.dacl_len = sd->dacl_len;
+ }
else
{
- if (obj->sd) dacl = sd_get_dacl( obj->sd, &present );
+ present = 0;
+ dacl = obj->sd ? sd_get_dacl( obj->sd, &present ) : NULL;
- if (obj->sd && present)
+ if (present)
+ {
new_sd.dacl_len = obj->sd->dacl_len;
- else
+ }
+ else if (token)
{
- dacl = token_get_default_dacl( current->process->token );
+ dacl = token_get_default_dacl( token );
new_sd.dacl_len = dacl->AclSize;
- new_sd.control |= SE_DACL_DEFAULTED;
}
}
@@ -511,6 +542,19 @@ int default_set_sd( struct object *obj, const struct security_descriptor *sd,
return 1;
}
+/** Set the security descriptor, only use the current primary token for defaults. */
+int default_set_sd( struct object *obj, const struct security_descriptor *sd,
+ unsigned int set_info )
+{
+ return set_sd_defaulting_token( obj, sd, set_info, current ? current->process->token : NULL );
+}
+
+/** Set the security descriptor, use the current thread impersonation token for defaults. */
+int default_set_sd_impersonation( struct object *obj, const struct security_descriptor *sd,
+ unsigned int set_info )
+{
+ return set_sd_defaulting_token( obj, sd, set_info, current ? thread_get_impersonation_token(current) : NULL );
+}
struct object *no_lookup_name( struct object *obj, struct unicode_str *name,
unsigned int attr )
{
diff --git a/server/object.h b/server/object.h
index bb3ff21..8cb18b8 100644
--- a/server/object.h
+++ b/server/object.h
@@ -138,7 +138,12 @@ extern int no_signal( struct object *obj, unsigned int access );
extern struct fd *no_get_fd( struct object *obj );
extern unsigned int no_map_access( struct object *obj, unsigned int access );
extern struct security_descriptor *default_get_sd( struct object *obj );
-extern int default_set_sd( struct object *obj, const struct security_descriptor *sd, unsigned int set_info );
+extern int set_sd_defaulting_token( struct object *obj, const struct security_descriptor *sd,
+ unsigned int set_info, struct token *token );
+extern int default_set_sd( struct object *obj, const struct security_descriptor *sd,
+ unsigned int set_info );
+extern int default_set_sd_impersonation( struct object *obj, const struct security_descriptor *sd,
+ unsigned int set_info );
extern struct object *no_lookup_name( struct object *obj, struct unicode_str *name, unsigned int attributes );
extern struct object *no_open_file( struct object *obj, unsigned int access, unsigned int sharing,
unsigned int options );
diff --git a/server/semaphore.c b/server/semaphore.c
index d87325c..4856339 100644
--- a/server/semaphore.c
+++ b/server/semaphore.c
@@ -52,22 +52,22 @@ static int semaphore_signal( struct object *obj, unsigned int access );
static const struct object_ops semaphore_ops =
{
- sizeof(struct semaphore), /* size */
- semaphore_dump, /* dump */
- semaphore_get_type, /* get_type */
- add_queue, /* add_queue */
- remove_queue, /* remove_queue */
- semaphore_signaled, /* signaled */
- semaphore_satisfied, /* satisfied */
- semaphore_signal, /* signal */
- no_get_fd, /* get_fd */
- semaphore_map_access, /* map_access */
- default_get_sd, /* get_sd */
- default_set_sd, /* set_sd */
- no_lookup_name, /* lookup_name */
- no_open_file, /* open_file */
- no_close_handle, /* close_handle */
- no_destroy /* destroy */
+ sizeof(struct semaphore), /* size */
+ semaphore_dump, /* dump */
+ semaphore_get_type, /* get_type */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ semaphore_signaled, /* signaled */
+ semaphore_satisfied, /* satisfied */
+ semaphore_signal, /* signal */
+ no_get_fd, /* get_fd */
+ semaphore_map_access, /* map_access */
+ default_get_sd, /* get_sd */
+ default_set_sd_impersonation, /* set_sd */
+ no_lookup_name, /* lookup_name */
+ no_open_file, /* open_file */
+ no_close_handle, /* close_handle */
+ no_destroy /* destroy */
};
@@ -89,10 +89,10 @@ static struct semaphore *create_semaphore( struct directory *root, const struct
/* initialize it if it didn't already exist */
sem->count = initial;
sem->max = max;
- if (sd) default_set_sd( &sem->obj, sd, OWNER_SECURITY_INFORMATION|
- GROUP_SECURITY_INFORMATION|
- DACL_SECURITY_INFORMATION|
- SACL_SECURITY_INFORMATION );
+ default_set_sd_impersonation( &sem->obj, sd, OWNER_SECURITY_INFORMATION|
+ GROUP_SECURITY_INFORMATION|
+ DACL_SECURITY_INFORMATION|
+ SACL_SECURITY_INFORMATION );
}
}
return sem;
diff --git a/server/timer.c b/server/timer.c
index 9c293f2..42cd8c2 100644
--- a/server/timer.c
+++ b/server/timer.c
@@ -59,22 +59,22 @@ static void timer_destroy( struct object *obj );
static const struct object_ops timer_ops =
{
- sizeof(struct timer), /* size */
- timer_dump, /* dump */
- timer_get_type, /* get_type */
- add_queue, /* add_queue */
- remove_queue, /* remove_queue */
- timer_signaled, /* signaled */
- timer_satisfied, /* satisfied */
- no_signal, /* signal */
- no_get_fd, /* get_fd */
- timer_map_access, /* map_access */
- default_get_sd, /* get_sd */
- default_set_sd, /* set_sd */
- no_lookup_name, /* lookup_name */
- no_open_file, /* open_file */
- no_close_handle, /* close_handle */
- timer_destroy /* destroy */
+ sizeof(struct timer), /* size */
+ timer_dump, /* dump */
+ timer_get_type, /* get_type */
+ add_queue, /* add_queue */
+ remove_queue, /* remove_queue */
+ timer_signaled, /* signaled */
+ timer_satisfied, /* satisfied */
+ no_signal, /* signal */
+ no_get_fd, /* get_fd */
+ timer_map_access, /* map_access */
+ default_get_sd, /* get_sd */
+ default_set_sd_impersonation, /* set_sd */
+ no_lookup_name, /* lookup_name */
+ no_open_file, /* open_file */
+ no_close_handle, /* close_handle */
+ timer_destroy /* destroy */
};
--
1.8.1.msysgit.1
More information about the wine-patches
mailing list