Module: wine Branch: master Commit: 3f431a0646c6bfb333971afcfe0dfeab71a90d3b URL: http://source.winehq.org/git/wine.git/?a=commit;h=3f431a0646c6bfb333971afcfe...
Author: Rob Shearman rob@codeweavers.com Date: Thu Sep 13 16:47:56 2007 +0100
server: Add get_token_statistics server call and use it to implement the TokenStatistics and TokenType levels for NtQueryInformationToken.
---
dlls/kernel32/tests/pipe.c | 1 - dlls/ntdll/nt.c | 44 ++++++++++++++++++++++++++++++++++++++- include/wine/server_protocol.h | 23 ++++++++++++++++++++- server/protocol.def | 13 +++++++++++ server/request.h | 2 + server/token.c | 19 +++++++++++++++++ server/trace.c | 23 ++++++++++++++++++++ 7 files changed, 121 insertions(+), 4 deletions(-)
diff --git a/dlls/kernel32/tests/pipe.c b/dlls/kernel32/tests/pipe.c index 09f406e..9150e50 100644 --- a/dlls/kernel32/tests/pipe.c +++ b/dlls/kernel32/tests/pipe.c @@ -1048,7 +1048,6 @@ static DWORD get_privilege_count(HANDLE hToken) BOOL ret;
ret = GetTokenInformation(hToken, TokenStatistics, &Statistics, Size, &Size); - todo_wine ok(ret, "GetTokenInformation(TokenStatistics)\n"); if (!ret) return -1;
diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index 27a18ef..8354fee 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -230,9 +230,9 @@ NTSTATUS WINAPI NtQueryInformationToken( case TokenImpersonationLevel: len = sizeof(SECURITY_IMPERSONATION_LEVEL); break; -#if 0 case TokenStatistics: -#endif /* 0 */ + len = sizeof(TOKEN_STATISTICS); + break; default: len = 0; } @@ -375,6 +375,46 @@ NTSTATUS WINAPI NtQueryInformationToken( } SERVER_END_REQ; break; + case TokenStatistics: + SERVER_START_REQ( get_token_statistics ) + { + TOKEN_STATISTICS *statistics = tokeninfo; + req->handle = token; + status = wine_server_call( req ); + if (status == STATUS_SUCCESS) + { + statistics->TokenId.LowPart = reply->token_id.low_part; + statistics->TokenId.HighPart = reply->token_id.high_part; + statistics->AuthenticationId.LowPart = 0; /* FIXME */ + statistics->AuthenticationId.HighPart = 0; /* FIXME */ + statistics->ExpirationTime.HighPart = 0x7fffffff; + statistics->ExpirationTime.LowPart = 0xffffffff; + statistics->TokenType = reply->primary ? TokenPrimary : TokenImpersonation; + statistics->ImpersonationLevel = reply->impersonation_level; + + /* kernel information not relevant to us */ + statistics->DynamicCharged = 0; + statistics->DynamicAvailable = 0; + + statistics->GroupCount = reply->group_count; + statistics->PrivilegeCount = reply->privilege_count; + statistics->ModifiedId.LowPart = reply->modified_id.low_part; + statistics->ModifiedId.HighPart = reply->modified_id.high_part; + } + } + SERVER_END_REQ; + break; + case TokenType: + SERVER_START_REQ( get_token_statistics ) + { + TOKEN_TYPE *token_type = tokeninfo; + req->handle = token; + status = wine_server_call( req ); + if (status == STATUS_SUCCESS) + *token_type = reply->primary ? TokenPrimary : TokenImpersonation; + } + SERVER_END_REQ; + break; default: { ERR("Unhandled Token Information class %d!\n", tokeninfoclass); diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index b1f48cb..b79fda4 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -4060,6 +4060,24 @@ struct make_process_system_reply };
+ +struct get_token_statistics_request +{ + struct request_header __header; + obj_handle_t handle; +}; +struct get_token_statistics_reply +{ + struct reply_header __header; + luid_t token_id; + luid_t modified_id; + int primary; + int impersonation_level; + int group_count; + int privilege_count; +}; + + enum request { REQ_new_process, @@ -4281,6 +4299,7 @@ enum request REQ_delete_device, REQ_get_next_device_request, REQ_make_process_system, + REQ_get_token_statistics, REQ_NB_REQUESTS };
@@ -4507,6 +4526,7 @@ union generic_request struct delete_device_request delete_device_request; struct get_next_device_request_request get_next_device_request_request; struct make_process_system_request make_process_system_request; + struct get_token_statistics_request get_token_statistics_request; }; union generic_reply { @@ -4731,8 +4751,9 @@ union generic_reply struct delete_device_reply delete_device_reply; struct get_next_device_request_reply get_next_device_request_reply; struct make_process_system_reply make_process_system_reply; + struct get_token_statistics_reply get_token_statistics_reply; };
-#define SERVER_PROTOCOL_VERSION 312 +#define SERVER_PROTOCOL_VERSION 313
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index e210e43..784a9f9 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2918,3 +2918,16 @@ enum message_type @REPLY obj_handle_t event; /* event signaled when all user processes have exited */ @END + + +/* Get detailed fixed-size information about a token */ +@REQ(get_token_statistics) + obj_handle_t handle; /* handle to the object */ +@REPLY + luid_t token_id; /* locally-unique identifier of the token */ + luid_t modified_id; /* locally-unique identifier of the modified version of the token */ + int primary; /* is the token primary or impersonation? */ + int impersonation_level; /* level of impersonation */ + int group_count; /* the number of groups the token is a member of */ + int privilege_count; /* the number of privileges the token has */ +@END diff --git a/server/request.h b/server/request.h index 12a7b9c..fe94d2e 100644 --- a/server/request.h +++ b/server/request.h @@ -329,6 +329,7 @@ DECL_HANDLER(create_device); DECL_HANDLER(delete_device); DECL_HANDLER(get_next_device_request); DECL_HANDLER(make_process_system); +DECL_HANDLER(get_token_statistics);
#ifdef WANT_REQUEST_HANDLERS
@@ -554,6 +555,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_delete_device, (req_handler)req_get_next_device_request, (req_handler)req_make_process_system, + (req_handler)req_get_token_statistics, }; #endif /* WANT_REQUEST_HANDLERS */
diff --git a/server/token.c b/server/token.c index a97fbde..655e597 100644 --- a/server/token.c +++ b/server/token.c @@ -1424,6 +1424,25 @@ DECL_HANDLER(get_token_impersonation_level) } }
+DECL_HANDLER(get_token_statistics) +{ + struct token *token; + + if ((token = (struct token *)get_handle_obj( current->process, req->handle, + TOKEN_QUERY, + &token_ops ))) + { + reply->token_id = token->token_id; + reply->modified_id = token->modified_id; + reply->primary = token->primary; + reply->impersonation_level = token->impersonation_level; + reply->group_count = list_count( &token->groups ); + reply->privilege_count = list_count( &token->privileges ); + + release_object( token ); + } +} + DECL_HANDLER(set_security_object) { data_size_t sd_size = get_req_data_size(); diff --git a/server/trace.c b/server/trace.c index 49f4479..e6ff06d 100644 --- a/server/trace.c +++ b/server/trace.c @@ -3548,6 +3548,25 @@ static void dump_make_process_system_reply( const struct make_process_system_rep fprintf( stderr, " event=%p", req->event ); }
+static void dump_get_token_statistics_request( const struct get_token_statistics_request *req ) +{ + fprintf( stderr, " handle=%p", req->handle ); +} + +static void dump_get_token_statistics_reply( const struct get_token_statistics_reply *req ) +{ + fprintf( stderr, " token_id=" ); + dump_luid( &req->token_id ); + fprintf( stderr, "," ); + fprintf( stderr, " modified_id=" ); + dump_luid( &req->modified_id ); + fprintf( stderr, "," ); + fprintf( stderr, " primary=%d,", req->primary ); + fprintf( stderr, " impersonation_level=%d,", req->impersonation_level ); + fprintf( stderr, " group_count=%d,", req->group_count ); + fprintf( stderr, " privilege_count=%d", req->privilege_count ); +} + static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_new_process_request, (dump_func)dump_get_new_process_info_request, @@ -3768,6 +3787,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_delete_device_request, (dump_func)dump_get_next_device_request_request, (dump_func)dump_make_process_system_request, + (dump_func)dump_get_token_statistics_request, };
static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { @@ -3990,6 +4010,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)0, (dump_func)dump_get_next_device_request_reply, (dump_func)dump_make_process_system_reply, + (dump_func)dump_get_token_statistics_reply, };
static const char * const req_names[REQ_NB_REQUESTS] = { @@ -4212,6 +4233,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "delete_device", "get_next_device_request", "make_process_system", + "get_token_statistics", };
static const struct @@ -4233,6 +4255,7 @@ static const struct { "CANCELLED", STATUS_CANCELLED }, { "CANT_OPEN_ANONYMOUS", STATUS_CANT_OPEN_ANONYMOUS }, { "CHILD_MUST_BE_VOLATILE", STATUS_CHILD_MUST_BE_VOLATILE }, + { "DEBUGGER_INACTIVE", STATUS_DEBUGGER_INACTIVE }, { "DEVICE_BUSY", STATUS_DEVICE_BUSY }, { "DIRECTORY_NOT_EMPTY", STATUS_DIRECTORY_NOT_EMPTY }, { "DISK_FULL", STATUS_DISK_FULL },