[PATCH v3 4/5] ntdll: Implement NtQueryInformationToken(TokenLinkedToken).

Zebediah Figura z.figura12 at gmail.com
Tue Feb 16 23:31:12 CST 2021


Signed-off-by: Zebediah Figura <z.figura12 at gmail.com>
---
 dlls/advapi32/tests/security.c | 11 +++++------
 dlls/ntdll/unix/security.c     | 14 +++++++++++++-
 server/process.c               |  2 +-
 server/protocol.def            |  8 ++++++++
 server/security.h              |  2 +-
 server/token.c                 | 31 +++++++++++++++++++++++++++++--
 6 files changed, 57 insertions(+), 11 deletions(-)

diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c
index 816b6418f03..8fddd635f55 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -8057,8 +8057,7 @@ static void test_elevation(void)
         CloseHandle(token);
         return;
     }
-    todo_wine ok(ret, "got error %u\n", GetLastError());
-    if (!ret) return;
+    ok(ret, "got error %u\n", GetLastError());
 
     if (type == TokenElevationTypeDefault)
     {
@@ -8131,7 +8130,7 @@ static void test_elevation(void)
         ok(type == TokenElevationTypeLimited, "got type %#x\n", type);
         ret = GetTokenInformation(linked.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size);
         ok(ret, "got error %u\n", GetLastError());
-        ok(elevation.TokenIsElevated == FALSE, "got elevation %#x\n", elevation.TokenIsElevated);
+        todo_wine ok(elevation.TokenIsElevated == FALSE, "got elevation %#x\n", elevation.TokenIsElevated);
 
         /* Asking for the linked token again gives us a different token. */
         ret = GetTokenInformation(token, TokenLinkedToken, &linked2, sizeof(linked2), &size);
@@ -8142,7 +8141,7 @@ static void test_elevation(void)
         ok(type == TokenElevationTypeLimited, "got type %#x\n", type);
         ret = GetTokenInformation(linked2.LinkedToken, TokenElevation, &elevation, sizeof(elevation), &size);
         ok(ret, "got error %u\n", GetLastError());
-        ok(elevation.TokenIsElevated == FALSE, "got elevation %#x\n", elevation.TokenIsElevated);
+        todo_wine ok(elevation.TokenIsElevated == FALSE, "got elevation %#x\n", elevation.TokenIsElevated);
 
         check_different_token(linked.LinkedToken, linked2.LinkedToken);
 
@@ -8168,12 +8167,12 @@ static void test_elevation(void)
         type = TokenElevationTypeLimited;
         ret = SetTokenInformation(token, TokenElevationType, &type, sizeof(type));
         ok(!ret, "expected failure\n");
-        ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %u\n", GetLastError());
+        todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %u\n", GetLastError());
 
         elevation.TokenIsElevated = FALSE;
         ret = SetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation));
         ok(!ret, "expected failure\n");
-        ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %u\n", GetLastError());
+        todo_wine ok(GetLastError() == ERROR_INVALID_PARAMETER, "got error %u\n", GetLastError());
     }
 
     ret = DuplicateTokenEx(token, TOKEN_ALL_ACCESS, NULL, SecurityAnonymous, TokenPrimary, &token2);
diff --git a/dlls/ntdll/unix/security.c b/dlls/ntdll/unix/security.c
index 04f1b43a5cb..c8cd04b70f3 100644
--- a/dlls/ntdll/unix/security.c
+++ b/dlls/ntdll/unix/security.c
@@ -167,7 +167,7 @@ NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS c
         0,    /* TokenAuditPolicy */
         0,    /* TokenOrigin */
         sizeof(TOKEN_ELEVATION_TYPE), /* TokenElevationType */
-        0,    /* TokenLinkedToken */
+        sizeof(TOKEN_LINKED_TOKEN), /* TokenLinkedToken */
         sizeof(TOKEN_ELEVATION), /* TokenElevation */
         0,    /* TokenHasRestrictions */
         0,    /* TokenAccessInformation */
@@ -476,6 +476,18 @@ NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS c
         SERVER_END_REQ;
         break;
 
