From dd99319cdebe783c9c3def3a39c8b6ab73689c5f Mon Sep 17 00:00:00 2001 From: Alexandre Julliard Date: Mon, 25 Apr 2022 13:23:28 +0200 Subject: [PATCH] server: Return the full token group for TokenLogonSid. Based on a patch by Fabian Maurer. Wine-Bug: https://bugs.winehq.org/show_bug.cgi?id=52845 Signed-off-by: Alexandre Julliard --- dlls/advapi32/tests/security.c | 3 +++ dlls/ntdll/unix/security.c | 24 ++---------------------- include/wine/server_protocol.h | 4 +++- server/protocol.def | 1 + server/request.h | 3 ++- server/token.c | 8 +++----- server/trace.c | 1 + 7 files changed, 15 insertions(+), 29 deletions(-) diff --git a/dlls/advapi32/tests/security.c b/dlls/advapi32/tests/security.c index 135a45f7727..ed91ccc39d3 100644 --- a/dlls/advapi32/tests/security.c +++ b/dlls/advapi32/tests/security.c @@ -1898,6 +1898,9 @@ static void test_token_attr(void) /* S-1-5-5-0-XXXXXX */ ret = IsWellKnownSid(Groups->Groups[0].Sid, WinLogonIdsSid); ok(ret, "Unknown SID\n"); + + ok(Groups->Groups[0].Attributes == (SE_GROUP_MANDATORY | SE_GROUP_ENABLED_BY_DEFAULT | SE_GROUP_ENABLED | SE_GROUP_LOGON_ID), + "got %lx\n", Groups->Groups[0].Attributes); } } diff --git a/dlls/ntdll/unix/security.c b/dlls/ntdll/unix/security.c index 2955355353e..7b401c8bd70 100644 --- a/dlls/ntdll/unix/security.c +++ b/dlls/ntdll/unix/security.c @@ -230,6 +230,7 @@ NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS c break; case TokenGroups: + case TokenLogonSid: { /* reply buffer is always shorter than output one */ void *buffer = malloc( length ); @@ -239,6 +240,7 @@ NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS c SERVER_START_REQ( get_token_groups ) { req->handle = wine_server_obj_handle( token ); + req->attr_mask = (class == TokenLogonSid) ? SE_GROUP_LOGON_ID : 0; wine_server_set_reply( req, buffer, length ); status = wine_server_call( req ); @@ -464,28 +466,6 @@ NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS c break; } - case TokenLogonSid: - SERVER_START_REQ( get_token_sid ) - { - TOKEN_GROUPS * groups = info; - PSID sid = groups + 1; - DWORD sid_len = length < sizeof(TOKEN_GROUPS) ? 0 : length - sizeof(TOKEN_GROUPS); - - req->handle = wine_server_obj_handle( token ); - req->which_sid = class; - wine_server_set_reply( req, sid, sid_len ); - status = wine_server_call( req ); - if (retlen) *retlen = reply->sid_len + sizeof(TOKEN_GROUPS); - if (status == STATUS_SUCCESS) - { - groups->GroupCount = 1; - groups->Groups[0].Sid = sid; - groups->Groups[0].Attributes = 0; - } - } - SERVER_END_REQ; - break; - case TokenLinkedToken: SERVER_START_REQ( create_linked_token ) { diff --git a/include/wine/server_protocol.h b/include/wine/server_protocol.h index 8f883b2d97e..868add58abf 100644 --- a/include/wine/server_protocol.h +++ b/include/wine/server_protocol.h @@ -4479,6 +4479,8 @@ struct get_token_groups_request { struct request_header __header; obj_handle_t handle; + unsigned int attr_mask; + char __pad_20[4]; }; struct get_token_groups_reply { @@ -6286,7 +6288,7 @@ union generic_reply /* ### protocol_version begin ### */ -#define SERVER_PROTOCOL_VERSION 750 +#define SERVER_PROTOCOL_VERSION 751 /* ### protocol_version end ### */ diff --git a/server/protocol.def b/server/protocol.def index 9b7b99ae86a..2be1658fca2 100644 --- a/server/protocol.def +++ b/server/protocol.def @@ -3176,6 +3176,7 @@ enum caret_state @REQ(get_token_groups) obj_handle_t handle; /* handle to the token */ + unsigned int attr_mask; /* mask for wanted attributes */ @REPLY data_size_t attr_len; /* length needed to store attrs */ data_size_t sid_len; /* length needed to store sids */ diff --git a/server/request.h b/server/request.h index 9ed2f898e6d..7fd63905e0e 100644 --- a/server/request.h +++ b/server/request.h @@ -1964,7 +1964,8 @@ C_ASSERT( sizeof(struct get_token_sid_request) == 24 ); 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( sizeof(struct get_token_groups_request) == 16 ); +C_ASSERT( FIELD_OFFSET(struct get_token_groups_request, attr_mask) == 16 ); +C_ASSERT( sizeof(struct get_token_groups_request) == 24 ); C_ASSERT( FIELD_OFFSET(struct get_token_groups_reply, attr_len) == 8 ); C_ASSERT( FIELD_OFFSET(struct get_token_groups_reply, sid_len) == 12 ); C_ASSERT( sizeof(struct get_token_groups_reply) == 16 ); diff --git a/server/token.c b/server/token.c index 4aca1ea133a..f817c1114f8 100644 --- a/server/token.c +++ b/server/token.c @@ -82,7 +82,6 @@ static const struct sid local_sid = { SID_REVISION, 1, SECURITY_LOCAL_SID_AUTHOR static const struct sid interactive_sid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_INTERACTIVE_RID } }; static const struct sid anonymous_logon_sid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_ANONYMOUS_LOGON_RID } }; static const struct sid authenticated_user_sid = { SID_REVISION, 1, SECURITY_NT_AUTHORITY, { SECURITY_AUTHENTICATED_USER_RID } }; -static const struct sid builtin_logon_sid = { SID_REVISION, 3, SECURITY_NT_AUTHORITY, { SECURITY_LOGON_IDS_RID, 0, 0 } }; static struct luid prev_luid_value = { 1000, 0 }; @@ -731,7 +730,7 @@ struct token *token_create_admin( unsigned primary, int impersonation_level, int struct sid alias_admins_sid = { SID_REVISION, 2, SECURITY_NT_AUTHORITY, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS }}; struct sid alias_users_sid = { SID_REVISION, 2, SECURITY_NT_AUTHORITY, { SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_USERS }}; /* on Windows, this value changes every time the user logs on */ - struct sid logon_sid = { SID_REVISION, 3, SECURITY_NT_AUTHORITY, { SECURITY_LOGON_IDS_RID, 0, 1 /* FIXME: should be randomly generated when tokens are inherited by new processes */ }}; + struct sid logon_sid = { SID_REVISION, 3, SECURITY_NT_AUTHORITY, { SECURITY_LOGON_IDS_RID, 0, 0 /* FIXME: should be randomly generated when tokens are inherited by new processes */ }}; const struct sid *user_sid = security_unix_uid_to_sid( getuid() ); struct acl *default_dacl = create_default_dacl( user_sid ); const struct luid_attr admin_privs[] = @@ -1354,9 +1353,6 @@ DECL_HANDLER(get_token_sid) case TokenOwner: sid = token->owner; break; - case TokenLogonSid: - sid = &builtin_logon_sid; - break; default: set_error( STATUS_INVALID_PARAMETER ); break; @@ -1384,6 +1380,7 @@ DECL_HANDLER(get_token_groups) LIST_FOR_EACH_ENTRY( group, &token->groups, const struct group, entry ) { + if (req->attr_mask && !(group->attrs & req->attr_mask)) continue; group_count++; reply->sid_len += sid_len( &group->sid ); } @@ -1398,6 +1395,7 @@ DECL_HANDLER(get_token_groups) { LIST_FOR_EACH_ENTRY( group, &token->groups, const struct group, entry ) { + if (req->attr_mask && !(group->attrs & req->attr_mask)) continue; sid = copy_sid( sid, &group->sid ); *attr_ptr++ = group->attrs; } diff --git a/server/trace.c b/server/trace.c index d71561e1247..15ca4e7d71e 100644 --- a/server/trace.c +++ b/server/trace.c @@ -3864,6 +3864,7 @@ static void dump_get_token_sid_reply( const struct get_token_sid_reply *req ) static void dump_get_token_groups_request( const struct get_token_groups_request *req ) { fprintf( stderr, " handle=%04x", req->handle ); + fprintf( stderr, ", attr_mask=%08x", req->attr_mask ); } static void dump_get_token_groups_reply( const struct get_token_groups_reply *req )