Add support for impersonating a token.

This commit is contained in:
Robert Shearman 2005-06-20 13:18:38 +00:00 committed by Alexandre Julliard
parent 0a645e8cb9
commit 4bba21643c
7 changed files with 52 additions and 6 deletions

View File

@ -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:

View File

@ -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 */

View File

@ -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 */

View File

@ -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)
{ {

View File

@ -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) */

View File

@ -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;

View File

@ -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 )