Commit bd56916f authored by Rob Shearman's avatar Rob Shearman Committed by Alexandre Julliard

server: Extend get_token_user server call to also retrieve SIDs for the token's…

server: Extend get_token_user server call to also retrieve SIDs for the token's owner or primary group.
parent 184f1fe3
...@@ -257,12 +257,6 @@ NTSTATUS WINAPI NtQueryInformationToken( ...@@ -257,12 +257,6 @@ NTSTATUS WINAPI NtQueryInformationToken(
switch (tokeninfoclass) switch (tokeninfoclass)
{ {
case TokenOwner:
len = sizeof(TOKEN_OWNER) + sizeof(SID);
break;
case TokenPrimaryGroup:
len = sizeof(TOKEN_PRIMARY_GROUP);
break;
case TokenSource: case TokenSource:
len = sizeof(TOKEN_SOURCE); len = sizeof(TOKEN_SOURCE);
break; break;
...@@ -287,16 +281,17 @@ NTSTATUS WINAPI NtQueryInformationToken( ...@@ -287,16 +281,17 @@ NTSTATUS WINAPI NtQueryInformationToken(
switch (tokeninfoclass) switch (tokeninfoclass)
{ {
case TokenUser: case TokenUser:
SERVER_START_REQ( get_token_user ) SERVER_START_REQ( get_token_sid )
{ {
TOKEN_USER * tuser = tokeninfo; TOKEN_USER * tuser = tokeninfo;
PSID sid = tuser + 1; PSID sid = tuser + 1;
DWORD sid_len = tokeninfolength < sizeof(TOKEN_USER) ? 0 : tokeninfolength - sizeof(TOKEN_USER); DWORD sid_len = tokeninfolength < sizeof(TOKEN_USER) ? 0 : tokeninfolength - sizeof(TOKEN_USER);
req->handle = wine_server_obj_handle( token ); req->handle = wine_server_obj_handle( token );
req->which_sid = tokeninfoclass;
wine_server_set_reply( req, sid, sid_len ); wine_server_set_reply( req, sid, sid_len );
status = wine_server_call( req ); 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) if (status == STATUS_SUCCESS)
{ {
tuser->User.Sid = sid; tuser->User.Sid = sid;
...@@ -372,17 +367,21 @@ NTSTATUS WINAPI NtQueryInformationToken( ...@@ -372,17 +367,21 @@ NTSTATUS WINAPI NtQueryInformationToken(
break; break;
} }
case TokenPrimaryGroup: case TokenPrimaryGroup:
if (tokeninfo) SERVER_START_REQ( get_token_sid )
{ {
TOKEN_PRIMARY_GROUP *tgroup = tokeninfo; TOKEN_PRIMARY_GROUP *tgroup = tokeninfo;
SID_IDENTIFIER_AUTHORITY sid = {SECURITY_NT_AUTHORITY}; PSID sid = tgroup + 1;
RtlAllocateAndInitializeSid( &sid, DWORD sid_len = tokeninfolength < sizeof(TOKEN_PRIMARY_GROUP) ? 0 : tokeninfolength - sizeof(TOKEN_PRIMARY_GROUP);
2,
SECURITY_BUILTIN_DOMAIN_RID, req->handle = wine_server_obj_handle( token );
DOMAIN_ALIAS_RID_ADMINS, req->which_sid = tokeninfoclass;
0, 0, 0, 0, 0, 0, wine_server_set_reply( req, sid, sid_len );
&(tgroup->PrimaryGroup)); 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; break;
case TokenPrivileges: case TokenPrivileges:
SERVER_START_REQ( get_token_privileges ) SERVER_START_REQ( get_token_privileges )
...@@ -398,15 +397,21 @@ NTSTATUS WINAPI NtQueryInformationToken( ...@@ -398,15 +397,21 @@ NTSTATUS WINAPI NtQueryInformationToken(
SERVER_END_REQ; SERVER_END_REQ;
break; break;
case TokenOwner: case TokenOwner:
if (tokeninfo) SERVER_START_REQ( get_token_sid )
{ {
TOKEN_OWNER *owner = tokeninfo; TOKEN_OWNER *towner = tokeninfo;
PSID sid = owner + 1; PSID sid = towner + 1;
SID_IDENTIFIER_AUTHORITY localSidAuthority = {SECURITY_NT_AUTHORITY}; DWORD sid_len = tokeninfolength < sizeof(TOKEN_OWNER) ? 0 : tokeninfolength - sizeof(TOKEN_OWNER);
RtlInitializeSid(sid, &localSidAuthority, 1);
*(RtlSubAuthoritySid(sid, 0)) = SECURITY_INTERACTIVE_RID; req->handle = wine_server_obj_handle( token );
owner->Owner = sid; 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; break;
case TokenImpersonationLevel: case TokenImpersonationLevel:
SERVER_START_REQ( get_token_impersonation_level ) SERVER_START_REQ( get_token_impersonation_level )
......
...@@ -4123,16 +4123,17 @@ struct access_check_reply ...@@ -4123,16 +4123,17 @@ struct access_check_reply
char __pad_20[4]; char __pad_20[4];
}; };
struct get_token_user_request struct get_token_sid_request
{ {
struct request_header __header; struct request_header __header;
obj_handle_t handle; obj_handle_t handle;
unsigned int which_sid;
}; };
struct get_token_user_reply struct get_token_sid_reply
{ {
struct reply_header __header; struct reply_header __header;
data_size_t user_len; data_size_t sid_len;
/* VARARG(user,SID); */ /* VARARG(sid,SID); */
char __pad_12[4]; char __pad_12[4];
}; };
...@@ -4862,7 +4863,7 @@ enum request ...@@ -4862,7 +4863,7 @@ enum request
REQ_check_token_privileges, REQ_check_token_privileges,
REQ_duplicate_token, REQ_duplicate_token,
REQ_access_check, REQ_access_check,
REQ_get_token_user, REQ_get_token_sid,
REQ_get_token_groups, REQ_get_token_groups,
REQ_get_token_default_dacl, REQ_get_token_default_dacl,
REQ_set_token_default_dacl, REQ_set_token_default_dacl,
...@@ -5110,7 +5111,7 @@ union generic_request ...@@ -5110,7 +5111,7 @@ union generic_request
struct check_token_privileges_request check_token_privileges_request; struct check_token_privileges_request check_token_privileges_request;
struct duplicate_token_request duplicate_token_request; struct duplicate_token_request duplicate_token_request;
struct access_check_request access_check_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_groups_request get_token_groups_request;
struct get_token_default_dacl_request get_token_default_dacl_request; struct get_token_default_dacl_request get_token_default_dacl_request;
struct set_token_default_dacl_request set_token_default_dacl_request; struct set_token_default_dacl_request set_token_default_dacl_request;
...@@ -5356,7 +5357,7 @@ union generic_reply ...@@ -5356,7 +5357,7 @@ union generic_reply
struct check_token_privileges_reply check_token_privileges_reply; struct check_token_privileges_reply check_token_privileges_reply;
struct duplicate_token_reply duplicate_token_reply; struct duplicate_token_reply duplicate_token_reply;
struct access_check_reply access_check_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_groups_reply get_token_groups_reply;
struct get_token_default_dacl_reply get_token_default_dacl_reply; struct get_token_default_dacl_reply get_token_default_dacl_reply;
struct set_token_default_dacl_reply set_token_default_dacl_reply; struct set_token_default_dacl_reply set_token_default_dacl_reply;
...@@ -5393,6 +5394,6 @@ union generic_reply ...@@ -5393,6 +5394,6 @@ union generic_reply
struct free_user_handle_reply free_user_handle_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 */ #endif /* __WINE_WINE_SERVER_PROTOCOL_H */
...@@ -2924,18 +2924,19 @@ enum message_type ...@@ -2924,18 +2924,19 @@ enum message_type
VARARG(privileges,LUID_AND_ATTRIBUTES); /* privileges used during access check */ VARARG(privileges,LUID_AND_ATTRIBUTES); /* privileges used during access check */
@END @END
@REQ(get_token_user) @REQ(get_token_sid)
obj_handle_t handle; /* handle to the token */ obj_handle_t handle; /* handle to the token */
unsigned int which_sid; /* which SID to retrieve from the token */
@REPLY @REPLY
data_size_t user_len; /* length needed to store user */ data_size_t sid_len; /* length needed to store sid */
VARARG(user,SID); /* sid of the user the token represents */ VARARG(sid,SID); /* the sid specified by which_sid from the token */
@END @END
@REQ(get_token_groups) @REQ(get_token_groups)
obj_handle_t handle; /* handle to the token */ obj_handle_t handle; /* handle to the token */
@REPLY @REPLY
data_size_t user_len; /* length needed to store user */ 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 @END
@REQ(get_token_default_dacl) @REQ(get_token_default_dacl)
......
...@@ -317,7 +317,7 @@ DECL_HANDLER(get_token_privileges); ...@@ -317,7 +317,7 @@ DECL_HANDLER(get_token_privileges);
DECL_HANDLER(check_token_privileges); DECL_HANDLER(check_token_privileges);
DECL_HANDLER(duplicate_token); DECL_HANDLER(duplicate_token);
DECL_HANDLER(access_check); DECL_HANDLER(access_check);
DECL_HANDLER(get_token_user); DECL_HANDLER(get_token_sid);
DECL_HANDLER(get_token_groups); DECL_HANDLER(get_token_groups);
DECL_HANDLER(get_token_default_dacl); DECL_HANDLER(get_token_default_dacl);
DECL_HANDLER(set_token_default_dacl); DECL_HANDLER(set_token_default_dacl);
...@@ -564,7 +564,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] = ...@@ -564,7 +564,7 @@ static const req_handler req_handlers[REQ_NB_REQUESTS] =
(req_handler)req_check_token_privileges, (req_handler)req_check_token_privileges,
(req_handler)req_duplicate_token, (req_handler)req_duplicate_token,
(req_handler)req_access_check, (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_groups,
(req_handler)req_get_token_default_dacl, (req_handler)req_get_token_default_dacl,
(req_handler)req_set_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 ); ...@@ -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, access_status) == 12 );
C_ASSERT( FIELD_OFFSET(struct access_check_reply, privileges_len) == 16 ); C_ASSERT( FIELD_OFFSET(struct access_check_reply, privileges_len) == 16 );
C_ASSERT( sizeof(struct access_check_reply) == 24 ); 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_sid_request, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_token_user_reply, user_len) == 8 ); C_ASSERT( FIELD_OFFSET(struct get_token_sid_request, which_sid) == 16 );
C_ASSERT( sizeof(struct get_token_user_reply) == 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_request, handle) == 12 );
C_ASSERT( FIELD_OFFSET(struct get_token_groups_reply, user_len) == 8 ); C_ASSERT( FIELD_OFFSET(struct get_token_groups_reply, user_len) == 8 );
C_ASSERT( sizeof(struct get_token_groups_reply) == 16 ); C_ASSERT( sizeof(struct get_token_groups_reply) == 16 );
......
...@@ -1225,27 +1225,51 @@ DECL_HANDLER(access_check) ...@@ -1225,27 +1225,51 @@ DECL_HANDLER(access_check)
} }
/* retrieves the SID of the user that the token represents */ /* retrieves the SID of the user that the token represents */
DECL_HANDLER(get_token_user) DECL_HANDLER(get_token_sid)
{ {
struct token *token; struct token *token;
reply->user_len = 0; reply->sid_len = 0;
if ((token = (struct token *)get_handle_obj( current->process, req->handle, if ((token = (struct token *)get_handle_obj( current->process, req->handle,
TOKEN_QUERY, TOKEN_QUERY,
&token_ops ))) &token_ops )))
{ {
const SID *user = token->user; const SID *sid = NULL;
reply->user_len = FIELD_OFFSET(SID, SubAuthority[user->SubAuthorityCount]); switch (req->which_sid)
if (reply->user_len <= get_reply_max_size()) {
case TokenUser:
assert(token->user);
sid = token->user;
break;
case TokenPrimaryGroup:
sid = token->primary_group;
break;
case TokenOwner:
{ {
SID *user_reply = set_reply_data_size( reply->user_len ); struct group *group;
if (user_reply) LIST_FOR_EACH_ENTRY( group, &token->groups, struct group, entry )
memcpy( user_reply, user, reply->user_len ); {
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 ); release_object( token );
} }
} }
......
...@@ -3426,15 +3426,16 @@ static void dump_access_check_reply( const struct access_check_reply *req ) ...@@ -3426,15 +3426,16 @@ static void dump_access_check_reply( const struct access_check_reply *req )
dump_varargs_LUID_AND_ATTRIBUTES( ", privileges=", cur_size ); 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, " 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 ); fprintf( stderr, " sid_len=%u", req->sid_len );
dump_varargs_SID( ", user=", cur_size ); dump_varargs_SID( ", sid=", cur_size );
} }
static void dump_get_token_groups_request( const struct get_token_groups_request *req ) 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] = { ...@@ -4012,7 +4013,7 @@ static const dump_func req_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_check_token_privileges_request, (dump_func)dump_check_token_privileges_request,
(dump_func)dump_duplicate_token_request, (dump_func)dump_duplicate_token_request,
(dump_func)dump_access_check_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_groups_request,
(dump_func)dump_get_token_default_dacl_request, (dump_func)dump_get_token_default_dacl_request,
(dump_func)dump_set_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] = { ...@@ -4256,7 +4257,7 @@ static const dump_func reply_dumpers[REQ_NB_REQUESTS] = {
(dump_func)dump_check_token_privileges_reply, (dump_func)dump_check_token_privileges_reply,
(dump_func)dump_duplicate_token_reply, (dump_func)dump_duplicate_token_reply,
(dump_func)dump_access_check_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_groups_reply,
(dump_func)dump_get_token_default_dacl_reply, (dump_func)dump_get_token_default_dacl_reply,
NULL, NULL,
...@@ -4500,7 +4501,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = { ...@@ -4500,7 +4501,7 @@ static const char * const req_names[REQ_NB_REQUESTS] = {
"check_token_privileges", "check_token_privileges",
"duplicate_token", "duplicate_token",
"access_check", "access_check",
"get_token_user", "get_token_sid",
"get_token_groups", "get_token_groups",
"get_token_default_dacl", "get_token_default_dacl",
"set_token_default_dacl", "set_token_default_dacl",
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment