[PATCH 4/5] ntdll: Implement NtQueryInformationToken(TokenLinkedToken).
Zebediah Figura
z.figura12 at gmail.com
Tue Feb 16 21:07:55 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 1cd6e3ccbdc..88d16dbee92 100644
--- a/dlls/advapi32/tests/security.c
+++ b/dlls/advapi32/tests/security.c
@@ -8051,8 +8051,7 @@ static void test_elevation(void)
ret = GetTokenInformation(token, TokenElevation, &elevation, sizeof(elevation), &size);
ok(ret, "got error %u\n", GetLastError());
ret = GetTokenInformation(token, TokenLinkedToken, &linked, sizeof(linked), &size);
- todo_wine ok(ret, "got error %u\n", GetLastError());
- if (!ret) return;
+ ok(ret, "got error %u\n", GetLastError());
if (type == TokenElevationTypeDefault)
{
@@ -8125,7 +8124,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);
@@ -8136,7 +8135,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);
@@ -8162,12 +8161,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