From 6d8fd34cabbcbc64062675be610fb8704fcdc3ec Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Michael=20M=C3=BCller?= <michael@fds-team.de>
Date: Mon, 7 Aug 2017 03:33:26 +0200
Subject: [PATCH] server: Correctly assign security labels for tokens.

---
 dlls/advapi32/tests/security.c | 21 ++++++++++-----------
 server/process.c               |  8 +-------
 server/security.h              |  2 +-
 server/token.c                 | 41 ++++++++++++++++++++++++-----------------
 4 files changed, 36 insertions(+), 36 deletions(-)

diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index bf4161c..0610ec7 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -7186,7 +7186,6 @@ static void test_token_security_descriptor(void)
     defaulted = TRUE;
     ret = GetSecurityDescriptorDacl(sd2, &present, &acl2, &defaulted);
     ok(ret, "GetSecurityDescriptorDacl failed with error %u\n", GetLastError());
-    todo_wine
     ok(present, "DACL not present\n");
 
     if (present)
@@ -7307,7 +7306,7 @@ static void test_token_security_descriptor(void)
                 ok(ret, "GetAce failed with error %u\n", GetLastError());
                 ok(ace->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
                    "Unexpected ACE type %#x\n", ace->Header.AceType);
-                todo_wine ok(EqualSid(&ace->SidStart, &medium_level),
+                ok(EqualSid(&ace->SidStart, &medium_level),
                    "Expected medium integrity level\n");
             }
 
@@ -7360,8 +7359,8 @@ static void test_token_security_descriptor(void)
             sacl = NULL;
             ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
             ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
-            todo_wine ok(present, "No SACL in the security descriptor\n");
-            todo_wine ok(sacl != NULL, "NULL SACL in the security descriptor\n");
+            ok(present, "No SACL in the security descriptor\n");
+            ok(sacl != NULL, "NULL SACL in the security descriptor\n");
 
             if (sacl)
             {
@@ -7410,8 +7409,8 @@ static void test_token_security_descriptor(void)
             sacl = NULL;
             ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
             ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
-            todo_wine ok(present, "No SACL in the security descriptor\n");
-            todo_wine ok(sacl != NULL, "NULL SACL in the security descriptor\n");
+            ok(present, "No SACL in the security descriptor\n");
+            ok(sacl != NULL, "NULL SACL in the security descriptor\n");
 
             if (sacl)
             {
@@ -7475,8 +7474,8 @@ static void test_token_security_descriptor(void)
 
         ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
         ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
-        todo_wine ok(present, "No SACL in the security descriptor\n");
-        todo_wine ok(sacl != NULL, "NULL SACL in the security descriptor\n");
+        ok(present, "No SACL in the security descriptor\n");
+        ok(sacl != NULL, "NULL SACL in the security descriptor\n");
 
         if (sacl)
         {
@@ -7513,8 +7512,8 @@ static void test_token_security_descriptor(void)
         sacl = NULL;
         ret = GetSecurityDescriptorSacl(sd3, &present, &sacl, &defaulted);
         ok(ret, "GetSecurityDescriptorSacl failed with error %u\n", GetLastError());
-        todo_wine ok(present, "No SACL in the security descriptor\n");
-        todo_wine ok(sacl != NULL, "NULL SACL in the security descriptor\n");
+        ok(present, "No SACL in the security descriptor\n");
+        ok(sacl != NULL, "NULL SACL in the security descriptor\n");
 
         if (sacl)
         {
@@ -7732,7 +7731,7 @@ static void test_child_token_sd_medium(void)
     ok(ret, "GetAce failed with error %u\n", GetLastError());
     ok(ace_label->Header.AceType == SYSTEM_MANDATORY_LABEL_ACE_TYPE,
        "Unexpected ACE type %#x\n", ace_label->Header.AceType);
-    todo_wine ok(EqualSid(&ace_label->SidStart, &medium_level),
+    ok(EqualSid(&ace_label->SidStart, &medium_level),
        "Expected medium integrity level\n");
 
     memset(buffer_integrity, 0, sizeof(buffer_integrity));
diff --git a/server/process.c b/server/process.c
index b7c9da3..250f777 100644
--- a/server/process.c
+++ b/server/process.c
@@ -562,17 +562,11 @@ struct process *create_process( int fd, struct thread *parent_thread, int inheri
                                        : 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( token ? token : parent->token, TRUE, 0, NULL, NULL, 0, NULL, 0 );
+        process->token = token_duplicate( token ? token : parent->token, TRUE, 0, NULL, NULL, 0, NULL, 0, NULL );
         process->affinity = parent->affinity;
     }
     if (!process->handles || !process->token) goto error;
 
-    /* Assign a high security label to the token. The default would be medium
-     * but Wine provides admin access to all applications right now so high
-     * makes more sense for the time being. */
-    if (!token_assign_label( process->token, security_high_label_sid ))
-        goto error;
-
     set_fd_events( process->msg_fd, POLLIN );  /* start listening to events */
     return process;
 
diff --git a/server/security.h b/server/security.h
index 32dfe5f..87377cc 100644
--- a/server/security.h
+++ b/server/security.h
@@ -59,7 +59,7 @@ 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,
                                       const LUID_AND_ATTRIBUTES *filter_privileges, unsigned int priv_count,
-                                      const SID *filter_groups, unsigned int group_count );
+                                      const SID *filter_groups, unsigned int group_count, struct token *impersonation );
 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 5db97b4..bd251c7 100644
--- a/server/token.c
+++ b/server/token.c
@@ -668,7 +668,7 @@ static int filter_privilege( struct privilege *privilege, const LUID_AND_ATTRIBU
 struct token *token_duplicate( struct token *src_token, unsigned primary,
                                int impersonation_level, const struct security_descriptor *sd,
                                const LUID_AND_ATTRIBUTES *filter_privileges, unsigned int priv_count,
-                               const SID *filter_groups, unsigned int group_count)
+                               const SID *filter_groups, unsigned int group_count, struct token *impersonation)
 {
     const luid_t *modified_id =
         primary || (impersonation_level == src_token->impersonation_level) ?
@@ -735,6 +735,12 @@ struct token *token_duplicate( struct token *src_token, unsigned primary,
     if (sd) default_set_sd( &token->obj, sd, OWNER_SECURITY_INFORMATION | GROUP_SECURITY_INFORMATION |
                             DACL_SECURITY_INFORMATION | SACL_SECURITY_INFORMATION );
 
+    if (!token_assign_label( token, impersonation ? (PSID)impersonation->integrity : (PSID)token->integrity ))
+    {
+        release_object( token );
+        return NULL;
+    }
+
     return token;
 }
 
@@ -906,6 +912,12 @@ struct token *token_create_admin( void )
                               admin_source, NULL, -1, TokenElevationTypeFull, &high_label_sid );
         /* we really need a primary group */
         assert( token->primary_group );
+
+        if (!token_assign_label( token, (PSID)token->integrity ))
+        {
+            release_object( token );
+            token = NULL;
+        }
     }
 
     free( logon_sid );
@@ -964,6 +976,12 @@ static struct token *token_create_limited( void )
                               admin_source, NULL, -1, TokenElevationTypeLimited, &medium_label_sid );
         /* we really need a primary group */
         assert( token->primary_group );
+
+        if (!token_assign_label( token, (PSID)token->integrity ))
+        {
+            release_object( token );
+            token = NULL;
+        }
     }
 
     free( logon_sid );
