ReactOS  0.4.15-dev-3187-ge372f2b
context.c File Reference
#include "precomp.h"
Include dependency graph for context.c:

Go to the source code of this file.

Functions

BOOL WINAPI ImpersonatePrinterClient (HANDLE hToken)
 
HANDLE WINAPI RevertToPrinterSelf (VOID)
 

Function Documentation

◆ ImpersonatePrinterClient()

BOOL WINAPI ImpersonatePrinterClient ( HANDLE  hToken)
See also
RevertToPrinterSelf

Definition at line 14 of file context.c.

15 {
16  DWORD cbReturned;
17  DWORD dwErrorCode;
19 
20  // Sanity check
21  if (!hToken)
22  {
23  dwErrorCode = ERROR_INVALID_HANDLE;
24  goto Cleanup;
25  }
26 
27  // Get the type of the supplied token.
28  if (!GetTokenInformation(hToken, TokenType, &Type, sizeof(TOKEN_TYPE), &cbReturned))
29  {
30  dwErrorCode = GetLastError();
31  ERR("GetTokenInformation failed with error %lu!\n", dwErrorCode);
32  goto Cleanup;
33  }
34 
35  // Check if this is an impersonation token and only set it as the thread token in this case.
36  // This is not always an impersonation token, see RevertToPrinterSelf.
37  if (Type == TokenImpersonation)
38  {
39  if (!SetThreadToken(NULL, hToken))
40  {
41  dwErrorCode = GetLastError();
42  ERR("SetThreadToken failed with error %lu!\n", dwErrorCode);
43  goto Cleanup;
44  }
45  }
46 
47 Cleanup:
48  if (hToken)
49  CloseHandle(hToken);
50 
51  SetLastError(dwErrorCode);
52  return (dwErrorCode == ERROR_SUCCESS);
53 }
#define CloseHandle
Definition: compat.h:598
#define ERROR_SUCCESS
Definition: deptool.c:10
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
BOOL WINAPI SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL, IN HANDLE TokenHandle)
Definition: security.c:463
Type
Definition: Type.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:611
static const WCHAR Cleanup[]
Definition: register.c:80
enum _TOKEN_TYPE TOKEN_TYPE
#define ERR(fmt,...)
Definition: debug.h:110
#define NULL
Definition: types.h:112
BOOL WINAPI GetTokenInformation(HANDLE TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, LPVOID TokenInformation, DWORD TokenInformationLength, PDWORD ReturnLength)
Definition: security.c:413
_In_ ACCESS_MASK _In_opt_ POBJECT_ATTRIBUTES _In_ BOOLEAN _In_ TOKEN_TYPE TokenType
Definition: sefuncs.h:388

◆ RevertToPrinterSelf()

HANDLE WINAPI RevertToPrinterSelf ( VOID  )

RevertToPrinterSelf reverts the security context from the current user's context back to the process context. As spoolss.dll is used by spoolsv.exe, this is usually the SYSTEM security context.

Unlike the traditional ImpersonateClient and then RevertToSelf approach, we do it the other way round here, because spoolss.dll is delay-loaded by spoolsv.exe in the current user's context. Use RevertToPrinterSelf then to return to the SYSTEM context for specific tasks.

Definition at line 64 of file context.c.

65 {
66  DWORD dwErrorCode;
67  HANDLE hReturnValue = NULL;
68  HANDLE hToken = NULL;
69 
70  // All spoolss code is usually called after impersonating the client. In this case, we can retrieve our current thread impersonation token using OpenThreadToken.
71  // But in rare occasions, spoolss code is also called from a higher-privileged thread that doesn't impersonate the client. Then we don't get an impersonation token.
72  // Anyway, we can't just return nothing in this case, because this is being treated as failure by the caller. So we return the token of the current process.
73  // This behaviour is verified with Windows!
75  {
76  // Tell the thread to stop impersonating.
77  if (!SetThreadToken(NULL, NULL))
78  {
79  dwErrorCode = GetLastError();
80  ERR("SetThreadToken failed with error %lu!\n", dwErrorCode);
81  goto Cleanup;
82  }
83  }
84  else if (!OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &hToken))
85  {
86  dwErrorCode = GetLastError();
87  ERR("OpenProcessToken failed with error %lu!\n", dwErrorCode);
88  goto Cleanup;
89  }
90 
91  // We were successful, return a token!
92  dwErrorCode = ERROR_SUCCESS;
93  hReturnValue = hToken;
94 
95  // Don't let the cleanup routine close this.
96  hToken = NULL;
97 
98 Cleanup:
99  if (hToken)
100  CloseHandle(hToken);
101 
102  SetLastError(dwErrorCode);
103  return hReturnValue;
104 }
#define CloseHandle
Definition: compat.h:598
#define ERROR_SUCCESS
Definition: deptool.c:10
#define TRUE
Definition: types.h:120
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1040
BOOL WINAPI SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL, IN HANDLE TokenHandle)
Definition: security.c:463
#define TOKEN_IMPERSONATE
Definition: setypes.h:892
HANDLE WINAPI GetCurrentThread(VOID)
Definition: proc.c:1148
#define TOKEN_QUERY
Definition: setypes.h:893
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:611
#define GetCurrentProcess()
Definition: compat.h:618
static const WCHAR Cleanup[]
Definition: register.c:80
#define ERR(fmt,...)
Definition: debug.h:110
BOOL WINAPI OpenThreadToken(HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf, HANDLE *TokenHandle)
Definition: security.c:338
#define NULL
Definition: types.h:112
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:296

Referenced by _CreateNonspooledPort(), _HandleAddPort(), _HandleConfigureLPTPortCommandOK(), _HandleDeletePort(), and _HandleSetDefaultCommConfig().