+    case TokenLinkedToken:
+        SERVER_START_REQ( create_linked_token )
+        {
+            TOKEN_LINKED_TOKEN *linked = info;
+
+            req->handle = wine_server_obj_handle( token );
+            status = wine_server_call( req );
+            if (!status) linked->LinkedToken = wine_server_ptr_handle( reply->linked );
+        }
+        SERVER_END_REQ;
+        break;
+
     default:
         ERR( "Unhandled token information class %u\n", class );
         return STATUS_NOT_IMPLEMENTED;
diff --git a/server/process.c b/server/process.c
index 78821593da0..e5fe7cc6b6e 100644
--- a/server/process.c
+++ b/server/process.c
@@ -578,7 +578,7 @@ struct process *create_process( int fd, struct process *parent, int inherit_all,
     if (!parent)
     {
         process->handles = alloc_handle_table( process, 0 );
-        process->token = token_create_admin();
+        process->token = token_create_admin( TokenElevationTypeFull );
         process->affinity = ~0;
     }
     else
diff --git a/server/protocol.def b/server/protocol.def
index 43899bee240..2641ac86ee8 100644
--- a/server/protocol.def
+++ b/server/protocol.def
@@ -3441,6 +3441,14 @@ struct handle_info
 @END
 
 
+/* Create a token which is an elevation counterpart to this token */
+ at REQ(create_linked_token)
+    obj_handle_t   handle;        /* handle to the token */
+ at REPLY
+    obj_handle_t   linked;        /* handle to the linked token */
+ at END
+
+
 /* Create I/O completion port */
 @REQ(create_completion)
     unsigned int access;          /* desired access to a port */
diff --git a/server/security.h b/server/security.h
index 08bdb8de805..416e1b6902d 100644
--- a/server/security.h
+++ b/server/security.h
@@ -54,7 +54,7 @@ extern const PSID security_high_label_sid;
 /* token functions */
 
 extern struct token *get_token_obj( struct process *process, obj_handle_t handle, unsigned int access );
-extern struct token *token_create_admin(void);
+extern struct token *token_create_admin( int elevation );
 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,
diff --git a/server/token.c b/server/token.c
index 5499841dd50..6cdeeacca71 100644
--- a/server/token.c
+++ b/server/token.c
@@ -830,7 +830,7 @@ struct token *get_token_obj( struct process *process, obj_handle_t handle, unsig
     return (struct token *)get_handle_obj( process, handle, access, &token_ops );
 }
 
-struct token *token_create_admin( void )
+struct token *token_create_admin( int elevation )
 {
     struct token *token = NULL;
     static const SID_IDENTIFIER_AUTHORITY nt_authority = { SECURITY_NT_AUTHORITY };
@@ -892,7 +892,7 @@ struct token *token_create_admin( void )
         static const TOKEN_SOURCE admin_source = {"SeMgr", {0, 0}};
         token = create_token( TRUE, user_sid, admin_groups, ARRAY_SIZE( admin_groups ),
                               admin_privs, ARRAY_SIZE( admin_privs ), default_dacl,
-                              admin_source, NULL, -1, TokenElevationTypeFull );
+                              admin_source, NULL, -1, elevation );
         /* we really need a primary group */
         assert( token->primary_group );
     }
@@ -1679,3 +1679,30 @@ DECL_HANDLER(get_token_elevation)
         release_object( token );
     }
 }
+
+DECL_HANDLER(create_linked_token)
+{
+    struct token *token, *linked;
+
+    if ((token = (struct token *)get_handle_obj( current->process, req->handle,
+                                                 TOKEN_QUERY, &token_ops )))
+    {
+        if (token->elevation == TokenElevationTypeFull)
+        {
+            linked = token_create_admin( TokenElevationTypeLimited );
+            reply->linked = alloc_handle( current->process, linked, TOKEN_ALL_ACCESS, 0 );
+            release_object( linked );
+        }
+        else if (token->elevation == TokenElevationTypeLimited)
+        {
+            linked = token_create_admin( TokenElevationTypeFull );
+            reply->linked = alloc_handle( current->process, linked, TOKEN_ALL_ACCESS, 0 );
+            release_object( linked );
+        }
+        else
+        {
+            reply->linked = 0;
+        }
+        release_object( token );
+    }
+}
-- 
2.20.1




More information about the wine-devel mailing list