165 lines
4.1 KiB
C
165 lines
4.1 KiB
C
|
/*++
|
|||
|
|
|||
|
Copyright (c) 1989 Microsoft Corporation
|
|||
|
|
|||
|
Module Name:
|
|||
|
|
|||
|
psimpers.c
|
|||
|
|
|||
|
Abstract:
|
|||
|
|
|||
|
This module implements the NtImpersonateThread() service.
|
|||
|
|
|||
|
|
|||
|
Author:
|
|||
|
|
|||
|
Jim Kelly (JimK) 20-Apr-1991
|
|||
|
|
|||
|
Revision History:
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
#include "psp.h"
|
|||
|
|
|||
|
#ifdef ALLOC_PRAGMA
|
|||
|
#pragma alloc_text(PAGE, NtImpersonateThread)
|
|||
|
#endif //ALLOC_PRAGMA
|
|||
|
|
|||
|
|
|||
|
NTSTATUS
|
|||
|
NtImpersonateThread(
|
|||
|
IN HANDLE ServerThreadHandle,
|
|||
|
IN HANDLE ClientThreadHandle,
|
|||
|
IN PSECURITY_QUALITY_OF_SERVICE SecurityQos
|
|||
|
)
|
|||
|
|
|||
|
/*++
|
|||
|
|
|||
|
Routine Description:
|
|||
|
|
|||
|
This routine is used to cause the server thread to impersonate the client
|
|||
|
thread. The impersonation is done according to the specified quality
|
|||
|
of service parameters.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Arguments:
|
|||
|
|
|||
|
ServerThreadHandle - Is a handle to the server thread (the impersonator, or
|
|||
|
doing the impersonation). This handle must be open for
|
|||
|
THREAD_IMPERSONATE access.
|
|||
|
|
|||
|
ClientThreadHandle - Is a handle to the Client thread (the impersonatee, or
|
|||
|
one being impersonated). This handle must be open for
|
|||
|
THREAD_DIRECT_IMPERSONATION access.
|
|||
|
|
|||
|
|
|||
|
SecurityQos - A pointer to security quality of service information
|
|||
|
indicating what form of impersonation is to be performed.
|
|||
|
|
|||
|
|
|||
|
|
|||
|
Return Value:
|
|||
|
|
|||
|
STATUS_SUCCESS - Indicates the call completed successfully.
|
|||
|
|
|||
|
|
|||
|
--*/
|
|||
|
|
|||
|
{
|
|||
|
|
|||
|
|
|||
|
KPROCESSOR_MODE PreviousMode;
|
|||
|
NTSTATUS Status;
|
|||
|
PETHREAD ClientThread, ServerThread;
|
|||
|
SECURITY_QUALITY_OF_SERVICE CapturedQos;
|
|||
|
SECURITY_CLIENT_CONTEXT ClientSecurityContext;
|
|||
|
|
|||
|
//
|
|||
|
// Get previous processor mode and probe and capture arguments if necessary
|
|||
|
//
|
|||
|
|
|||
|
PreviousMode = KeGetPreviousMode();
|
|||
|
|
|||
|
try {
|
|||
|
|
|||
|
if (PreviousMode != KernelMode) {
|
|||
|
ProbeForReadSmallStructure (SecurityQos,
|
|||
|
sizeof (SECURITY_QUALITY_OF_SERVICE),
|
|||
|
sizeof (ULONG));
|
|||
|
}
|
|||
|
CapturedQos = *SecurityQos;
|
|||
|
|
|||
|
} except (ExSystemExceptionFilter ()) {
|
|||
|
return GetExceptionCode ();
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Reference the client thread, checking for appropriate access.
|
|||
|
//
|
|||
|
|
|||
|
Status = ObReferenceObjectByHandle (ClientThreadHandle, // Handle
|
|||
|
THREAD_DIRECT_IMPERSONATION, // DesiredAccess
|
|||
|
PsThreadType, // ObjectType
|
|||
|
PreviousMode, // AccessMode
|
|||
|
&ClientThread, // Object
|
|||
|
NULL); // GrantedAccess
|
|||
|
|
|||
|
if (!NT_SUCCESS (Status)) {
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
//
|
|||
|
// Reference the client thread, checking for appropriate access.
|
|||
|
//
|
|||
|
|
|||
|
Status = ObReferenceObjectByHandle (ServerThreadHandle, // Handle
|
|||
|
THREAD_IMPERSONATE, // DesiredAccess
|
|||
|
PsThreadType, // ObjectType
|
|||
|
PreviousMode, // AccessMode
|
|||
|
&ServerThread, // Object
|
|||
|
NULL); // GrantedAccess
|
|||
|
|
|||
|
if (!NT_SUCCESS (Status)) {
|
|||
|
ObDereferenceObject (ClientThread);
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Get the client's security context
|
|||
|
//
|
|||
|
|
|||
|
Status = SeCreateClientSecurity (ClientThread, // ClientThread
|
|||
|
&CapturedQos, // SecurityQos
|
|||
|
FALSE, // ServerIsRemote
|
|||
|
&ClientSecurityContext); // ClientContext
|
|||
|
|
|||
|
if (!NT_SUCCESS (Status)) {
|
|||
|
ObDereferenceObject (ServerThread);
|
|||
|
ObDereferenceObject (ClientThread);
|
|||
|
return Status;
|
|||
|
}
|
|||
|
|
|||
|
|
|||
|
//
|
|||
|
// Impersonate the client
|
|||
|
//
|
|||
|
|
|||
|
Status = SeImpersonateClientEx (&ClientSecurityContext, ServerThread);
|
|||
|
|
|||
|
SeDeleteClientSecurity (&ClientSecurityContext);
|
|||
|
|
|||
|
//
|
|||
|
// Done.
|
|||
|
//
|
|||
|
|
|||
|
|
|||
|
ObDereferenceObject (ServerThread);
|
|||
|
ObDereferenceObject (ClientThread);
|
|||
|
|
|||
|
return Status ;
|
|||
|
}
|