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 <julliard@winehq.org>
This commit is contained in:
parent
1a0f082682
commit
dd99319cde
|
@ -1898,6 +1898,9 @@ static void test_token_attr(void)
|
||||||
/* S-1-5-5-0-XXXXXX */
|
/* S-1-5-5-0-XXXXXX */
|
||||||
ret = IsWellKnownSid(Groups->Groups[0].Sid, WinLogonIdsSid);
|
ret = IsWellKnownSid(Groups->Groups[0].Sid, WinLogonIdsSid);
|
||||||
ok(ret, "Unknown SID\n");
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -230,6 +230,7 @@ NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS c
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TokenGroups:
|
case TokenGroups:
|
||||||
|
case TokenLogonSid:
|
||||||
{
|
{
|
||||||
/* reply buffer is always shorter than output one */
|
/* reply buffer is always shorter than output one */
|
||||||
void *buffer = malloc( length );
|
void *buffer = malloc( length );
|
||||||
|
@ -239,6 +240,7 @@ NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS c
|
||||||
SERVER_START_REQ( get_token_groups )
|
SERVER_START_REQ( get_token_groups )
|
||||||
{
|
{
|
||||||
req->handle = wine_server_obj_handle( token );
|
req->handle = wine_server_obj_handle( token );
|
||||||
|
req->attr_mask = (class == TokenLogonSid) ? SE_GROUP_LOGON_ID : 0;
|
||||||
wine_server_set_reply( req, buffer, length );
|
wine_server_set_reply( req, buffer, length );
|
||||||
status = wine_server_call( req );
|
status = wine_server_call( req );
|
||||||
|
|
||||||
|
@ -464,28 +466,6 @@ NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS c
|
||||||
break;
|
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:
|
case TokenLinkedToken:
|
||||||
SERVER_START_REQ( create_linked_token )
|
SERVER_START_REQ( create_linked_token )
|
||||||
{
|
{
|
||||||
|
|
|
@ -4479,6 +4479,8 @@ struct get_token_groups_request
|
||||||
{
|
{
|
||||||
struct request_header __header;
|
struct request_header __header;
|
||||||
obj_handle_t handle;
|
obj_handle_t handle;
|
||||||
|
unsigned int attr_mask;
|
||||||
|
char __pad_20[4];
|
||||||
};
|
};
|
||||||
struct get_token_groups_reply
|
struct get_token_groups_reply
|
||||||
{
|
{
|
||||||
|
@ -6286,7 +6288,7 @@ union generic_reply
|
||||||
|
|
||||||
/* ### protocol_version begin ### */
|
/* ### protocol_version begin ### */
|
||||||
|
|
||||||
#define SERVER_PROTOCOL_VERSION 750
|
#define SERVER_PROTOCOL_VERSION 751
|
||||||
|
|
||||||
/* ### protocol_version end ### */
|
/* ### protocol_version end ### */
|
||||||
|
|
||||||
|
|
|
@ -3176,6 +3176,7 @@ enum caret_state
|
||||||
|
|
||||||
@REQ(get_token_groups)
|
@REQ(get_token_groups)
|
||||||
obj_handle_t handle; /* handle to the token */
|
obj_handle_t handle; /* handle to the token */
|
||||||
|
unsigned int attr_mask; /* mask for wanted attributes */
|
||||||
@REPLY
|
@REPLY
|
||||||
data_size_t attr_len; /* length needed to store attrs */
|
data_size_t attr_len; /* length needed to store attrs */
|
||||||
data_size_t sid_len; /* length needed to store sids */
|
data_size_t sid_len; /* length needed to store sids */
|
||||||
|
|
|
@ -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( FIELD_OFFSET(struct get_token_sid_reply, sid_len) == 8 );
|
||||||
C_ASSERT( sizeof(struct get_token_sid_reply) == 16 );
|
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( 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, attr_len) == 8 );
|
||||||
C_ASSERT( FIELD_OFFSET(struct get_token_groups_reply, sid_len) == 12 );
|
C_ASSERT( FIELD_OFFSET(struct get_token_groups_reply, sid_len) == 12 );
|
||||||
C_ASSERT( sizeof(struct get_token_groups_reply) == 16 );
|
C_ASSERT( sizeof(struct get_token_groups_reply) == 16 );
|
||||||
|
|
|
@ -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 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 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 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 };
|
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_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 }};
|
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 */
|
/* 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() );
|
const struct sid *user_sid = security_unix_uid_to_sid( getuid() );
|
||||||
struct acl *default_dacl = create_default_dacl( user_sid );
|
struct acl *default_dacl = create_default_dacl( user_sid );
|
||||||
const struct luid_attr admin_privs[] =
|
const struct luid_attr admin_privs[] =
|
||||||
|
@ -1354,9 +1353,6 @@ DECL_HANDLER(get_token_sid)
|
||||||
case TokenOwner:
|
case TokenOwner:
|
||||||
sid = token->owner;
|
sid = token->owner;
|
||||||
break;
|
break;
|
||||||
case TokenLogonSid:
|
|
||||||
sid = &builtin_logon_sid;
|
|
||||||
break;
|
|
||||||
default:
|
default:
|
||||||
set_error( STATUS_INVALID_PARAMETER );
|
set_error( STATUS_INVALID_PARAMETER );
|
||||||
break;
|
break;
|
||||||
|
@ -1384,6 +1380,7 @@ DECL_HANDLER(get_token_groups)
|
||||||
|
|
||||||
LIST_FOR_EACH_ENTRY( group, &token->groups, const struct group, entry )
|
LIST_FOR_EACH_ENTRY( group, &token->groups, const struct group, entry )
|
||||||
{
|
{
|
||||||
|
if (req->attr_mask && !(group->attrs & req->attr_mask)) continue;
|
||||||
group_count++;
|
group_count++;
|
||||||
reply->sid_len += sid_len( &group->sid );
|
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 )
|
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 );
|
sid = copy_sid( sid, &group->sid );
|
||||||
*attr_ptr++ = group->attrs;
|
*attr_ptr++ = group->attrs;
|
||||||
}
|
}
|
||||||
|
|
|
@ -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 )
|
static void dump_get_token_groups_request( const struct get_token_groups_request *req )
|
||||||
{
|
{
|
||||||
fprintf( stderr, " handle=%04x", req->handle );
|
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 )
|
static void dump_get_token_groups_reply( const struct get_token_groups_reply *req )
|
||||||
|
|
Loading…
Reference in New Issue