server: Don't depend on the TOKEN_GROUPS structure on the server side.
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
990cc1c64b
commit
868af0c500
|
@ -233,43 +233,38 @@ NTSTATUS WINAPI NtQueryInformationToken( HANDLE token, TOKEN_INFORMATION_CLASS c
|
|||
{
|
||||
/* reply buffer is always shorter than output one */
|
||||
void *buffer = malloc( length );
|
||||
TOKEN_GROUPS *groups = info;
|
||||
ULONG i, count, needed_size;
|
||||
|
||||
SERVER_START_REQ( get_token_groups )
|
||||
{
|
||||
TOKEN_GROUPS *groups = info;
|
||||
|
||||
req->handle = wine_server_obj_handle( token );
|
||||
wine_server_set_reply( req, buffer, length );
|
||||
status = wine_server_call( req );
|
||||
if (status == STATUS_BUFFER_TOO_SMALL)
|
||||
|
||||
count = reply->attr_len / sizeof(unsigned int);
|
||||
needed_size = offsetof( TOKEN_GROUPS, Groups[count] ) + reply->sid_len;
|
||||
if (status == STATUS_SUCCESS && needed_size > length) status = STATUS_BUFFER_TOO_SMALL;
|
||||
|
||||
if (status == STATUS_SUCCESS)
|
||||
{
|
||||
if (retlen) *retlen = reply->user_len;
|
||||
}
|
||||
else if (status == STATUS_SUCCESS)
|
||||
{
|
||||
struct token_groups *tg = buffer;
|
||||
unsigned int *attr = (unsigned int *)(tg + 1);
|
||||
ULONG i;
|
||||
const int non_sid_portion = (sizeof(struct token_groups) + tg->count * sizeof(unsigned int));
|
||||
SID *sids = (SID *)((char *)info + FIELD_OFFSET( TOKEN_GROUPS, Groups[tg->count] ));
|
||||
unsigned int *attr = buffer;
|
||||
SID *sids = (SID *)&groups->Groups[count];
|
||||
|
||||
if (retlen) *retlen = reply->user_len;
|
||||
|
||||
groups->GroupCount = tg->count;
|
||||
memcpy( sids, (char *)buffer + non_sid_portion,
|
||||
reply->user_len - offsetof( TOKEN_GROUPS, Groups[tg->count] ));
|
||||
|
||||
for (i = 0; i < tg->count; i++)
|
||||
groups->GroupCount = count;
|
||||
memcpy( sids, attr + count, reply->sid_len );
|
||||
for (i = 0; i < count; i++)
|
||||
{
|
||||
groups->Groups[i].Attributes = attr[i];
|
||||
groups->Groups[i].Sid = sids;
|
||||
sids = (SID *)((char *)sids + offsetof( SID, SubAuthority[sids->SubAuthorityCount] ));
|
||||
}
|
||||
}
|
||||
else if (retlen) *retlen = 0;
|
||||
else if (status != STATUS_BUFFER_TOO_SMALL) needed_size = 0;
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
free( buffer );
|
||||
if (retlen) *retlen = needed_size;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -439,13 +439,6 @@ struct object_type_info
|
|||
|
||||
};
|
||||
|
||||
struct token_groups
|
||||
{
|
||||
unsigned int count;
|
||||
|
||||
|
||||
};
|
||||
|
||||
enum select_op
|
||||
{
|
||||
SELECT_NONE,
|
||||
|
@ -4470,9 +4463,10 @@ struct get_token_groups_request
|
|||
struct get_token_groups_reply
|
||||
{
|
||||
struct reply_header __header;
|
||||
data_size_t user_len;
|
||||
/* VARARG(user,token_groups); */
|
||||
char __pad_12[4];
|
||||
data_size_t attr_len;
|
||||
data_size_t sid_len;
|
||||
/* VARARG(attrs,uints,attr_len); */
|
||||
/* VARARG(sids,sids); */
|
||||
};
|
||||
|
||||
struct get_token_default_dacl_request
|
||||
|
|
|
@ -455,13 +455,6 @@ struct object_type_info
|
|||
/* VARARG(name,unicode_str); */
|
||||
};
|
||||
|
||||
struct token_groups
|
||||
{
|
||||
unsigned int count;
|
||||
/* unsigned int attributes[count]; */
|
||||
/* VARARG(sids,sid); */
|
||||
};
|
||||
|
||||
enum select_op
|
||||
{
|
||||
SELECT_NONE,
|
||||
|
@ -3174,8 +3167,10 @@ enum caret_state
|
|||
@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 */
|
||||
data_size_t attr_len; /* length needed to store attrs */
|
||||
data_size_t sid_len; /* length needed to store sids */
|
||||
VARARG(attrs,uints,attr_len); /* group attributes */
|
||||
VARARG(sids,sids); /* group sids */
|
||||
@END
|
||||
|
||||
@REQ(get_token_default_dacl)
|
||||
|
|
|
@ -1957,7 +1957,8 @@ 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_reply, user_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( sizeof(struct get_token_groups_reply) == 16 );
|
||||
C_ASSERT( FIELD_OFFSET(struct get_token_default_dacl_request, handle) == 12 );
|
||||
C_ASSERT( sizeof(struct get_token_default_dacl_request) == 16 );
|
||||
|
|
|
@ -1390,49 +1390,27 @@ DECL_HANDLER(get_token_groups)
|
|||
{
|
||||
struct token *token;
|
||||
|
||||
reply->user_len = 0;
|
||||
|
||||
if ((token = (struct token *)get_handle_obj( current->process, req->handle,
|
||||
TOKEN_QUERY,
|
||||
&token_ops )))
|
||||
if ((token = (struct token *)get_handle_obj( current->process, req->handle, TOKEN_QUERY, &token_ops )))
|
||||
{
|
||||
size_t size_needed = sizeof(struct token_groups);
|
||||
size_t sid_size = 0;
|
||||
unsigned int group_count = 0;
|
||||
const struct group *group;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( group, &token->groups, const struct group, entry )
|
||||
{
|
||||
group_count++;
|
||||
sid_size += sid_len( &group->sid );
|
||||
reply->sid_len += sid_len( &group->sid );
|
||||
}
|
||||
size_needed += sid_size;
|
||||
/* attributes size */
|
||||
size_needed += sizeof(unsigned int) * group_count;
|
||||
reply->attr_len = sizeof(unsigned int) * group_count;
|
||||
|
||||
/* reply buffer contains size_needed bytes formatted as:
|
||||
|
||||
unsigned int count;
|
||||
unsigned int attrib[count];
|
||||
char sid_data[];
|
||||
|
||||
user_len includes extra data needed for TOKEN_GROUPS representation,
|
||||
required caller buffer size calculated here to avoid extra server call */
|
||||
reply->user_len = FIELD_OFFSET( TOKEN_GROUPS, Groups[group_count] ) + sid_size;
|
||||
|
||||
if (reply->user_len <= get_reply_max_size())
|
||||
if (reply->attr_len + reply->sid_len <= get_reply_max_size())
|
||||
{
|
||||
struct token_groups *tg = set_reply_data_size( size_needed );
|
||||
if (tg)
|
||||
unsigned int *attr_ptr = set_reply_data_size( reply->attr_len + reply->sid_len );
|
||||
struct sid *sid = (struct sid *)(attr_ptr + group_count);
|
||||
|
||||
if (attr_ptr)
|
||||
{
|
||||
unsigned int *attr_ptr = (unsigned int *)(tg + 1);
|
||||
struct sid *sid = (struct sid *)(attr_ptr + group_count);
|
||||
|
||||
tg->count = group_count;
|
||||
|
||||
LIST_FOR_EACH_ENTRY( group, &token->groups, const struct group, entry )
|
||||
{
|
||||
|
||||
*attr_ptr = 0;
|
||||
if (group->mandatory) *attr_ptr |= SE_GROUP_MANDATORY;
|
||||
if (group->def) *attr_ptr |= SE_GROUP_ENABLED_BY_DEFAULT;
|
||||
|
|
|
@ -1040,6 +1040,28 @@ static void dump_varargs_sid( const char *prefix, data_size_t size )
|
|||
remove_data( size );
|
||||
}
|
||||
|
||||
static void dump_varargs_sids( const char *prefix, data_size_t size )
|
||||
{
|
||||
const struct sid *sid = cur_data;
|
||||
data_size_t len = size;
|
||||
|
||||
fprintf( stderr,"%s{", prefix );
|
||||
while (len > 0)
|
||||
{
|
||||
if (!sid_valid_size( sid, len ))
|
||||
{
|
||||
fprintf( stderr, "bad len %u", len);
|
||||
break;
|
||||
}
|
||||
dump_inline_sid( "", sid, size );
|
||||
len -= sid_len( sid );
|
||||
sid = (const struct sid *)((const char *)sid + sid_len( sid ));
|
||||
if (len) fputc( ',', stderr );
|
||||
}
|
||||
fputc( '}', stderr );
|
||||
remove_data( size );
|
||||
}
|
||||
|
||||
static void dump_inline_acl( const char *prefix, const struct acl *acl, data_size_t size )
|
||||
{
|
||||
const struct ace *ace;
|
||||
|
@ -1131,41 +1153,6 @@ static void dump_varargs_security_descriptor( const char *prefix, data_size_t si
|
|||
remove_data( size );
|
||||
}
|
||||
|
||||
static void dump_varargs_token_groups( const char *prefix, data_size_t size )
|
||||
{
|
||||
const struct token_groups *tg = cur_data;
|
||||
|
||||
fprintf( stderr,"%s{", prefix );
|
||||
if (size >= sizeof(struct token_groups))
|
||||
{
|
||||
size_t offset = sizeof(*tg);
|
||||
fprintf( stderr, "count=%08x,", tg->count );
|
||||
if (tg->count * sizeof(unsigned int) <= size)
|
||||
{
|
||||
unsigned int i;
|
||||
const unsigned int *attr = (const unsigned int *)(tg + 1);
|
||||
|
||||
offset += tg->count * sizeof(unsigned int);
|
||||
|
||||
fputc( '[', stderr );
|
||||
for (i = 0; i < tg->count; i++)
|
||||
{
|
||||
const struct sid *sid = (const struct sid *)((const char *)cur_data + offset);
|
||||
if (i != 0)
|
||||
fputc( ',', stderr );
|
||||
fputc( '{', stderr );
|
||||
fprintf( stderr, "attributes=%08x", attr[i] );
|
||||
dump_inline_sid( ",sid=", sid, size - offset );
|
||||
if (!sid_valid_size( sid, size - offset )) break;
|
||||
offset += sid_len( sid );
|
||||
fputc( '}', stderr );
|
||||
}
|
||||
fputc( ']', stderr );
|
||||
}
|
||||
}
|
||||
fputc( '}', stderr );
|
||||
}
|
||||
|
||||
static void dump_varargs_process_info( const char *prefix, data_size_t size )
|
||||
{
|
||||
data_size_t pos = 0;
|
||||
|
@ -3869,8 +3856,10 @@ static void dump_get_token_groups_request( const struct get_token_groups_request
|
|||
|
||||
static void dump_get_token_groups_reply( const struct get_token_groups_reply *req )
|
||||
{
|
||||
fprintf( stderr, " user_len=%u", req->user_len );
|
||||
dump_varargs_token_groups( ", user=", cur_size );
|
||||
fprintf( stderr, " attr_len=%u", req->attr_len );
|
||||
fprintf( stderr, ", sid_len=%u", req->sid_len );
|
||||
dump_varargs_uints( ", attrs=", min(cur_size,req->attr_len) );
|
||||
dump_varargs_sids( ", sids=", cur_size );
|
||||
}
|
||||
|
||||
static void dump_get_token_default_dacl_request( const struct get_token_default_dacl_request *req )
|
||||
|
|
Loading…
Reference in New Issue