ReactOS 0.4.16-dev-329-g9223134
priv.c
Go to the documentation of this file.
1/*
2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/rtl/priv.c
5 * PURPOSE: Security related functions and Security Objects
6 * PROGRAMMER: Eric Kohl
7 * Pierre Schweitzer (pierre@reactos.org)
8 */
9
10/* INCLUDES *****************************************************************/
11
12#include <rtl.h>
13
14#define NDEBUG
15#include <debug.h>
16
17/* FUNCTIONS ***************************************************************/
18
19/*
20 * @implemented
21 */
26{
28
31 if (!NT_SUCCESS(Status))
32 {
35 }
36
37 return Status;
38}
39
40/*
41 * @implemented
42 */
46{
47 HANDLE ProcessToken;
48 HANDLE ImpersonationToken;
50 OBJECT_ATTRIBUTES ObjAttr;
52
54
57 &ProcessToken);
58 if (!NT_SUCCESS(Status))
59 {
60 DPRINT1("NtOpenProcessToken() failed (Status %lx)\n", Status);
61 return Status;
62 }
63
66 Sqos.ContextTrackingMode = 0;
67 Sqos.EffectiveOnly = FALSE;
68
70 NULL,
71 0,
72 NULL,
73 NULL);
74
75 ObjAttr.SecurityQualityOfService = &Sqos;
76
77 Status = ZwDuplicateToken(ProcessToken,
79 &ObjAttr,
80 Sqos.EffectiveOnly, /* why both here _and_ in Sqos? */
82 &ImpersonationToken);
83 if (!NT_SUCCESS(Status))
84 {
85 DPRINT1("NtDuplicateToken() failed (Status %lx)\n", Status);
86 NtClose(ProcessToken);
87 return Status;
88 }
89
90 Status = ZwSetInformationThread(NtCurrentThread(),
92 &ImpersonationToken,
93 sizeof(HANDLE));
94 if (!NT_SUCCESS(Status))
95 {
96 DPRINT1("NtSetInformationThread() failed (Status %lx)\n", Status);
97 }
98
99 ZwClose(ImpersonationToken);
100 ZwClose(ProcessToken);
101
102 return Status;
103}
104
105/*
106 * @implemented
107 */
109NTAPI
111 IN ULONG NumPriv,
112 IN ULONG Flags,
113 OUT PVOID *ReturnedState)
114{
116 NTSTATUS Status, IntStatus;
117 ULONG ReturnLength, i, OldSize;
120 HANDLE ImpersonationToken = 0, ProcessToken;
121
122 DPRINT("RtlAcquirePrivilege(%p, %u, %u, %p)\n", Privilege, NumPriv, Flags, ReturnedState);
123
124 /* Validate flags */
126 {
128 }
129
130 /* If user wants to acquire privileges for the process, we have to impersonate him */
132 {
134 }
135
136 /* Allocate enough memory to hold: old privileges (fixed buffer size, might not be enough)
137 * new privileges (big enough, after old privileges memory area)
138 */
139 State = RtlAllocateHeap(RtlGetProcessHeap(), 0, sizeof(RTL_ACQUIRE_STATE) + sizeof(TOKEN_PRIVILEGES) +
140 (NumPriv - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES));
141 if (!State)
142 {
143 return STATUS_NO_MEMORY;
144 }
145
146 /* Only zero a bit of the memory (will be faster that way) */
147 State->Token = 0;
148 State->OldImpersonationToken = 0;
149 State->Flags = 0;
150 State->OldPrivileges = NULL;
151
152 /* Check whether we have already an active impersonation */
153 if (NtCurrentTeb()->IsImpersonating)
154 {
155 /* Check whether we want to impersonate */
157 {
158 /* That's all fine, just get the token.
159 * We need access for: adjust (obvious...) but also
160 * query, to be able to query old privileges
161 */
163 if (!NT_SUCCESS(Status))
164 {
165 RtlFreeHeap(RtlGetProcessHeap(), 0, State);
166 return Status;
167 }
168 }
169 else
170 {
171 /* Otherwise, we have to temporary disable active impersonation.
172 * Get previous impersonation token to save it
173 */
174 Status = RtlpOpenThreadToken(TOKEN_IMPERSONATE, &State->OldImpersonationToken);
175 if (!NT_SUCCESS(Status))
176 {
177 RtlFreeHeap(RtlGetProcessHeap(), 0, State);
178 return Status;
179 }
180
181 /* Remember the fact we had an active impersonation */
183
184 /* Revert impersonation (ie, give 0 as handle) */
185 Status = ZwSetInformationThread(NtCurrentThread(),
187 &ImpersonationToken,
188 sizeof(HANDLE));
189 }
190 }
191
192 /* If we have no token yet (which is likely) */
193 if (!State->Token)
194 {
195 /* If we are asked to use process, then do */
197 {
199 &State->Token);
200 if (!NT_SUCCESS(Status))
201 {
202 goto Cleanup;
203 }
204 }
205 else
206 {
207 /* Otherwise, we have to impersonate.
208 * Open token for duplication
209 */
211
213 NULL,
214 0,
215 NULL,
216 NULL);
217
218 ObjectAttributes.SecurityQualityOfService = &Sqos;
219 Sqos.Length = sizeof(SECURITY_QUALITY_OF_SERVICE);
221 Sqos.ContextTrackingMode = 1;
222 Sqos.EffectiveOnly = FALSE;
223
224 /* Duplicate */
225 Status = ZwDuplicateToken(ProcessToken,
228 FALSE,
230 &ImpersonationToken);
231 if (!NT_SUCCESS(Status))
232 {
233 ZwClose(ProcessToken);
234 goto Cleanup;
235 }
236
237 /* Assign our duplicated token to current thread */
238 Status = ZwSetInformationThread(NtCurrentThread(),
240 &ImpersonationToken,
241 sizeof(HANDLE));
242 if (!NT_SUCCESS(Status))
243 {
244 ZwClose(ImpersonationToken);
245 ZwClose(ProcessToken);
246 goto Cleanup;
247 }
248
249 /* Save said token and the fact we have impersonated */
250 State->Token = ImpersonationToken;
252
253 ZwClose(ProcessToken);
254 }
255 }
256
257 /* Properly set the privileges pointers:
258 * OldPrivileges points to the static memory in struct (= OldPrivBuffer)
259 * NewPrivileges points to the dynamic memory after OldPrivBuffer
260 * There's NO overflow risks (OldPrivileges is always used with its size)
261 */
262 State->OldPrivileges = (PTOKEN_PRIVILEGES)State->OldPrivBuffer;
263 State->NewPrivileges = (PTOKEN_PRIVILEGES)(State->OldPrivBuffer + (sizeof(State->OldPrivBuffer) / sizeof(State->OldPrivBuffer[0])));
264
265 /* Assign all the privileges to be acquired */
266 State->NewPrivileges->PrivilegeCount = NumPriv;
267 for (i = 0; i < NumPriv; ++i)
268 {
269 State->NewPrivileges->Privileges[i].Luid.LowPart = Privilege[i];
270 State->NewPrivileges->Privileges[i].Luid.HighPart = 0;
271 State->NewPrivileges->Privileges[i].Attributes = SE_PRIVILEGE_ENABLED;
272 }
273
274 /* Start privileges adjustements */
275 OldSize = sizeof(State->OldPrivBuffer);
276 do
277 {
278 ReturnLength = sizeof(State->OldPrivBuffer);
279 Status = ZwAdjustPrivilegesToken(State->Token, FALSE, State->NewPrivileges,
280 OldSize, State->OldPrivileges, &ReturnLength);
281 /* This is returned when OldPrivileges buffer is too small */
283 {
284 /* Try to allocate a new one, big enough to hold data */
285 State->OldPrivileges = RtlAllocateHeap(RtlGetProcessHeap(), 0, ReturnLength);
286 if (State->OldPrivileges)
287 {
288 DPRINT("Allocated old privileges: %p\n", State->OldPrivileges);
289 OldSize = ReturnLength;
290 continue;
291 }
292 else
293 {
294 /* If we failed, properly set status: we failed because of the lack of memory */
296 }
297 }
298
299 /* If we failed to assign at least one privilege */
301 {
302 /* If there was actually only one privilege to acquire, use more accurate status */
303 if (NumPriv == 1)
304 {
306 }
307 }
308
309 /* Fail if needed, otherwise return our state to caller */
310 if (!NT_SUCCESS(Status))
311 {
312 goto Cleanup;
313 }
314 else
315 {
316 *ReturnedState = State;
317 break;
318 }
319 } while (TRUE);
320
321 DPRINT("RtlAcquirePrivilege succeed!\n");
322
323 return Status;
324
325Cleanup:
326 /* If we allocated our own buffer for old privileges, release it */
327 if (State->OldPrivileges && (PVOID)State->OldPrivBuffer != (PVOID)State->OldPrivileges)
328 {
329 RtlFreeHeap(RtlGetProcessHeap(), 0, State->OldPrivileges);
330 }
331
332 /* Do we have to restore previously active impersonation? */
334 {
335 IntStatus = ZwSetInformationThread(NtCurrentThread(), ThreadImpersonationToken,
336 &State->OldImpersonationToken, sizeof(HANDLE));
337 /* If this ever happens, we're in a really bad situation... */
338 if (!NT_SUCCESS(IntStatus))
339 {
340 RtlRaiseStatus(IntStatus);
341 }
342 }
343
344 /* Release token */
345 if (State->Token)
346 {
347 ZwClose(State->Token);
348 }
349
350 /* And free our state buffer */
351 RtlFreeHeap(RtlGetProcessHeap(), 0, State);
352
353 DPRINT("RtlAcquirePrivilege() failed with status: %lx\n", Status);
354
355 return Status;
356}
357
358/*
359 * @implemented
360 */
361VOID
362NTAPI
364{
367
368 DPRINT("RtlReleasePrivilege(%p)\n", ReturnedState);
369
370 /* If we had an active impersonation before we acquired privileges
371 * Or if we have impersonated, quit it
372 */
374 {
375 /* Restore it for the current thread */
376 Status = ZwSetInformationThread(NtCurrentThread(), ThreadImpersonationToken,
377 &State->OldImpersonationToken, sizeof(HANDLE));
378 if (!NT_SUCCESS(Status))
379 {
381 }
382
383 /* And close the token if needed */
384 if (State->OldImpersonationToken)
385 ZwClose(State->OldImpersonationToken);
386 }
387 else
388 {
389 /* Otherwise, restore old state */
391 State->OldPrivileges, 0, NULL, NULL);
392 if (!NT_SUCCESS(Status))
393 {
395 }
396 }
397
398 /* If we used a different buffer for old privileges, just free it */
399 if ((PVOID)State->OldPrivBuffer != (PVOID)State->OldPrivileges)
400 {
401 DPRINT("Releasing old privileges: %p\n", State->OldPrivileges);
402 RtlFreeHeap(RtlGetProcessHeap(), 0, State->OldPrivileges);
403 }
404
405 /* Release token and free state */
406 ZwClose(State->Token);
407 RtlFreeHeap(RtlGetProcessHeap(), 0, State);
408}
409
410/*
411 * @implemented
412 */
414NTAPI
417 IN BOOLEAN CurrentThread,
419{
420 TOKEN_PRIVILEGES NewState;
421 TOKEN_PRIVILEGES OldState;
425
427
428 DPRINT("RtlAdjustPrivilege() called\n");
429
430 if (CurrentThread)
431 {
434 FALSE,
435 &TokenHandle);
436 }
437 else
438 {
441 &TokenHandle);
442 }
443
444 if (!NT_SUCCESS (Status))
445 {
446 DPRINT1("Retrieving token handle failed (Status %lx)\n", Status);
447 return Status;
448 }
449
450 OldState.PrivilegeCount = 1;
451
452 NewState.PrivilegeCount = 1;
453 NewState.Privileges[0].Luid.LowPart = Privilege;
454 NewState.Privileges[0].Luid.HighPart = 0;
455 NewState.Privileges[0].Attributes = (Enable) ? SE_PRIVILEGE_ENABLED : 0;
456
458 FALSE,
459 &NewState,
460 sizeof(TOKEN_PRIVILEGES),
461 &OldState,
462 &ReturnLength);
465 {
466 DPRINT1("Failed to assign all privileges\n");
468 }
469
470 if (!NT_SUCCESS(Status))
471 {
472 DPRINT1("NtAdjustPrivilegesToken() failed (Status %lx)\n", Status);
473 return Status;
474 }
475
476 if (OldState.PrivilegeCount == 0)
477 {
478 *Enabled = Enable;
479 }
480 else
481 {
483 }
484
485 DPRINT("RtlAdjustPrivilege() done\n");
486
487 return STATUS_SUCCESS;
488}
489
490#if (NTDDI_VERSION >= NTDDI_VISTA) || (DLL_EXPORT_VERSION >= _WIN32_WINNT_VISTA)
491
514NTAPI
517 _In_reads_opt_(PrivilegeCount) _When_(PrivilegeCount != 0, _Notnull_)
518 PULONG PrivilegesToKeep,
519 _In_ ULONG PrivilegeCount)
520{
522 UINT64 PrivilegesToKeepBitmap;
527
529
530 DPRINT("RtlRemovePrivileges(%p, %p, %u)\n", TokenHandle, PrivilegesToKeep, PrivilegeCount);
531
532 /* Save privileges that should be keep */
533 PrivilegesToKeepBitmap = 0;
534 if (PrivilegeCount)
535 {
536 for (i = 0; i < PrivilegeCount; i++)
537 {
538 if (PrivilegesToKeep[i] > SE_MAX_WELL_KNOWN_PRIVILEGE)
539 {
541 }
542 PrivilegesToKeepBitmap |= (1ULL << PrivilegesToKeep[i]);
543 }
544 }
545
546 /* Get token privileges information */
547 Status = ZwQueryInformationToken(TokenHandle,
549 Buffer,
550 sizeof(Buffer),
551 &ReturnLength);
552 if (!NT_SUCCESS(Status))
553 {
554 return Status;
555 }
556
557 /* Remove all privileges that we don't need to keep */
559 for (i = 0; i < Privileges->PrivilegeCount; i++)
560 {
561 LARGE_INTEGER Privilege = *(LARGE_INTEGER*)&Privileges->Privileges[i].Luid;
563 if (PrivilegesToKeepBitmap & (1ULL << Privilege.QuadPart))
564 {
565 PrivilegesToKeepBitmap &= ~(1ULL << Privilege.QuadPart);
566 }
567 else
568 {
569 Privileges->Privileges[i].Attributes = SE_PRIVILEGE_REMOVED;
570 }
571 }
572
573 if (PrivilegesToKeepBitmap)
574 {
576 }
577 else
578 {
580 FALSE,
582 sizeof(Buffer),
583 NULL,
584 NULL);
585 }
586
587 return Status;
588}
589
590#endif /* (NTDDI_VERSION >= NTDDI_VISTA) */
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
unsigned char BOOLEAN
unsigned long long UINT64
LONG NTSTATUS
Definition: precomp.h:26
#define DPRINT1
Definition: precomp.h:8
PVOID NTAPI RtlAllocateHeap(IN PVOID HeapHandle, IN ULONG Flags, IN SIZE_T Size)
Definition: heap.c:590
BOOLEAN NTAPI RtlFreeHeap(IN PVOID HeapHandle, IN ULONG Flags, IN PVOID HeapBase)
Definition: heap.c:608
Definition: bufpool.h:45
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#define STATUS_NO_MEMORY
Definition: d3dkmdt.h:51
#define NULL
Definition: types.h:112
#define TRUE
Definition: types.h:120
#define FALSE
Definition: types.h:117
#define NT_SUCCESS(StatCode)
Definition: apphelp.c:33
@ ThreadImpersonationToken
Definition: compat.h:940
static const WCHAR Cleanup[]
Definition: register.c:80
IN CINT OUT PVOID IN ULONG OUT PULONG ReturnLength
Definition: dumpinfo.c:43
Status
Definition: gdiplustypes.h:25
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
#define C_ASSERT(e)
Definition: intsafe.h:73
#define NtCurrentTeb
enum _SECURITY_IMPERSONATION_LEVEL SECURITY_IMPERSONATION_LEVEL
@ SecurityDelegation
Definition: lsa.idl:58
struct _SECURITY_QUALITY_OF_SERVICE SECURITY_QUALITY_OF_SERVICE
#define ASSERT(a)
Definition: mode.c:44
@ TokenImpersonation
Definition: imports.h:274
#define SE_MIN_WELL_KNOWN_PRIVILEGE
Definition: security.c:655
#define SE_MAX_WELL_KNOWN_PRIVILEGE
Definition: security.c:685
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
@ Enabled
Definition: mountmgr.h:179
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
_In_ ACCESS_MASK _In_ ULONG _Out_ PHANDLE TokenHandle
Definition: psfuncs.h:726
NTSYSAPI NTSTATUS NTAPI ZwOpenThreadToken(_In_ HANDLE ThreadHandle, _In_ ACCESS_MASK DesiredAccess, _In_ BOOLEAN OpenAsSelf, _Out_ PHANDLE TokenHandle)
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
struct _RTL_ACQUIRE_STATE * PRTL_ACQUIRE_STATE
#define RTL_ACQUIRE_PRIVILEGE_IMPERSONATE
Definition: rtltypes.h:270
#define RTL_ACQUIRE_PRIVILEGE_PROCESS
Definition: rtltypes.h:271
_Must_inspect_result_ NTSYSAPI NTSTATUS NTAPI ZwAdjustPrivilegesToken(_In_ HANDLE TokenHandle, _In_ BOOLEAN DisableAllPrivileges, _In_opt_ PTOKEN_PRIVILEGES NewState, _In_ ULONG BufferLength, _Out_writes_bytes_to_opt_(BufferLength, *ReturnLength) PTOKEN_PRIVILEGES PreviousState, _When_(PreviousState !=NULL, _Out_) PULONG ReturnLength)
#define _Notnull_
Definition: no_sal2.h:54
#define _In_reads_opt_(s)
Definition: no_sal2.h:222
#define _In_
Definition: no_sal2.h:158
#define _When_(c, a)
Definition: no_sal2.h:38
ULONG ACCESS_MASK
Definition: nt_native.h:40
#define NtCurrentProcess()
Definition: nt_native.h:1657
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
PVOID *typedef PHANDLE
Definition: ntsecpkg.h:455
#define STATUS_NOT_ALL_ASSIGNED
Definition: ntstatus.h:85
#define PAGED_CODE_RTL()
Definition: rtlp.h:16
NTSTATUS NTAPI RtlAdjustPrivilege(IN ULONG Privilege, IN BOOLEAN Enable, IN BOOLEAN CurrentThread, OUT PBOOLEAN Enabled)
Definition: priv.c:415
VOID NTAPI RtlReleasePrivilege(IN PVOID ReturnedState)
Definition: priv.c:363
NTSTATUS NTAPI RtlAcquirePrivilege(IN PULONG Privilege, IN ULONG NumPriv, IN ULONG Flags, OUT PVOID *ReturnedState)
Definition: priv.c:110
NTSTATUS NTAPI RtlpOpenThreadToken(IN ACCESS_MASK DesiredAccess, OUT PHANDLE TokenHandle)
Definition: priv.c:24
NTSTATUS NTAPI RtlRemovePrivileges(_In_ HANDLE TokenHandle, _In_reads_opt_(PrivilegeCount) _When_(PrivilegeCount !=0, _Notnull_) PULONG PrivilegesToKeep, _In_ ULONG PrivilegeCount)
Removes all privileges in the specified access token.
Definition: priv.c:515
NTSTATUS NTAPI RtlImpersonateSelf(IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
Definition: priv.c:45
#define STATUS_SUCCESS
Definition: shellext.h:65
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define DPRINT
Definition: sndvol32.h:73
LONG HighPart
DWORD LowPart
PVOID SecurityQualityOfService
Definition: umtypes.h:188
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode
Definition: lsa.idl:66
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
$ULONG PrivilegeCount
Definition: setypes.h:1023
LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]
Definition: setypes.h:1024
uint32_t * PULONG
Definition: typedefs.h:59
unsigned char * PBOOLEAN
Definition: typedefs.h:53
#define ANYSIZE_ARRAY
Definition: typedefs.h:46
#define NTAPI
Definition: typedefs.h:36
#define IN
Definition: typedefs.h:39
uint32_t ULONG
Definition: typedefs.h:59
#define OUT
Definition: typedefs.h:40
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
_Out_ PBOOLEAN _Out_ PBOOLEAN _Out_ PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: psfuncs.h:156
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:17
#define TOKEN_DUPLICATE
Definition: setypes.h:926
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:930
struct _TOKEN_PRIVILEGES TOKEN_PRIVILEGES
#define TOKEN_QUERY
Definition: setypes.h:928
@ TokenPrivileges
Definition: setypes.h:968
struct _TOKEN_PRIVILEGES * PTOKEN_PRIVILEGES
#define TOKEN_IMPERSONATE
Definition: setypes.h:927
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
#define SE_PRIVILEGE_REMOVED
Definition: setypes.h:64
unsigned char UCHAR
Definition: xmlstorage.h:181
NTSYSAPI NTSTATUS NTAPI ZwOpenProcessToken(_In_ HANDLE ProcessHandle, _In_ ACCESS_MASK DesiredAccess, _Out_ PHANDLE TokenHandle)
#define NtCurrentThread()