ReactOS 0.4.15-dev-7958-gcd0bb1a
priv.c File Reference
#include <rtl.h>
#include <debug.h>
Include dependency graph for priv.c:

Go to the source code of this file.

Macros

#define NDEBUG
 

Functions

NTSTATUS NTAPI RtlpOpenThreadToken (IN ACCESS_MASK DesiredAccess, OUT PHANDLE TokenHandle)
 
NTSTATUS NTAPI RtlImpersonateSelf (IN SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
 
NTSTATUS NTAPI RtlAcquirePrivilege (IN PULONG Privilege, IN ULONG NumPriv, IN ULONG Flags, OUT PVOID *ReturnedState)
 
VOID NTAPI RtlReleasePrivilege (IN PVOID ReturnedState)
 
NTSTATUS NTAPI RtlAdjustPrivilege (IN ULONG Privilege, IN BOOLEAN Enable, IN BOOLEAN CurrentThread, OUT PBOOLEAN Enabled)
 
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.
 

Macro Definition Documentation

◆ NDEBUG

#define NDEBUG

Definition at line 14 of file priv.c.

Function Documentation

◆ RtlAcquirePrivilege()

NTSTATUS NTAPI RtlAcquirePrivilege ( IN PULONG  Privilege,
IN ULONG  NumPriv,
IN ULONG  Flags,
OUT PVOID ReturnedState 
)

Definition at line 110 of file priv.c.

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}
#define STATUS_PRIVILEGE_NOT_HELD
Definition: DriverTester.h:9
LONG NTSTATUS
Definition: precomp.h:26
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
IN PUNICODE_STRING IN POBJECT_ATTRIBUTES ObjectAttributes
Definition: conport.c:36
#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:32
@ 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 NtCurrentTeb
@ SecurityDelegation
Definition: lsa.idl:58
struct _SECURITY_QUALITY_OF_SERVICE SECURITY_QUALITY_OF_SERVICE
@ TokenImpersonation
Definition: imports.h:274
#define InitializeObjectAttributes(p, n, a, r, s)
Definition: reg.c:106
NTSYSAPI NTSTATUS NTAPI ZwClose(_In_ HANDLE Handle)
DECLSPEC_NORETURN NTSYSAPI VOID NTAPI RtlRaiseStatus(_In_ NTSTATUS Status)
#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 NtCurrentProcess()
Definition: nt_native.h:1657
#define STATUS_NOT_ALL_ASSIGNED
Definition: ntstatus.h:85
#define STATUS_NO_MEMORY
Definition: ntstatus.h:260
NTSTATUS NTAPI RtlpOpenThreadToken(IN ACCESS_MASK DesiredAccess, OUT PHANDLE TokenHandle)
Definition: priv.c:24
#define STATUS_BUFFER_TOO_SMALL
Definition: shellext.h:69
#define DPRINT
Definition: sndvol32.h:71
SECURITY_CONTEXT_TRACKING_MODE ContextTrackingMode
Definition: lsa.idl:66
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: lsa.idl:65
#define ANYSIZE_ARRAY
Definition: typedefs.h:46
uint32_t ULONG
Definition: typedefs.h:59
#define STATUS_INVALID_PARAMETER
Definition: udferr_usr.h:135
BOOL Privilege(LPTSTR pszPrivilege, BOOL bEnable)
Definition: user_lib.cpp:531
_Must_inspect_result_ _In_ ULONG Flags
Definition: wsk.h:170
#define TOKEN_DUPLICATE
Definition: setypes.h:926
#define TOKEN_ADJUST_PRIVILEGES
Definition: setypes.h:930
#define TOKEN_QUERY
Definition: setypes.h:928
struct _TOKEN_PRIVILEGES * PTOKEN_PRIVILEGES
#define TOKEN_IMPERSONATE
Definition: setypes.h:927
#define SE_PRIVILEGE_ENABLED
Definition: setypes.h:63
NTSYSAPI NTSTATUS NTAPI ZwOpenProcessToken(_In_ HANDLE ProcessHandle, _In_ ACCESS_MASK DesiredAccess, _Out_ PHANDLE TokenHandle)
#define NtCurrentThread()

◆ RtlAdjustPrivilege()

