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,
|
NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class,
|
||||||
LPCVOID data, ULONG length )
|
LPCVOID data, ULONG length )
|
||||||
{
|
{
|
||||||
|
NTSTATUS status;
|
||||||
switch(class)
|
switch(class)
|
||||||
{
|
{
|
||||||
case ThreadZeroTlsCell:
|
case ThreadZeroTlsCell:
|
||||||
|
@ -577,8 +578,16 @@ NTSTATUS WINAPI NtSetInformationThread( HANDLE handle, THREADINFOCLASS class,
|
||||||
{
|
{
|
||||||
const HANDLE *phToken = data;
|
const HANDLE *phToken = data;
|
||||||
if (length != sizeof(HANDLE)) return STATUS_INVALID_PARAMETER;
|
if (length != sizeof(HANDLE)) return STATUS_INVALID_PARAMETER;
|
||||||
FIXME("Set ThreadImpersonationToken handle to %p\n", *phToken );
|
TRACE("Setting ThreadImpersonationToken handle to %p\n", *phToken );
|
||||||
return STATUS_SUCCESS;
|
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 ThreadBasicInformation:
|
||||||
case ThreadTimes:
|
case ThreadTimes:
|
||||||
|
|
|
@ -414,6 +414,7 @@ struct set_thread_info_request
|
||||||
int mask;
|
int mask;
|
||||||
int priority;
|
int priority;
|
||||||
int affinity;
|
int affinity;
|
||||||
|
obj_handle_t token;
|
||||||
};
|
};
|
||||||
struct set_thread_info_reply
|
struct set_thread_info_reply
|
||||||
{
|
{
|
||||||
|
@ -421,6 +422,7 @@ struct set_thread_info_reply
|
||||||
};
|
};
|
||||||
#define SET_THREAD_INFO_PRIORITY 0x01
|
#define SET_THREAD_INFO_PRIORITY 0x01
|
||||||
#define SET_THREAD_INFO_AFFINITY 0x02
|
#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;
|
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 */
|
#endif /* __WINE_WINE_SERVER_PROTOCOL_H */
|
||||||
|
|
|
@ -360,9 +360,11 @@ struct security_descriptor
|
||||||
int mask; /* setting mask (see below) */
|
int mask; /* setting mask (see below) */
|
||||||
int priority; /* priority class */
|
int priority; /* priority class */
|
||||||
int affinity; /* affinity mask */
|
int affinity; /* affinity mask */
|
||||||
|
obj_handle_t token; /* impersonation token */
|
||||||
@END
|
@END
|
||||||
#define SET_THREAD_INFO_PRIORITY 0x01
|
#define SET_THREAD_INFO_PRIORITY 0x01
|
||||||
#define SET_THREAD_INFO_AFFINITY 0x02
|
#define SET_THREAD_INFO_AFFINITY 0x02
|
||||||
|
#define SET_THREAD_INFO_TOKEN 0x04
|
||||||
|
|
||||||
|
|
||||||
/* Retrieve information about a module */
|
/* 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,
|
extern int token_check_privileges( struct token *token, int all_required,
|
||||||
const LUID_AND_ATTRIBUTES *reqprivs,
|
const LUID_AND_ATTRIBUTES *reqprivs,
|
||||||
unsigned int count, LUID_AND_ATTRIBUTES *usedprivs);
|
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)
|
static inline int thread_single_check_privilege( struct thread *thread, const LUID *priv)
|
||||||
{
|
{
|
||||||
|
|
|
@ -45,6 +45,7 @@
|
||||||
#include "thread.h"
|
#include "thread.h"
|
||||||
#include "request.h"
|
#include "request.h"
|
||||||
#include "user.h"
|
#include "user.h"
|
||||||
|
#include "security.h"
|
||||||
|
|
||||||
|
|
||||||
/* thread queues */
|
/* thread queues */
|
||||||
|
@ -314,6 +315,8 @@ static void set_thread_info( struct thread *thread,
|
||||||
if (req->affinity != 1) set_error( STATUS_INVALID_PARAMETER );
|
if (req->affinity != 1) set_error( STATUS_INVALID_PARAMETER );
|
||||||
else thread->affinity = req->affinity;
|
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) */
|
/* 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]) ));
|
!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 )
|
static const ACE_HEADER *ace_next( const ACE_HEADER *ace )
|
||||||
{
|
{
|
||||||
return (const ACE_HEADER *)((const char *)ace + ace->AceSize);
|
return (const ACE_HEADER *)((const char *)ace + ace->AceSize);
|
||||||
|
@ -964,8 +987,13 @@ DECL_HANDLER(access_check)
|
||||||
|
|
||||||
memset(&priv, 0, sizeof(priv));
|
memset(&priv, 0, sizeof(priv));
|
||||||
|
|
||||||
/* FIXME: check token is an impersonation token, if not return
|
/* only impersonation tokens may be used with this function */
|
||||||
* STATUS_NO_IMPERSONATION_TOKEN */
|
if (token->primary)
|
||||||
|
{
|
||||||
|
set_error( STATUS_NO_IMPERSONATION_TOKEN );
|
||||||
|
release_object( token );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
mapping.GenericRead = req->mapping_read;
|
mapping.GenericRead = req->mapping_read;
|
||||||
mapping.GenericWrite = req->mapping_write;
|
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, " handle=%p,", req->handle );
|
||||||
fprintf( stderr, " mask=%d,", req->mask );
|
fprintf( stderr, " mask=%d,", req->mask );
|
||||||
fprintf( stderr, " priority=%d,", req->priority );
|
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 )
|
static void dump_get_dll_info_request( const struct get_dll_info_request *req )
|
||||||
|
|
Loading…
Reference in New Issue