Add support for impersonating a token.
This commit is contained in:
parent
0a645e8cb9
commit
4bba21643c
|
@ -535,6 +535,7 @@ NTSTATUS WINAPI NtQueryInformationThread( HANDLE handle, THREADINFOCLASS class,
|
|||
NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class,
|
||||
LPCVOID data, ULONG length )
|
||||
{
|
||||
NTSTATUS status;
|
||||
switch(class)
|
||||
{
|
||||
case ThreadZeroTlsCell:
|
||||
|
@ -577,8 +578,16 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class,
|
|||
{
|
||||
const HANDLE *phToken = data;
|
||||
if (length != sizeof(HANDLE)) return STATUS_INVALID_PARAMETER;
|
||||
FIXME("Set ThreadImpersonationToken handle to %p\n", *phToken );
|
||||
return STATUS_SUCCESS;
|
||||
TRACE("Setting ThreadImpersonationToken handle to %p\n", *phToken );
|
||||
SERVER_START_REQ( set_thread_info )
|
||||
{
|
||||
req->handle = handle;
|
||||
req->token = *phToken;
|
||||
req->mask = SET_THREAD_INFO_TOKEN;
|
||||
status = wine_server_call( req );
|
||||
}
|
||||
SERVER_END_REQ;
|
||||
return status;
|
||||
}
|
||||
case ThreadBasicInformation:
|
||||
case ThreadTimes:
|
||||
|
|
|
@ -414,6 +414,7 @@ struct set_thread_info_request
|
|||
int mask;
|
||||
int priority;
|
||||
int affinity;
|
||||
obj_handle_t token;
|
||||
};
|
||||
struct set_thread_info_reply
|
||||
{
|
||||
|
@ -421,6 +422,7 @@ struct set_thread_info_reply
|
|||
};
|
||||
#define SET_THREAD_INFO_PRIORITY 0x01
|
||||
#define SET_THREAD_INFO_AFFINITY 0x02
|
||||
#define SET_THREAD_INFO_TOKEN 0x04
|
||||
|
||||
|
||||
|
||||
|
@ -4186,6 +4188,6 @@ union generic_reply
|
|||
struct set_mailslot_info_reply set_mailslot_info_reply;
|
||||
};
|
||||
|
||||
#define SERVER_PROTOCOL_VERSION 178
|
||||
#define SERVER_PROTOCOL_VERSION 179
|
||||
|
||||
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||
|
|
|
@ -360,9 +360,11 @@ struct security_descriptor
|
|||
int mask; /* setting mask (see below) */
|
||||
int priority; /* priority class */
|
||||
int affinity; /* affinity mask */
|
||||
obj_handle_t token; /* impersonation token */
|
||||
@END
|
||||
#define SET_THREAD_INFO_PRIORITY 0x01
|
||||
#define SET_THREAD_INFO_AFFINITY 0x02
|
||||
#define SET_THREAD_INFO_TOKEN 0x04
|
||||
|
||||
|
||||
/* Retrieve information about a module */
|
||||
|
|
|
@ -43,6 +43,7 @@ extern struct token *token_create_admin(void);
|
|||
extern int token_check_privileges( struct token *token, int all_required,
|
||||
const LUID_AND_ATTRIBUTES *reqprivs,
|
||||
unsigned int count, LUID_AND_ATTRIBUTES *usedprivs);
|
||||
extern void security_set_thread_token( struct thread *thread, obj_handle_t handle );
|
||||
|
||||
static inline int thread_single_check_privilege( struct thread *thread, const LUID *priv)
|
||||
{
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "thread.h"
|
||||
#include "request.h"
|
||||
#include "user.h"
|
||||
#include "security.h"
|
||||
|
||||
|
||||
/* thread queues */
|
||||
|
@ -314,6 +315,8 @@ static void set_thread_info( struct thread *thread,
|
|||
if (req->affinity != 1) set_error( STATUS_INVALID_PARAMETER );
|
||||
else thread->affinity = req->affinity;
|
||||
}
|
||||
if (req->mask & SET_THREAD_INFO_TOKEN)
|
||||
security_set_thread_token( thread, req->token );
|
||||
}
|
||||
|
||||
/* stop a thread (at the Unix level) */
|
||||
|
|
|
@ -140,6 +140,29 @@ static inline int security_equal_sid( const SID *sid1, const SID *sid2 )
|
|||
!memcmp( sid1, sid2, FIELD_OFFSET(SID, SubAuthority[sid1->SubAuthorityCount]) ));
|
||||
}
|
||||
|
||||
void security_set_thread_token( struct thread *thread, obj_handle_t handle )
|
||||
{
|
||||
if (!handle)
|
||||
{
|
||||
if (thread->token)
|
||||
release_object( thread->token );
|
||||
thread->token = NULL;
|
||||
}
|
||||
else
|
||||
{
|
||||
struct token *token = (struct token *)get_handle_obj( current->process,
|
||||
handle,
|
||||
TOKEN_IMPERSONATE,
|
||||
&token_ops );
|
||||
if (token)
|
||||
{
|
||||
if (thread->token)
|
||||
release_object( thread->token );
|
||||
thread->token = token;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static const ACE_HEADER *ace_next( const ACE_HEADER *ace )
|
||||
{
|
||||
return (const ACE_HEADER *)((const char *)ace + ace->AceSize);
|
||||
|
@ -964,8 +987,13 @@ DECL_HANDLER(access_check)
|
|||
|
||||
memset(&priv, 0, sizeof(priv));
|
||||
|
||||
/* FIXME: check token is an impersonation token, if not return
|
||||
* STATUS_NO_IMPERSONATION_TOKEN */
|
||||
/* only impersonation tokens may be used with this function */
|
||||
if (token->primary)
|
||||
{
|
||||
set_error( STATUS_NO_IMPERSONATION_TOKEN );
|
||||
release_object( token );
|
||||
return;
|
||||
}
|
||||
|
||||
mapping.GenericRead = req->mapping_read;
|
||||
mapping.GenericWrite = req->mapping_write;
|
||||
|
|
|
@ -741,7 +741,8 @@ static void dump_set_thread_info_request( const struct set_thread_info_request *
|
|||
fprintf( stderr, " handle=%p,", req->handle );
|
||||
fprintf( stderr, " mask=%d,", req->mask );
|
||||
fprintf( stderr, " priority=%d,", req->priority );
|
||||
fprintf( stderr, " affinity=%d", req->affinity );
|
||||
fprintf( stderr, " affinity=%d,", req->affinity );
|
||||
fprintf( stderr, " token=%p", req->token );
|
||||
}
|
||||
|
||||
static void dump_get_dll_info_request( const struct get_dll_info_request *req )
|
||||
|
|
Loading…
Reference in New Issue