NTSTATUS NTAPI RtlAdjustPrivilege ( IN ULONG  Privilege,
IN BOOLEAN  Enable,
IN BOOLEAN  CurrentThread,
OUT PBOOLEAN  Enabled 
)

Definition at line 415 of file priv.c.

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}
#define DPRINT1
Definition: precomp.h:8
@ Enabled
Definition: mountmgr.h:159
_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)
_In_ ULONGLONG _In_ ULONGLONG _In_ BOOLEAN Enable
Definition: ntddpcm.h:142
#define PAGED_CODE_RTL()
Definition: rtlp.h:16
#define STATUS_SUCCESS
Definition: shellext.h:65
LONG HighPart
DWORD LowPart
$ULONG PrivilegeCount
Definition: setypes.h:1023
LUID_AND_ATTRIBUTES Privileges[ANYSIZE_ARRAY]
Definition: setypes.h:1024

◆ RtlImpersonateSelf()

NTSTATUS NTAPI RtlImpersonateSelf ( IN SECURITY_IMPERSONATION_LEVEL  ImpersonationLevel)

Definition at line 45 of file priv.c.

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}
NTSTATUS NTAPI NtClose(IN HANDLE Handle)
Definition: obhandle.c:3402
PVOID SecurityQualityOfService
Definition: umtypes.h:188
_Out_ PBOOLEAN _Out_ PBOOLEAN _Out_ PSECURITY_IMPERSONATION_LEVEL ImpersonationLevel
Definition: psfuncs.h:156

Referenced by ImpersonateSelf(), InsertTokenToProcessCommon(), and START_TEST().

◆ RtlpOpenThreadToken()

NTSTATUS NTAPI RtlpOpenThreadToken ( IN ACCESS_MASK  DesiredAccess,
OUT PHANDLE  TokenHandle 
)

Definition at line 24 of file priv.c.

26{
28
31 if (!NT_SUCCESS(Status))
32 {
35 }
36
37 return Status;
38}
_Must_inspect_result_ _In_ WDFDEVICE _In_ ULONG _In_ ACCESS_MASK DesiredAccess
Definition: wdfdevice.h:2658

Referenced by RtlAcquirePrivilege().

◆ RtlReleasePrivilege()

VOID NTAPI RtlReleasePrivilege ( IN PVOID  ReturnedState)

Definition at line 363 of file priv.c.

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}
struct _RTL_ACQUIRE_STATE * PRTL_ACQUIRE_STATE

◆ RtlRemovePrivileges()

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.

Parameters
[in]TokenHandleA handle to the access token that contains the privileges to be removed.
[in]PrivilegesToKeepA pointer to an array of privilege values (defined as SE_XXX_PRIVILEGE) that specify the privileges to keep in the token.
[in]PrivilegeCountSpecifies the number of entries in the PrivilegesToKeep array.
Returns
Returns STATUS_SUCCESS if privileges removed successfully. STATUS_INVALID_PARAMETER is returned if input privilege value greater than SE_MAX_WELL_KNOWN_PRIVILEGE. STATUS_NOT_ALL_ASSIGNED is returned if The token does not have one or more of the privileges specified in the PrivilegesToKeep parameter, and no privileges were removed. A failure NTSTATUS code is returned otherwise.

Definition at line 515 of file priv.c.

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}
unsigned long long UINT64
Definition: bufpool.h:45
#define C_ASSERT(e)
Definition: intsafe.h:73
#define ASSERT(a)
Definition: mode.c:44
#define SE_MIN_WELL_KNOWN_PRIVILEGE
Definition: security.c:655
#define SE_MAX_WELL_KNOWN_PRIVILEGE
Definition: security.c:685
_In_ PSECURITY_SUBJECT_CONTEXT _In_ BOOLEAN _In_ ACCESS_MASK _In_ ACCESS_MASK _Outptr_opt_ PPRIVILEGE_SET * Privileges
Definition: sefuncs.h:17
struct _TOKEN_PRIVILEGES TOKEN_PRIVILEGES
@ TokenPrivileges
Definition: setypes.h:968
#define SE_PRIVILEGE_REMOVED
Definition: setypes.h:64
unsigned char UCHAR
Definition: xmlstorage.h:181

Referenced by START_TEST().