ReactOS  0.4.15-dev-1150-g593bcce
context.c
Go to the documentation of this file.
1 /*
2  * PROJECT: ReactOS Spooler Router
3  * LICENSE: GPL-2.0+ (https://spdx.org/licenses/GPL-2.0+)
4  * PURPOSE: Functions related to switching between security contexts
5  * COPYRIGHT: Copyright 2015 Colin Finck (colin@reactos.org)
6  */
7 
8 #include "precomp.h"
9 
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 }
54 
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:487
Type
Definition: Type.h:6
#define ERROR_SUCCESS
Definition: deptool.c:10
#define TRUE
Definition: types.h:120
#define ERROR_INVALID_HANDLE
Definition: compat.h:98
DWORD WINAPI GetLastError(VOID)
Definition: except.c:1044
BOOL WINAPI SetThreadToken(IN PHANDLE ThreadHandle OPTIONAL, IN HANDLE TokenHandle)
Definition: security.c:463
#define TOKEN_IMPERSONATE
Definition: setypes.h:873
HANDLE WINAPI GetCurrentThread(VOID)
Definition: proc.c:1148
unsigned int BOOL
Definition: ntddk_ex.h:94
smooth NULL
Definition: ftsmooth.c:416
#define TOKEN_QUERY
Definition: setypes.h:874
#define WINAPI
Definition: msvc.h:6
unsigned long DWORD
Definition: ntddk_ex.h:95
#define SetLastError(x)
Definition: compat.h:500
BOOL WINAPI ImpersonatePrinterClient(HANDLE hToken)
Definition: context.c:14
#define GetCurrentProcess()
Definition: compat.h:507
HANDLE WINAPI RevertToPrinterSelf(VOID)
Definition: context.c:64
static const WCHAR Cleanup[]
Definition: register.c:80
enum _TOKEN_TYPE TOKEN_TYPE
#define ERR(fmt,...)
Definition: debug.h:110
BOOL WINAPI OpenThreadToken(HANDLE ThreadHandle, DWORD DesiredAccess, BOOL OpenAsSelf, HANDLE *TokenHandle)
Definition: security.c:338
BOOL WINAPI OpenProcessToken(HANDLE ProcessHandle, DWORD DesiredAccess, PHANDLE TokenHandle)
Definition: security.c:296
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:417