[4/7] server: Setting a security descriptor should not replace an existing owner or group if only a DACL is being set.

Joris van der Wel joris at jorisvanderwel.com
Wed Jun 25 18:13:31 CDT 2014


server: Setting a security descriptor should not replace an existing
 owner or group if only a DACL is being set.

---
 dlls/advapi32/tests/security.c | 100
+++++++++++++++++++++++++++++++++++++++++
 server/object.c                |  29 ++++++++++--
 2 files changed, 125 insertions(+), 4 deletions(-)
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://www.winehq.org/pipermail/wine-patches/attachments/20140626/a784f25f/attachment.html>
-------------- next part --------------
From 4834a430a896822a5372ebf06e287aa2a86747fa Mon Sep 17 00:00:00 2001
From: Joris van der Wel <joris at jorisvanderwel.com>
Date: Thu, 26 Jun 2014 00:17:41 +0200
Subject: server: Setting a security descriptor should not replace an existing
 owner or group if only a DACL is being set.

---
 dlls/advapi32/tests/security.c | 100 +++++++++++++++++++++++++++++++++++++++++
 server/object.c                |  29 ++++++++++--
 2 files changed, 125 insertions(+), 4 deletions(-)

diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index f3ccc8e..684f32f 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -2490,6 +2490,70 @@ 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)
+
 static void test_process_security(void)
 {
     BOOL res;
@@ -2504,6 +2568,9 @@ static void test_process_security(void)
     SECURITY_ATTRIBUTES psa;
     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);
@@ -2514,6 +2581,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 );
@@ -2574,19 +2644,48 @@ static void test_process_security(void)
     CHECK_SET_SECURITY( event, SACL_SECURITY_INFORMATION, ERROR_ACCESS_DENIED );
     CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS );
     /* NULL DACL is valid and means that everyone has access */
+    CHECK_DACL_IS_NULL( event );
     SecurityDescriptor->Control |= SE_DACL_PRESENT;
     CHECK_SET_SECURITY( event, DACL_SECURITY_INFORMATION, ERROR_SUCCESS );
+    CHECK_DACL_IS_NULL( 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 );
+    
     res = SetSecurityDescriptorGroup(SecurityDescriptor, UsersSid, FALSE);
     ok(res, "SetSecurityDescriptorGroup failed with error %d\n", GetLastError());
     CHECK_SET_SECURITY( event, GROUP_SECURITY_INFORMATION, ERROR_SUCCESS );
+    CHECK_DACL_IS_NULL( event );
+    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));
@@ -2612,6 +2711,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)
diff --git a/server/object.c b/server/object.c
index 021c741..394183d 100644
--- a/server/object.c
+++ b/server/object.c
@@ -438,20 +438,41 @@ int default_set_sd( struct object *obj, const struct security_descriptor *sd,
 
     owner = sd_get_owner( sd );
     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 );
+        owner = obj->sd ? sd_get_owner( obj->sd ) : NULL;
+        
+        if (owner)
+        {
+            new_sd.owner_len = obj->sd->owner_len;
+        }
+        else
+        {
+            owner = token_get_user( current->process->token );
+            new_sd.owner_len = security_sid_len( owner );
+        }
     }
 
     group = sd_get_group( sd );
     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 );
+        group = obj->sd ? sd_get_group( obj->sd ) : NULL;
+        if (group)
+        {
+            new_sd.group_len = obj->sd->group_len;
+        }
+        else
+        {
+            group = token_get_primary_group( current->process->token );
+            new_sd.group_len = security_sid_len( group );
+        }
     }
 
     new_sd.control |= SE_SACL_PRESENT;
-- 
1.8.1.msysgit.1



More information about the wine-patches mailing list