2 * COPYRIGHT: See COPYING in the top level directory
3 * PROJECT: ReactOS system libraries
4 * FILE: lib/advapi32/token/token.c
5 * PURPOSE: Token functions
6 * PROGRAMMER: Ariadne ( ariadne@xs4all.nl)
20 AdjustTokenGroups (HANDLE TokenHandle
,
22 PTOKEN_GROUPS NewState
,
24 PTOKEN_GROUPS PreviousState
,
29 Status
= NtAdjustGroupsToken (TokenHandle
,
34 (PULONG
)ReturnLength
);
35 if (!NT_SUCCESS (Status
))
37 SetLastError (RtlNtStatusToDosError (Status
));
49 AdjustTokenPrivileges (HANDLE TokenHandle
,
50 BOOL DisableAllPrivileges
,
51 PTOKEN_PRIVILEGES NewState
,
53 PTOKEN_PRIVILEGES PreviousState
,
58 Status
= NtAdjustPrivilegesToken (TokenHandle
,
63 (PULONG
)ReturnLength
);
64 if (STATUS_NOT_ALL_ASSIGNED
== Status
)
66 SetLastError(ERROR_NOT_ALL_ASSIGNED
);
69 if (! NT_SUCCESS(Status
))
71 SetLastError(RtlNtStatusToDosError(Status
));
75 SetLastError(ERROR_SUCCESS
); /* AdjustTokenPrivileges is documented to do this */
84 GetTokenInformation (HANDLE TokenHandle
,
85 TOKEN_INFORMATION_CLASS TokenInformationClass
,
86 LPVOID TokenInformation
,
87 DWORD TokenInformationLength
,
92 Status
= NtQueryInformationToken (TokenHandle
,
93 TokenInformationClass
,
95 TokenInformationLength
,
96 (PULONG
)ReturnLength
);
97 if (!NT_SUCCESS (Status
))
99 SetLastError (RtlNtStatusToDosError (Status
));
111 SetTokenInformation (HANDLE TokenHandle
,
112 TOKEN_INFORMATION_CLASS TokenInformationClass
,
113 LPVOID TokenInformation
,
114 DWORD TokenInformationLength
)
118 Status
= NtSetInformationToken (TokenHandle
,
119 TokenInformationClass
,
121 TokenInformationLength
);
122 if (!NT_SUCCESS (Status
))
124 SetLastError (RtlNtStatusToDosError (Status
));
136 AccessCheck (PSECURITY_DESCRIPTOR pSecurityDescriptor
,
139 PGENERIC_MAPPING GenericMapping
,
140 PPRIVILEGE_SET PrivilegeSet
,
141 LPDWORD PrivilegeSetLength
,
142 LPDWORD GrantedAccess
,
148 Status
= NtAccessCheck (pSecurityDescriptor
,
153 (PULONG
)PrivilegeSetLength
,
154 (PACCESS_MASK
)GrantedAccess
,
156 if (!NT_SUCCESS (Status
))
158 SetLastError (RtlNtStatusToDosError (Status
));
162 if (!NT_SUCCESS (AccessStat
))
164 SetLastError (RtlNtStatusToDosError (Status
));
165 *AccessStatus
= FALSE
;
169 *AccessStatus
= TRUE
;
179 OpenProcessToken (HANDLE ProcessHandle
,
185 Status
= NtOpenProcessToken (ProcessHandle
,
188 if (!NT_SUCCESS (Status
))
190 SetLastError (RtlNtStatusToDosError (Status
));
202 OpenThreadToken (HANDLE ThreadHandle
,
209 Status
= NtOpenThreadToken (ThreadHandle
,
213 if (!NT_SUCCESS(Status
))
215 SetLastError (RtlNtStatusToDosError (Status
));
227 SetThreadToken (PHANDLE ThreadHandle
,
233 hThread
= NtCurrentThread();
234 if (ThreadHandle
!= NULL
)
235 hThread
= ThreadHandle
;
237 Status
= NtSetInformationThread (hThread
,
238 ThreadImpersonationToken
,
241 if (!NT_SUCCESS(Status
))
243 SetLastError (RtlNtStatusToDosError (Status
));
255 DuplicateTokenEx (HANDLE ExistingTokenHandle
,
256 DWORD dwDesiredAccess
,
257 LPSECURITY_ATTRIBUTES lpTokenAttributes
,
258 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
259 TOKEN_TYPE TokenType
,
260 PHANDLE DuplicateTokenHandle
)
262 OBJECT_ATTRIBUTES ObjectAttributes
;
265 SECURITY_QUALITY_OF_SERVICE Sqos
;
267 Sqos
.Length
= sizeof(SECURITY_QUALITY_OF_SERVICE
);
268 Sqos
.ImpersonationLevel
= ImpersonationLevel
;
269 Sqos
.ContextTrackingMode
= 0;
270 Sqos
.EffectiveOnly
= FALSE
;
272 InitializeObjectAttributes(
275 lpTokenAttributes
->bInheritHandle
? OBJ_INHERIT
: 0,
277 lpTokenAttributes
->lpSecurityDescriptor
280 ObjectAttributes
.SecurityQualityOfService
= &Sqos
;
282 Status
= NtDuplicateToken (ExistingTokenHandle
,
285 Sqos
.EffectiveOnly
, /* why both here _and_ in Sqos? */
288 if (!NT_SUCCESS(Status
))
290 SetLastError(RtlNtStatusToDosError(Status
));
302 DuplicateToken (HANDLE ExistingTokenHandle
,
303 SECURITY_IMPERSONATION_LEVEL ImpersonationLevel
,
304 PHANDLE DuplicateTokenHandle
)
306 return DuplicateTokenEx (ExistingTokenHandle
,
307 TOKEN_DUPLICATE
| TOKEN_IMPERSONATE
| TOKEN_QUERY
,
311 DuplicateTokenHandle
);
319 CheckTokenMembership (HANDLE ExistingTokenHandle
,
324 BOOL ReleaseToken
= FALSE
;
328 PTOKEN_GROUPS lpGroups
= NULL
;
329 TOKEN_TYPE TokenInformation
;
331 if (IsMember
== NULL
)
333 SetLastError(ERROR_INVALID_PARAMETER
);
337 if (ExistingTokenHandle
== NULL
)
339 /* Get impersonation token of the calling thread */
340 if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY
, FALSE
, &ExistingTokenHandle
))
343 if (!DuplicateToken(ExistingTokenHandle
, SecurityAnonymous
, &AccessToken
))
345 CloseHandle(ExistingTokenHandle
);
348 CloseHandle(ExistingTokenHandle
);
353 if (!GetTokenInformation(ExistingTokenHandle
, TokenType
, &TokenInformation
, sizeof(TokenInformation
), &dwSize
))
355 if (TokenInformation
!= TokenImpersonation
)
357 /* Duplicate token to have a impersonation token */
358 if (!DuplicateToken(ExistingTokenHandle
, SecurityAnonymous
, &AccessToken
))
363 AccessToken
= ExistingTokenHandle
;
367 /* Search in groups of the token */
368 if (!GetTokenInformation(AccessToken
, TokenGroups
, NULL
, 0, &dwSize
))
370 lpGroups
= (PTOKEN_GROUPS
)HeapAlloc(GetProcessHeap(), 0, dwSize
);
373 if (!GetTokenInformation(AccessToken
, TokenGroups
, lpGroups
, dwSize
, &dwSize
))
375 for (i
= 0; i
< lpGroups
->GroupCount
; i
++)
377 if (EqualSid(SidToCheck
, &lpGroups
->Groups
[i
].Sid
))
384 /* FIXME: Search in users of the token? */
385 DPRINT1("CheckTokenMembership() partially implemented!\n");
389 if (lpGroups
!= NULL
)
390 HeapFree(GetProcessHeap(), 0, lpGroups
);
392 CloseHandle(AccessToken
);