Module: wine Branch: master Commit: c96749790b064a08ce866b459acce70c12c78a71 URL: https://source.winehq.org/git/wine.git/?a=commit;h=c96749790b064a08ce866b459...
Author: Zebediah Figura z.figura12@gmail.com Date: Tue Feb 16 23:31:11 2021 -0600
ntdll: Implement NtQueryInformationToken(TokenElevationType).
Signed-off-by: Zebediah Figura z.figura12@gmail.com Signed-off-by: Alexandre Julliard julliard@winehq.org
---
dlls/ntdll/unix/security.c | 8 ++++++-- include/wine/server_protocol.h | 19 ++++++++++++++++++- server/protocol.def | 8 ++++++++ server/request.h | 6 ++++++ server/token.c | 20 +++++++++++++++++--- server/trace.c | 13 +++++++++++++ 6 files changed, 68 insertions(+), 6 deletions(-)
diff --git a/dlls/ntdll/unix/security.c b/dlls/ntdll/unix/security.c index fc9cc9d4572..04f1b43a5cb 100644 --- a/dlls/ntdll/unix/security.c +++ b/dlls/ntdll/unix/security.c @@ -391,11 +391,15 @@ NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS c break;
case TokenElevationType: + SERVER_START_REQ( get_token_elevation ) { TOKEN_ELEVATION_TYPE *type = info; - FIXME("QueryInformationToken( ..., TokenElevationType, ...) semi-stub\n"); - *type = TokenElevationTypeFull; + + req->handle = wine_server_obj_handle( token ); + status = wine_server_call( req ); + if (!status) *type = reply->elevation; } + SERVER_END_REQ; break;
case TokenElevation: diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index ec34867caf1..bf9536ddcc8 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -4936,6 +4936,20 @@ struct get_token_statistics_reply
+struct get_token_elevation_request +{ + struct request_header __header; + obj_handle_t handle; +}; +struct get_token_elevation_reply +{ + struct reply_header __header; + int elevation; + char __pad_12[4]; +}; + + + struct create_completion_request { struct request_header __header; @@ -5627,6 +5641,7 @@ enum request REQ_get_kernel_object_handle, REQ_make_process_system, REQ_get_token_statistics, + REQ_get_token_elevation, REQ_create_completion, REQ_open_completion, REQ_add_completion, @@ -5908,6 +5923,7 @@ union generic_request struct get_kernel_object_handle_request get_kernel_object_handle_request; struct make_process_system_request make_process_system_request; struct get_token_statistics_request get_token_statistics_request; + struct get_token_elevation_request get_token_elevation_request; struct create_completion_request create_completion_request; struct open_completion_request open_completion_request; struct add_completion_request add_completion_request; @@ -6187,6 +6203,7 @@ union generic_reply struct get_kernel_object_handle_reply get_kernel_object_handle_reply; struct make_process_system_reply make_process_system_reply; struct get_token_statistics_reply get_token_statistics_reply; + struct get_token_elevation_reply get_token_elevation_reply; struct create_completion_reply create_completion_reply; struct open_completion_reply open_completion_reply; struct add_completion_reply add_completion_reply; @@ -6220,7 +6237,7 @@ union generic_reply
/* ### protocol_version begin ### */
-#define SERVER_PROTOCOL_VERSION 678 +#define SERVER_PROTOCOL_VERSION 679
/* ### protocol_version end ### */
diff --git a/server/protocol.def b/server/protocol.def index fb3ee3a52de..43899bee240 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3433,6 +3433,14 @@ struct handle_info @END
+/* Get the token elevation type */ +@REQ(get_token_elevation) + obj_handle_t handle; /* handle to the token */ +@REPLY + int elevation; /* token elevation type */ +@END + + /* Create I/O completion port */ @REQ(create_completion) unsigned int access; /* desired access to a port */ diff --git a/server/request.h b/server/request.h index d1ff4cc7a82..4313b42ca52 100644 --- a/server/request.h +++ b/server/request.h @@ -364,6 +364,7 @@ DECL_HANDLER(release_kernel_object); DECL_HANDLER(get_kernel_object_handle); DECL_HANDLER(make_process_system); DECL_HANDLER(get_token_statistics); +DECL_HANDLER(get_token_elevation); DECL_HANDLER(create_completion); DECL_HANDLER(open_completion); DECL_HANDLER(add_completion); @@ -644,6 +645,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_get_kernel_object_handle, (req_handler)req_make_process_system, (req_handler)req_get_token_statistics, + (req_handler)req_get_token_elevation, (req_handler)req_create_completion, (req_handler)req_open_completion, (req_handler)req_add_completion, @@ -2105,6 +2107,10 @@ C_ASSERT( FIELD_OFFSET(struct get_token_statistics_reply, impersonation_level) = C_ASSERT( FIELD_OFFSET(struct get_token_statistics_reply, group_count) == 32 ); C_ASSERT( FIELD_OFFSET(struct get_token_statistics_reply, privilege_count) == 36 ); C_ASSERT( sizeof(struct get_token_statistics_reply) == 40 ); +C_ASSERT( FIELD_OFFSET(struct get_token_elevation_request, handle) == 12 ); +C_ASSERT( sizeof(struct get_token_elevation_request) == 16 ); +C_ASSERT( FIELD_OFFSET(struct get_token_elevation_reply, elevation) == 8 ); +C_ASSERT( sizeof(struct get_token_elevation_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct create_completion_request, access) == 12 ); C_ASSERT( FIELD_OFFSET(struct create_completion_request, concurrent) == 16 ); C_ASSERT( sizeof(struct create_completion_request) == 24 ); diff --git a/server/token.c b/server/token.c index 2ae1cb1780a..5499841dd50 100644 --- a/server/token.c +++ b/server/token.c @@ -126,6 +126,7 @@ struct token ACL *default_dacl; /* the default DACL to assign to objects created by this user */ TOKEN_SOURCE source; /* source of the token */ int impersonation_level; /* impersonation level this token is capable of if non-primary token */ + int elevation; /* elevation type */ };
struct privilege @@ -541,7 +542,7 @@ static struct token *create_token( unsigned primary, const SID *user, const LUID_AND_ATTRIBUTES *privs, unsigned int priv_count, const ACL *default_dacl, TOKEN_SOURCE source, const luid_t *modified_id, - int impersonation_level ) + int impersonation_level, int elevation ) { struct token *token = alloc_object( &token_ops ); if (token) @@ -563,6 +564,7 @@ static struct token *create_token( unsigned primary, const SID *user, token->impersonation_level = impersonation_level; token->default_dacl = NULL; token->primary_group = NULL; + token->elevation = elevation;
/* copy user */ token->user = memdup( user, security_sid_len( user )); @@ -678,7 +680,7 @@ struct token *token_duplicate( struct token *src_token, unsigned primary, token = create_token( primary, src_token->user, NULL, 0, NULL, 0, src_token->default_dacl, src_token->source, modified_id, - impersonation_level ); + impersonation_level, src_token->elevation ); if (!token) return token;
/* copy groups */ @@ -890,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 ); + admin_source, NULL, -1, TokenElevationTypeFull ); /* we really need a primary group */ assert( token->primary_group ); } @@ -1665,3 +1667,15 @@ DECL_HANDLER(set_token_default_dacl) release_object( token ); } } + +DECL_HANDLER(get_token_elevation) +{ + struct token *token; + + if ((token = (struct token *)get_handle_obj( current->process, req->handle, + TOKEN_QUERY, &token_ops ))) + { + reply->elevation = token->elevation; + release_object( token ); + } +} diff --git a/server/trace.c b/server/trace.c index 4e83550d028..128dd1191f8 100644 --- a/server/trace.c +++ b/server/trace.c @@ -4184,6 +4184,16 @@ static void dump_get_token_statistics_reply( const struct get_token_statistics_r fprintf( stderr, ", privilege_count=%d", req->privilege_count ); }
+static void dump_get_token_elevation_request( const struct get_token_elevation_request *req ) +{ + fprintf( stderr, " handle=%04x", req->handle ); +} + +static void dump_get_token_elevation_reply( const struct get_token_elevation_reply *req ) +{ + fprintf( stderr, " elevation=%d", req->elevation ); +} + static void dump_create_completion_request( const struct create_completion_request *req ) { fprintf( stderr, " access=%08x", req->access ); @@ -4696,6 +4706,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_get_kernel_object_handle_request, (dump_func)dump_make_process_system_request, (dump_func)dump_get_token_statistics_request, + (dump_func)dump_get_token_elevation_request, (dump_func)dump_create_completion_request, (dump_func)dump_open_completion_request, (dump_func)dump_add_completion_request, @@ -4973,6 +4984,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_get_kernel_object_handle_reply, (dump_func)dump_make_process_system_reply, (dump_func)dump_get_token_statistics_reply, + (dump_func)dump_get_token_elevation_reply, (dump_func)dump_create_completion_reply, (dump_func)dump_open_completion_reply, NULL, @@ -5250,6 +5262,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "get_kernel_object_handle", "make_process_system", "get_token_statistics", + "get_token_elevation", "create_completion", "open_completion", "add_completion",