diff --git a/dlls/ntdll/nt.c b/dlls/ntdll/nt.c index b29a8ae0797..bc01a4f3d5e 100644 --- a/dlls/ntdll/nt.c +++ b/dlls/ntdll/nt.c @@ -257,12 +257,6 @@ NTSTATUS WINAPI NtQueryInformationToken( switch (tokeninfoclass) { - case TokenOwner: - len = sizeof(TOKEN_OWNER) + sizeof(SID); - break; - case TokenPrimaryGroup: - len = sizeof(TOKEN_PRIMARY_GROUP); - break; case TokenSource: len = sizeof(TOKEN_SOURCE); break; @@ -287,16 +281,17 @@ NTSTATUS WINAPI NtQueryInformationToken( switch (tokeninfoclass) { case TokenUser: - SERVER_START_REQ( get_token_user ) + SERVER_START_REQ( get_token_sid ) { TOKEN_USER * tuser = tokeninfo; PSID sid = tuser + 1; DWORD sid_len = tokeninfolength < sizeof(TOKEN_USER) ? 0 : tokeninfolength - sizeof(TOKEN_USER); req->handle = wine_server_obj_handle( token ); + req->which_sid = tokeninfoclass; wine_server_set_reply( req, sid, sid_len ); status = wine_server_call( req ); - if (retlen) *retlen = reply->user_len + sizeof(TOKEN_USER); + if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_USER); if (status == STATUS_SUCCESS) { tuser->User.Sid = sid; @@ -372,17 +367,21 @@ NTSTATUS WINAPI NtQueryInformationToken( break; } case TokenPrimaryGroup: - if (tokeninfo) + SERVER_START_REQ( get_token_sid ) { TOKEN_PRIMARY_GROUP *tgroup = tokeninfo; - SID_IDENTIFIER_AUTHORITY sid = {SECURITY_NT_AUTHORITY}; - RtlAllocateAndInitializeSid( &sid, - 2, - SECURITY_BUILTIN_DOMAIN_RID, - DOMAIN_ALIAS_RID_ADMINS, - 0, 0, 0, 0, 0, 0, - &(tgroup->PrimaryGroup)); + PSID sid = tgroup + 1; + DWORD sid_len = tokeninfolength < sizeof(TOKEN_PRIMARY_GROUP) ? 0 : tokeninfolength - sizeof(TOKEN_PRIMARY_GROUP); + + req->handle = wine_server_obj_handle( token ); + req->which_sid = tokeninfoclass; + wine_server_set_reply( req, sid, sid_len ); + status = wine_server_call( req ); + if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_PRIMARY_GROUP); + if (status == STATUS_SUCCESS) + tgroup->PrimaryGroup = sid; } + SERVER_END_REQ; break; case TokenPrivileges: SERVER_START_REQ( get_token_privileges ) @@ -398,15 +397,21 @@ NTSTATUS WINAPI NtQueryInformationToken( SERVER_END_REQ; break; case TokenOwner: - if (tokeninfo) + SERVER_START_REQ( get_token_sid ) { - TOKEN_OWNER *owner = tokeninfo; - PSID sid = owner + 1; - SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY}; - RtlInitializeSid(sid, &localSidAuthority, 1); - *(RtlSubAuthoritySid(sid, 0)) = SECURITY_INTERACTIVE_RID; - owner->Owner = sid; + TOKEN_OWNER *towner = tokeninfo; + PSID sid = towner + 1; + DWORD sid_len = tokeninfolength < sizeof(TOKEN_OWNER) ? 0 : tokeninfolength - sizeof(TOKEN_OWNER); + + req->handle = wine_server_obj_handle( token ); + req->which_sid = tokeninfoclass; + wine_server_set_reply( req, sid, sid_len ); + status = wine_server_call( req ); + if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_OWNER); + if (status == STATUS_SUCCESS) + towner->Owner = sid; } + SERVER_END_REQ; break; case TokenImpersonationLevel: SERVER_START_REQ( get_token_impersonation_level ) diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index fd52bfbf15d..6a860dfc53a 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -4123,16 +4123,17 @@ struct access_check_reply char __pad_20[4]; }; -struct get_token_user_request +struct get_token_sid_request { struct request_header __header; obj_handle_t handle; + unsigned int which_sid; }; -struct get_token_user_reply +struct get_token_sid_reply { struct reply_header __header; - data_size_t user_len; - /* VARARG(user,SID); */ + data_size_t sid_len; + /* VARARG(sid,SID); */ char __pad_12[4]; }; @@ -4862,7 +4863,7 @@ enum request REQ_check_token_privileges, REQ_duplicate_token, REQ_access_check, - REQ_get_token_user, + REQ_get_token_sid, REQ_get_token_groups, REQ_get_token_default_dacl, REQ_set_token_default_dacl, @@ -5110,7 +5111,7 @@ union generic_request struct check_token_privileges_request check_token_privileges_request; struct duplicate_token_request duplicate_token_request; struct access_check_request access_check_request; - struct get_token_user_request get_token_user_request; + struct get_token_sid_request get_token_sid_request; struct get_token_groups_request get_token_groups_request; struct get_token_default_dacl_request get_token_default_dacl_request; struct set_token_default_dacl_request set_token_default_dacl_request; @@ -5356,7 +5357,7 @@ union generic_reply struct check_token_privileges_reply check_token_privileges_reply; struct duplicate_token_reply duplicate_token_reply; struct access_check_reply access_check_reply; - struct get_token_user_reply get_token_user_reply; + struct get_token_sid_reply get_token_sid_reply; struct get_token_groups_reply get_token_groups_reply; struct get_token_default_dacl_reply get_token_default_dacl_reply; struct set_token_default_dacl_reply set_token_default_dacl_reply; @@ -5393,6 +5394,6 @@ union generic_reply struct free_user_handle_reply free_user_handle_reply; }; -#define SERVER_PROTOCOL_VERSION 393 +#define SERVER_PROTOCOL_VERSION 394 #endif /* __WINE_WINE_SERVER_PROTOCOL_H */ diff --git a/server/protocol.def b/server/protocol.def index ca44e380a6a..bba6788da3d 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -2924,18 +2924,19 @@ enum message_type VARARG(privileges,LUID_AND_ATTRIBUTES); /* privileges used during access check */ @END -@REQ(get_token_user) +@REQ(get_token_sid) obj_handle_t handle; /* handle to the token */ + unsigned int which_sid; /* which SID to retrieve from the token */ @REPLY - data_size_t user_len; /* length needed to store user */ - VARARG(user,SID); /* sid of the user the token represents */ + data_size_t sid_len; /* length needed to store sid */ + VARARG(sid,SID); /* the sid specified by which_sid from the token */ @END @REQ(get_token_groups) obj_handle_t handle; /* handle to the token */ @REPLY data_size_t user_len; /* length needed to store user */ - VARARG(user,token_groups); /* groups the token's user belongs to */ + VARARG(user,token_groups); /* groups the token's user belongs to */ @END @REQ(get_token_default_dacl) diff --git a/server/request.h b/server/request.h index 8aa8a9d246a..ca5fc88ed30 100644 --- a/server/request.h +++ b/server/request.h @@ -317,7 +317,7 @@ DECL_HANDLER(get_token_privileges); DECL_HANDLER(check_token_privileges); DECL_HANDLER(duplicate_token); DECL_HANDLER(access_check); -DECL_HANDLER(get_token_user); +DECL_HANDLER(get_token_sid); DECL_HANDLER(get_token_groups); DECL_HANDLER(get_token_default_dacl); DECL_HANDLER(set_token_default_dacl); @@ -564,7 +564,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = (req_handler)req_check_token_privileges, (req_handler)req_duplicate_token, (req_handler)req_access_check, - (req_handler)req_get_token_user, + (req_handler)req_get_token_sid, (req_handler)req_get_token_groups, (req_handler)req_get_token_default_dacl, (req_handler)req_set_token_default_dacl, @@ -1755,9 +1755,10 @@ C_ASSERT( FIELD_OFFSET(struct access_check_reply, access_granted) == 8 ); C_ASSERT( FIELD_OFFSET(struct access_check_reply, access_status) == 12 ); C_ASSERT( FIELD_OFFSET(struct access_check_reply, privileges_len) == 16 ); C_ASSERT( sizeof(struct access_check_reply) == 24 ); -C_ASSERT( FIELD_OFFSET(struct get_token_user_request, handle) == 12 ); -C_ASSERT( FIELD_OFFSET(struct get_token_user_reply, user_len) == 8 ); -C_ASSERT( sizeof(struct get_token_user_reply) == 16 ); +C_ASSERT( FIELD_OFFSET(struct get_token_sid_request, handle) == 12 ); +C_ASSERT( FIELD_OFFSET(struct get_token_sid_request, which_sid) == 16 ); +C_ASSERT( FIELD_OFFSET(struct get_token_sid_reply, sid_len) == 8 ); +C_ASSERT( sizeof(struct get_token_sid_reply) == 16 ); C_ASSERT( FIELD_OFFSET(struct get_token_groups_request, handle) == 12 ); C_ASSERT( FIELD_OFFSET(struct get_token_groups_reply, user_len) == 8 ); C_ASSERT( sizeof(struct get_token_groups_reply) == 16 ); diff --git a/server/token.c b/server/token.c index ce896ac17dc..4c45d50ac77 100644 --- a/server/token.c +++ b/server/token.c @@ -1225,27 +1225,51 @@ DECL_HANDLER(access_check) } /* retrieves the SID of the user that the token represents */ -DECL_HANDLER(get_token_user) +DECL_HANDLER(get_token_sid) { struct token *token; - reply->user_len = 0; + reply->sid_len = 0; if ((token = (struct token *)get_handle_obj( current->process, req->handle, TOKEN_QUERY, &token_ops ))) { - const SID *user = token->user; + const SID *sid = NULL; - reply->user_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]); - if (reply->user_len <= get_reply_max_size()) + switch (req->which_sid) { - SID *user_reply = set_reply_data_size( reply->user_len ); - if (user_reply) - memcpy( user_reply, user, reply->user_len ); + case TokenUser: + assert(token->user); + sid = token->user; + break; + case TokenPrimaryGroup: + sid = token->primary_group; + break; + case TokenOwner: + { + struct group *group; + LIST_FOR_EACH_ENTRY( group, &token->groups, struct group, entry ) + { + if (group->owner) + { + sid = &group->sid; + break; + } + } + break; + } + default: + set_error( STATUS_INVALID_PARAMETER ); + break; } - else set_error( STATUS_BUFFER_TOO_SMALL ); + if (sid) + { + reply->sid_len = FIELD_OFFSET(SID, SubAuthority[sid->SubAuthorityCount]); + if (reply->sid_len <= get_reply_max_size()) set_reply_data( sid, reply->sid_len ); + else set_error( STATUS_BUFFER_TOO_SMALL ); + } release_object( token ); } } diff --git a/server/trace.c b/server/trace.c index a529e5bf9f7..a4b1faac917 100644 --- a/server/trace.c +++ b/server/trace.c @@ -3426,15 +3426,16 @@ static void dump_access_check_reply( const struct access_check_reply *req ) dump_varargs_LUID_AND_ATTRIBUTES( ", privileges=", cur_size ); } -static void dump_get_token_user_request( const struct get_token_user_request *req ) +static void dump_get_token_sid_request( const struct get_token_sid_request *req ) { fprintf( stderr, " handle=%04x", req->handle ); + fprintf( stderr, ", which_sid=%08x", req->which_sid ); } -static void dump_get_token_user_reply( const struct get_token_user_reply *req ) +static void dump_get_token_sid_reply( const struct get_token_sid_reply *req ) { - fprintf( stderr, " user_len=%u", req->user_len ); - dump_varargs_SID( ", user=", cur_size ); + fprintf( stderr, " sid_len=%u", req->sid_len ); + dump_varargs_SID( ", sid=", cur_size ); } static void dump_get_token_groups_request( const struct get_token_groups_request *req ) @@ -4012,7 +4013,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_check_token_privileges_request, (dump_func)dump_duplicate_token_request, (dump_func)dump_access_check_request, - (dump_func)dump_get_token_user_request, + (dump_func)dump_get_token_sid_request, (dump_func)dump_get_token_groups_request, (dump_func)dump_get_token_default_dacl_request, (dump_func)dump_set_token_default_dacl_request, @@ -4256,7 +4257,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = { (dump_func)dump_check_token_privileges_reply, (dump_func)dump_duplicate_token_reply, (dump_func)dump_access_check_reply, - (dump_func)dump_get_token_user_reply, + (dump_func)dump_get_token_sid_reply, (dump_func)dump_get_token_groups_reply, (dump_func)dump_get_token_default_dacl_reply, NULL, @@ -4500,7 +4501,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { "check_token_privileges", "duplicate_token", "access_check", - "get_token_user", + "get_token_sid", "get_token_groups", "get_token_default_dacl", "set_token_default_dacl",