Time to commit some Work-In-Progress stuff before my diff gets too large..
[reactos.git] / reactos / win32ss / printing / base / spoolss / context.c
1 /*
2 * PROJECT: ReactOS Spooler Router
3 * LICENSE: GNU LGPL v2.1 or any later version as published by the Free Software Foundation
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
10 /**
11 * @see RevertToPrinterSelf
12 */
13 BOOL WINAPI
14 ImpersonatePrinterClient(HANDLE hToken)
15 {
16 if (!hToken)
17 {
18 SetLastError(ERROR_INVALID_HANDLE);
19 return FALSE;
20 }
21
22 if (!SetThreadToken(NULL, hToken))
23 {
24 ERR("SetThreadToken failed with error %lu!\n", GetLastError());
25 CloseHandle(hToken);
26 return FALSE;
27 }
28
29 CloseHandle(hToken);
30 return TRUE;
31 }
32
33 /**
34 * RevertToPrinterSelf reverts the security context from the current user's context back to the process context.
35 * As spoolss.dll is used by spoolsv.exe, this is usually the SYSTEM security context.
36 *
37 * Unlike the traditional ImpersonateClient and then RevertToSelf approach, we do it the other way round here,
38 * because spoolss.dll is delay-loaded by spoolsv.exe in the current user's context. Use RevertToPrinterSelf then to
39 * return to the SYSTEM context for specific tasks.
40 */
41 HANDLE WINAPI
42 RevertToPrinterSelf()
43 {
44 HANDLE hToken;
45
46 // Retrieve our current impersonation token
47 if (!OpenThreadToken(GetCurrentThread(), TOKEN_IMPERSONATE, TRUE, &hToken))
48 {
49 ERR("OpenThreadToken failed with error %lu!\n", GetLastError());
50 return NULL;
51 }
52
53 // Tell the thread to stop impersonating
54 if (!SetThreadToken(NULL, NULL))
55 {
56 ERR("SetThreadToken failed with error %lu!\n", GetLastError());
57 return NULL;
58 }
59
60 // Return the token required for reverting back to impersonation in ImpersonatePrinterClient
61 return hToken;
62 }