@@ -1432,7 +1450,8 @@ DECL_HANDLER(duplicate_token)
                                                      TOKEN_DUPLICATE,
                                                      &token_ops )))
     {
-        struct token *token = token_duplicate( src_token, req->primary, req->impersonation_level, sd, NULL, 0, NULL, 0 );
+        struct token *token = token_duplicate( src_token, req->primary, req->impersonation_level, sd, NULL, 0,
+                                               NULL, 0, thread_get_impersonation_token( current ) );
         if (token)
         {
             unsigned int access = req->access ? req->access : get_handle_access( current->process, req->handle );
@@ -1462,7 +1481,7 @@ DECL_HANDLER(filter_token)
         group_count = get_sid_count( filter_groups, get_req_data_size() - priv_count * sizeof(LUID_AND_ATTRIBUTES) );
 
         token = token_duplicate( src_token, src_token->primary, src_token->impersonation_level, NULL,
-                                 filter_privileges, priv_count, filter_groups, group_count );
+                                 filter_privileges, priv_count, filter_groups, group_count, thread_get_impersonation_token( current ) );
         if (token)
         {
             unsigned int access = get_handle_access( current->process, req->handle );
@@ -1788,23 +1807,11 @@ DECL_HANDLER(set_token_default_dacl)
 DECL_HANDLER(create_token)
 {
     struct token *token;
-    PSID label;
-
-    if (req->admin)
-    {
-        token = token_create_admin();
-        label = security_high_label_sid;
-    }
-    else
-    {
-        token = token_create_limited();
-        label = security_medium_label_sid;
-    }
 
+    token = req->admin ? token_create_admin() : token_create_limited();
     if (token)
     {
-        if (token_assign_label( token, label ))
-            reply->token = alloc_handle( current->process, token, TOKEN_ALL_ACCESS, 0 );
+        reply->token = alloc_handle( current->process, token, TOKEN_ALL_ACCESS, 0 );
         release_object( token );
     }
 }
-- 
2.7.4

