advapi32: Move token functions to kernelbase.

Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Alexandre Julliard 2019-06-25 12:35:37 +02:00
parent d03eae54f4
commit 7557620aeb
5 changed files with 389 additions and 606 deletions

View File

@ -29,8 +29,8 @@
@ stdcall AddMandatoryAce(ptr long long long ptr)
# @ stub AddUsersToEncryptedFile
# @ stub AddUsersToEncryptedFileEx
@ stdcall AdjustTokenGroups(long long ptr long ptr ptr)
@ stdcall AdjustTokenPrivileges(long long ptr long ptr ptr)
@ stdcall -import AdjustTokenGroups(long long ptr long ptr ptr)
@ stdcall -import AdjustTokenPrivileges(long long ptr long ptr ptr)
@ stdcall -import AllocateAndInitializeSid(ptr long long long long long long long long long ptr)
@ stdcall -import AllocateLocallyUniqueId(ptr)
@ stdcall AreAllAccessesGranted(long long)
@ -94,7 +94,7 @@
@ stdcall ChangeServiceConfigA(long long long long wstr str ptr str str str str)
@ stdcall ChangeServiceConfigW(long long long long wstr wstr ptr wstr wstr wstr wstr)
# @ stub CheckForHiberboot
@ stdcall CheckTokenMembership(long ptr ptr)
@ stdcall -import CheckTokenMembership(long ptr ptr)
@ stdcall ClearEventLogA (long str)
@ stdcall ClearEventLogW (long wstr)
# @ stub CloseCodeAuthzLevel
@ -142,7 +142,7 @@
@ stdcall CreateProcessAsUserW(long wstr wstr ptr ptr long long ptr wstr ptr ptr) kernel32.CreateProcessAsUserW
@ stdcall CreateProcessWithLogonW(wstr wstr wstr long wstr wstr long ptr wstr ptr ptr)
@ stdcall CreateProcessWithTokenW(long long wstr wstr long ptr wstr ptr ptr)
@ stdcall CreateRestrictedToken(long long long ptr long ptr long ptr ptr)
@ stdcall -import CreateRestrictedToken(long long long ptr long ptr long ptr ptr)
@ stdcall CreateServiceA(long str str long long long long str str ptr str str str)
@ stdcall CreateServiceW(long wstr wstr long long long long wstr wstr ptr wstr wstr wstr)
# @ stub CreateTraceInstanceId
@ -239,8 +239,8 @@
@ stdcall DeregisterEventSource(long)
@ stdcall DestroyPrivateObjectSecurity(ptr)
# @ stub DuplicateEncryptionInfoFile
@ stdcall DuplicateToken(long long ptr)
@ stdcall DuplicateTokenEx(long long ptr long long ptr)
@ stdcall -import DuplicateToken(long long ptr)
@ stdcall -import DuplicateTokenEx(long long ptr long long ptr)
# @ stub ElfBackupEventLogFileA
# @ stub ElfBackupEventLogFileW
# @ stub ElfChangeNotify
@ -371,7 +371,7 @@
@ stub GetSiteSidFromToken
# @ stub GetStringConditionFromBinary
# @ stub GetThreadWaitChain
@ stdcall GetTokenInformation(long long ptr long ptr)
@ stdcall -import GetTokenInformation(long long ptr long ptr)
@ stdcall GetTraceEnableFlags(int64) ntdll.EtwGetTraceEnableFlags
@ stdcall GetTraceEnableLevel(int64) ntdll.EtwGetTraceEnableLevel
@ stdcall -ret64 GetTraceLoggerHandle(ptr) ntdll.EtwGetTraceLoggerHandle
@ -398,10 +398,10 @@
# @ stub I_ScSetServiceBitsW
# @ stub I_ScValidatePnPService
# @ stub IdentifyCodeAuthzLevelW
@ stdcall ImpersonateAnonymousToken(long)
@ stdcall ImpersonateLoggedOnUser(long)
@ stdcall ImpersonateNamedPipeClient(long)
@ stdcall ImpersonateSelf(long)
@ stdcall -import ImpersonateAnonymousToken(long)
@ stdcall -import ImpersonateLoggedOnUser(long)
@ stdcall -import ImpersonateNamedPipeClient(long)
@ stdcall -import ImpersonateSelf(long)
@ stdcall InitializeAcl(ptr long long)
@ stdcall InitializeSecurityDescriptor(ptr long)
@ stdcall -import InitializeSid(ptr ptr long)
@ -414,7 +414,7 @@
@ stub InstallApplication
@ stub IsProcessRestricted
@ stdcall IsTextUnicode(ptr long ptr)
@ stdcall IsTokenRestricted(long)
@ stdcall -import IsTokenRestricted(long)
# @ stub IsTokenUntrusted
@ stdcall IsValidAcl(ptr)
# @ stub IsValidRelativeSecurityDescriptor
@ -542,12 +542,12 @@
@ stdcall OpenEncryptedFileRawW(wstr long ptr)
@ stdcall OpenEventLogA (str str)
@ stdcall OpenEventLogW (wstr wstr)
@ stdcall OpenProcessToken(long long ptr)
@ stdcall -import OpenProcessToken(long long ptr)
@ stdcall OpenSCManagerA(str str long)
@ stdcall OpenSCManagerW(wstr wstr long)
@ stdcall OpenServiceA(long str long)
@ stdcall OpenServiceW(long wstr long)
@ stdcall OpenThreadToken(long long long ptr)
@ stdcall -import OpenThreadToken(long long long ptr)
# @ stub OpenThreadWaitChainSession
@ stdcall -ret64 OpenTraceA(ptr)
@ stdcall -ret64 OpenTraceW(ptr)
@ -582,7 +582,7 @@
@ stdcall PerfStartProvider(ptr ptr ptr)
@ stdcall PerfStartProviderEx(ptr ptr ptr)
@ stdcall PerfStopProvider(long)
@ stdcall PrivilegeCheck(ptr ptr ptr)
@ stdcall -import PrivilegeCheck(ptr ptr ptr)
@ stdcall PrivilegedServiceAuditAlarmA(str str long ptr long)
@ stdcall PrivilegedServiceAuditAlarmW(wstr wstr long ptr long)
# @ stub ProcessIdleTasks
@ -712,7 +712,7 @@
# @ stub RemoveUsersFromEncryptedFile
@ stdcall ReportEventA(long long long long ptr long long ptr ptr)
@ stdcall ReportEventW(long long long long ptr long long ptr ptr)
@ stdcall RevertToSelf()
@ stdcall -import RevertToSelf()
# @ stub SafeBaseRegGetKeySecurity
@ stdcall SaferCloseLevel(ptr)
@ stdcall SaferComputeTokenFromLevel(ptr ptr ptr long ptr)
@ -763,8 +763,8 @@
@ stdcall SetServiceBits(long long long long)
@ stdcall SetServiceObjectSecurity(long long ptr)
@ stdcall SetServiceStatus(long ptr)
@ stdcall SetThreadToken (ptr ptr)
@ stdcall SetTokenInformation (long long ptr long)
@ stdcall -import SetThreadToken(ptr ptr)
@ stdcall -import SetTokenInformation(long long ptr long)
# @ stub SetTraceCallback
# @ stub SetUserFileEncryptionKey
# @ stub SetUserFileEncryptionKeyEx

View File

@ -523,401 +523,6 @@ BOOL ADVAPI_GetComputerSid(PSID sid)
return TRUE;
}
/* ##############################
###### TOKEN FUNCTIONS ######
##############################
*/
/******************************************************************************
* OpenProcessToken [ADVAPI32.@]
* Opens the access token associated with a process handle.
*
* PARAMS
* ProcessHandle [I] Handle to process
* DesiredAccess [I] Desired access to process
* TokenHandle [O] Pointer to handle of open access token
*
* RETURNS
* Success: TRUE. TokenHandle contains the access token.
* Failure: FALSE.
*
* NOTES
* See NtOpenProcessToken.
*/
BOOL WINAPI
OpenProcessToken( HANDLE ProcessHandle, DWORD DesiredAccess,
HANDLE *TokenHandle )
{
return set_ntstatus(NtOpenProcessToken( ProcessHandle, DesiredAccess, TokenHandle ));
}
/******************************************************************************
* OpenThreadToken [ADVAPI32.@]
*
* Opens the access token associated with a thread handle.
*
* PARAMS
* ThreadHandle [I] Handle to process
* DesiredAccess [I] Desired access to the thread
* OpenAsSelf [I] ???
* TokenHandle [O] Destination for the token handle
*
* RETURNS
* Success: TRUE. TokenHandle contains the access token.
* Failure: FALSE.
*
* NOTES
* See NtOpenThreadToken.
*/
BOOL WINAPI
OpenThreadToken( HANDLE ThreadHandle, DWORD DesiredAccess,
BOOL OpenAsSelf, HANDLE *TokenHandle)
{
return set_ntstatus( NtOpenThreadToken(ThreadHandle, DesiredAccess, OpenAsSelf, TokenHandle));
}
BOOL WINAPI
AdjustTokenGroups( HANDLE TokenHandle, BOOL ResetToDefault, PTOKEN_GROUPS NewState,
DWORD BufferLength, PTOKEN_GROUPS PreviousState, PDWORD ReturnLength )
{
return set_ntstatus( NtAdjustGroupsToken(TokenHandle, ResetToDefault, NewState, BufferLength,
PreviousState, ReturnLength));
}
/******************************************************************************
* AdjustTokenPrivileges [ADVAPI32.@]
*
* Adjust the privileges of an open token handle.
*
* PARAMS
* TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
* DisableAllPrivileges [I] TRUE=Remove all privileges, FALSE=Use NewState
* NewState [I] Desired new privileges of the token
* BufferLength [I] Length of NewState
* PreviousState [O] Destination for the previous state
* ReturnLength [I/O] Size of PreviousState
*
*
* RETURNS
* Success: TRUE. Privileges are set to NewState and PreviousState is updated.
* Failure: FALSE.
*
* NOTES
* See NtAdjustPrivilegesToken.
*/
BOOL WINAPI
AdjustTokenPrivileges( HANDLE TokenHandle, BOOL DisableAllPrivileges,
PTOKEN_PRIVILEGES NewState, DWORD BufferLength,
PTOKEN_PRIVILEGES PreviousState, PDWORD ReturnLength )
{
NTSTATUS status;
TRACE("(%p %d %p %d %p %p)\n", TokenHandle, DisableAllPrivileges, NewState, BufferLength,
PreviousState, ReturnLength);
status = NtAdjustPrivilegesToken(TokenHandle, DisableAllPrivileges,
NewState, BufferLength, PreviousState,
ReturnLength);
SetLastError( RtlNtStatusToDosError( status ));
if ((status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED))
return TRUE;
else
return FALSE;
}
/******************************************************************************
* CheckTokenMembership [ADVAPI32.@]
*
* Determine if an access token is a member of a SID.
*
* PARAMS
* TokenHandle [I] Handle from OpenProcessToken() or OpenThreadToken()
* SidToCheck [I] SID that possibly contains the token
* IsMember [O] Destination for result.
*
* RETURNS
* Success: TRUE. IsMember is TRUE if TokenHandle is a member, FALSE otherwise.
* Failure: FALSE.
*/
BOOL WINAPI
CheckTokenMembership( HANDLE token, PSID sid_to_check,
PBOOL is_member )
{
PTOKEN_GROUPS token_groups = NULL;
HANDLE thread_token = NULL;
DWORD size, i;
BOOL ret;
TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
*is_member = FALSE;
if (!token)
{
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
{
HANDLE process_token;
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
if (!ret)
goto exit;
ret = DuplicateTokenEx(process_token, TOKEN_QUERY,
NULL, SecurityImpersonation, TokenImpersonation,
&thread_token);
CloseHandle(process_token);
if (!ret)
goto exit;
}
token = thread_token;
}
else
{
TOKEN_TYPE type;
ret = GetTokenInformation(token, TokenType, &type, sizeof(TOKEN_TYPE), &size);
if (!ret) goto exit;
if (type == TokenPrimary)
{
SetLastError(ERROR_NO_IMPERSONATION_TOKEN);
return FALSE;
}
}
ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
goto exit;
token_groups = heap_alloc(size);
if (!token_groups)
{
ret = FALSE;
goto exit;
}
ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
if (!ret)
goto exit;
for (i = 0; i < token_groups->GroupCount; i++)
{
TRACE("Groups[%d]: {0x%x, %s}\n", i,
token_groups->Groups[i].Attributes,
debugstr_sid(token_groups->Groups[i].Sid));
if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
EqualSid(sid_to_check, token_groups->Groups[i].Sid))
{
*is_member = TRUE;
TRACE("sid enabled and found in token\n");
break;
}
}
exit:
heap_free(token_groups);
if (thread_token != NULL) CloseHandle(thread_token);
return ret;
}
/******************************************************************************
* GetTokenInformation [ADVAPI32.@]
*
* Get a type of information about an access token.
*
* PARAMS
* token [I] Handle from OpenProcessToken() or OpenThreadToken()
* tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
* tokeninfo [O] Destination for token information
* tokeninfolength [I] Length of tokeninfo
* retlen [O] Destination for returned token information length
*
* RETURNS
* Success: TRUE. tokeninfo contains retlen bytes of token information
* Failure: FALSE.
*
* NOTES
* See NtQueryInformationToken.
*/
BOOL WINAPI
GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
LPVOID tokeninfo, DWORD tokeninfolength, LPDWORD retlen )
{
TRACE("(%p, %s, %p, %d, %p):\n",
token,
(tokeninfoclass == TokenUser) ? "TokenUser" :
(tokeninfoclass == TokenGroups) ? "TokenGroups" :
(tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
(tokeninfoclass == TokenOwner) ? "TokenOwner" :
(tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
(tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
(tokeninfoclass == TokenSource) ? "TokenSource" :
(tokeninfoclass == TokenType) ? "TokenType" :
(tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
(tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
(tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
(tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
(tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
(tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
(tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
"Unknown",
tokeninfo, tokeninfolength, retlen);
return set_ntstatus( NtQueryInformationToken( token, tokeninfoclass, tokeninfo,
tokeninfolength, retlen));
}
/******************************************************************************
* SetTokenInformation [ADVAPI32.@]
*
* Set information for an access token.
*
* PARAMS
* token [I] Handle from OpenProcessToken() or OpenThreadToken()
* tokeninfoclass [I] A TOKEN_INFORMATION_CLASS from "winnt.h"
* tokeninfo [I] Token information to set
* tokeninfolength [I] Length of tokeninfo
*
* RETURNS
* Success: TRUE. The information for the token is set to tokeninfo.
* Failure: FALSE.
*/
BOOL WINAPI
SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS tokeninfoclass,
LPVOID tokeninfo, DWORD tokeninfolength )
{
TRACE("(%p, %s, %p, %d)\n",
token,
(tokeninfoclass == TokenUser) ? "TokenUser" :
(tokeninfoclass == TokenGroups) ? "TokenGroups" :
(tokeninfoclass == TokenPrivileges) ? "TokenPrivileges" :
(tokeninfoclass == TokenOwner) ? "TokenOwner" :
(tokeninfoclass == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
(tokeninfoclass == TokenDefaultDacl) ? "TokenDefaultDacl" :
(tokeninfoclass == TokenSource) ? "TokenSource" :
(tokeninfoclass == TokenType) ? "TokenType" :
(tokeninfoclass == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
(tokeninfoclass == TokenStatistics) ? "TokenStatistics" :
(tokeninfoclass == TokenRestrictedSids) ? "TokenRestrictedSids" :
(tokeninfoclass == TokenSessionId) ? "TokenSessionId" :
(tokeninfoclass == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
(tokeninfoclass == TokenSessionReference) ? "TokenSessionReference" :
(tokeninfoclass == TokenSandBoxInert) ? "TokenSandBoxInert" :
"Unknown",
tokeninfo, tokeninfolength);
return set_ntstatus( NtSetInformationToken( token, tokeninfoclass, tokeninfo, tokeninfolength ));
}
/*************************************************************************
* SetThreadToken [ADVAPI32.@]
*
* Assigns an 'impersonation token' to a thread so it can assume the
* security privileges of another thread or process. Can also remove
* a previously assigned token.
*
* PARAMS
* thread [O] Handle to thread to set the token for
* token [I] Token to set
*
* RETURNS
* Success: TRUE. The threads access token is set to token
* Failure: FALSE.
*
* NOTES
* Only supported on NT or higher. On Win9X this function does nothing.
* See SetTokenInformation.
*/
BOOL WINAPI SetThreadToken(PHANDLE thread, HANDLE token)
{
return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
ThreadImpersonationToken, &token, sizeof token ));
}
/*************************************************************************
* CreateRestrictedToken [ADVAPI32.@]
*
* Create a new more restricted token from an existing token.
*
* PARAMS
* baseToken [I] Token to base the new restricted token on
* flags [I] Options
* nDisableSids [I] Length of disableSids array
* disableSids [I] Array of SIDs to disable in the new token
* nDeletePrivs [I] Length of deletePrivs array
* deletePrivs [I] Array of privileges to delete in the new token
* nRestrictSids [I] Length of restrictSids array
* restrictSids [I] Array of SIDs to restrict in the new token
* newToken [O] Address where the new token is stored
*
* RETURNS
* Success: TRUE
* Failure: FALSE
*/
BOOL WINAPI CreateRestrictedToken(
HANDLE baseToken,
DWORD flags,
DWORD nDisableSids,
PSID_AND_ATTRIBUTES disableSids,
DWORD nDeletePrivs,
PLUID_AND_ATTRIBUTES deletePrivs,
DWORD nRestrictSids,
PSID_AND_ATTRIBUTES restrictSids,
PHANDLE newToken)
{
TOKEN_TYPE type;
SECURITY_IMPERSONATION_LEVEL level = SecurityAnonymous;
DWORD size;
FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
baseToken, flags, nDisableSids, disableSids,
nDeletePrivs, deletePrivs,
nRestrictSids, restrictSids,
newToken);
size = sizeof(type);
if (!GetTokenInformation( baseToken, TokenType, &type, size, &size )) return FALSE;
if (type == TokenImpersonation)
{
size = sizeof(level);
if (!GetTokenInformation( baseToken, TokenImpersonationLevel, &level, size, &size ))
return FALSE;
}
return DuplicateTokenEx( baseToken, MAXIMUM_ALLOWED, NULL, level, type, newToken );
}
BOOL WINAPI
IsTokenRestricted( HANDLE TokenHandle )
{
TOKEN_GROUPS *groups;
DWORD size;
NTSTATUS status;
BOOL restricted;
TRACE("(%p)\n", TokenHandle);
status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, NULL, 0, &size);
if (status != STATUS_BUFFER_TOO_SMALL)
return FALSE;
groups = heap_alloc(size);
if (!groups)
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
status = NtQueryInformationToken(TokenHandle, TokenRestrictedSids, groups, size, &size);
if (status != STATUS_SUCCESS)
{
heap_free(groups);
return set_ntstatus(status);
}
restricted = groups->GroupCount > 0;
heap_free(groups);
return restricted;
}
DWORD WINAPI
GetEffectiveRightsFromAclA( PACL pacl, PTRUSTEEA pTrustee, PACCESS_MASK pAccessRights )
{
@ -1392,16 +997,6 @@ BOOL WINAPI InitializeAcl(PACL acl, DWORD size, DWORD rev)
return set_ntstatus( RtlCreateAcl(acl, size, rev));
}
BOOL WINAPI ImpersonateNamedPipeClient( HANDLE hNamedPipe )
{
IO_STATUS_BLOCK io_block;
TRACE("(%p)\n", hNamedPipe);
return set_ntstatus( NtFsControlFile(hNamedPipe, NULL, NULL, NULL,
&io_block, FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0) );
}
/******************************************************************************
* AddAccessAllowedAce [ADVAPI32.@]
*/
@ -2300,114 +1895,6 @@ NotifyBootConfigStatus( BOOL x1 )
return TRUE;
}
/******************************************************************************
* RevertToSelf [ADVAPI32.@]
*
* Ends the impersonation of a user.
*
* PARAMS
* void []
*
* RETURNS
* Success: TRUE.
* Failure: FALSE.
*/
BOOL WINAPI
RevertToSelf( void )
{
HANDLE Token = NULL;
return set_ntstatus( NtSetInformationThread( GetCurrentThread(),
ThreadImpersonationToken, &Token, sizeof(Token) ) );
}
/******************************************************************************
* ImpersonateSelf [ADVAPI32.@]
*
* Makes an impersonation token that represents the process user and assigns
* to the current thread.
*
* PARAMS
* ImpersonationLevel [I] Level at which to impersonate.
*
* RETURNS
* Success: TRUE.
* Failure: FALSE.
*/
BOOL WINAPI
ImpersonateSelf(SECURITY_IMPERSONATION_LEVEL ImpersonationLevel)
{
return set_ntstatus( RtlImpersonateSelf( ImpersonationLevel ) );
}
/******************************************************************************
* ImpersonateLoggedOnUser [ADVAPI32.@]
*/
BOOL WINAPI ImpersonateLoggedOnUser(HANDLE hToken)
{
DWORD size;
NTSTATUS Status;
HANDLE ImpersonationToken;
TOKEN_TYPE Type;
static BOOL warn = TRUE;
if (warn)
{
FIXME( "(%p)\n", hToken );
warn = FALSE;
}
if (!GetTokenInformation( hToken, TokenType, &Type,
sizeof(TOKEN_TYPE), &size ))
return FALSE;
if (Type == TokenPrimary)
{
OBJECT_ATTRIBUTES ObjectAttributes;
InitializeObjectAttributes( &ObjectAttributes, NULL, 0, NULL, NULL );
Status = NtDuplicateToken( hToken,
TOKEN_IMPERSONATE | TOKEN_QUERY,
&ObjectAttributes,
SecurityImpersonation,
TokenImpersonation,
&ImpersonationToken );
if (Status != STATUS_SUCCESS)
{
ERR( "NtDuplicateToken failed with error 0x%08x\n", Status );
SetLastError( RtlNtStatusToDosError( Status ) );
return FALSE;
}
}
else
ImpersonationToken = hToken;
Status = NtSetInformationThread( GetCurrentThread(),
ThreadImpersonationToken,
&ImpersonationToken,
sizeof(ImpersonationToken) );
if (Type == TokenPrimary)
NtClose( ImpersonationToken );
if (Status != STATUS_SUCCESS)
{
ERR( "NtSetInformationThread failed with error 0x%08x\n", Status );
SetLastError( RtlNtStatusToDosError( Status ) );
return FALSE;
}
return TRUE;
}
/******************************************************************************
* ImpersonateAnonymousToken [ADVAPI32.@]
*/
BOOL WINAPI ImpersonateAnonymousToken( HANDLE thread )
{
TRACE("(%p)\n", thread);
return set_ntstatus( NtImpersonateAnonymousToken( thread ) );
}
/******************************************************************************
* AccessCheck [ADVAPI32.@]
*/
@ -2890,22 +2377,6 @@ BOOL WINAPI LookupAccountNameW( LPCWSTR lpSystemName, LPCWSTR lpAccountName, PSI
return FALSE;
}
/******************************************************************************
* PrivilegeCheck [ADVAPI32.@]
*/
BOOL WINAPI PrivilegeCheck( HANDLE ClientToken, PPRIVILEGE_SET RequiredPrivileges, LPBOOL pfResult)
{
BOOL ret;
BOOLEAN Result;
TRACE("%p %p %p\n", ClientToken, RequiredPrivileges, pfResult);
ret = set_ntstatus (NtPrivilegeCheck (ClientToken, RequiredPrivileges, &Result));
if (ret)
*pfResult = Result;
return ret;
}
/******************************************************************************
* AccessCheckAndAuditAlarmA [ADVAPI32.@]
*/
@ -5292,46 +4763,6 @@ BOOL WINAPI CreateProcessWithTokenW(HANDLE token, DWORD logon_flags, LPCWSTR app
current_directory, startup_info, process_information );
}
/******************************************************************************
* DuplicateTokenEx [ADVAPI32.@]
*/
BOOL WINAPI DuplicateTokenEx(
HANDLE ExistingTokenHandle, DWORD dwDesiredAccess,
LPSECURITY_ATTRIBUTES lpTokenAttributes,
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
TOKEN_TYPE TokenType,
PHANDLE DuplicateTokenHandle )
{
OBJECT_ATTRIBUTES ObjectAttributes;
TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", ExistingTokenHandle, dwDesiredAccess,
ImpersonationLevel, TokenType, DuplicateTokenHandle);
InitializeObjectAttributes(
&ObjectAttributes,
NULL,
(lpTokenAttributes && lpTokenAttributes->bInheritHandle) ? OBJ_INHERIT : 0,
NULL,
lpTokenAttributes ? lpTokenAttributes->lpSecurityDescriptor : NULL );
return set_ntstatus( NtDuplicateToken( ExistingTokenHandle,
dwDesiredAccess,
&ObjectAttributes,
ImpersonationLevel,
TokenType,
DuplicateTokenHandle ) );
}
BOOL WINAPI DuplicateToken(
HANDLE ExistingTokenHandle,
SECURITY_IMPERSONATION_LEVEL ImpersonationLevel,
PHANDLE DuplicateTokenHandle )
{
return DuplicateTokenEx( ExistingTokenHandle, TOKEN_IMPERSONATE | TOKEN_QUERY,
NULL, ImpersonationLevel, TokenImpersonation,
DuplicateTokenHandle );
}
/******************************************************************************
* ComputeStringSidSize
*/

View File

@ -1,6 +1,6 @@
MODULE = kernelbase.dll
IMPORTLIB = kernelbase
IMPORTS = uuid advapi32 ntdll winecrt0 kernel32
IMPORTS = uuid ntdll winecrt0 kernel32
EXTRADLLFLAGS = -nodefaultlibs -nostartfiles -mno-cygwin
C_SRCS = \

View File

@ -27,8 +27,8 @@
# @ stub AddScopedPolicyIDAce
@ stdcall AddVectoredContinueHandler(long ptr) kernel32.AddVectoredContinueHandler
@ stdcall AddVectoredExceptionHandler(long ptr) kernel32.AddVectoredExceptionHandler
@ stdcall AdjustTokenGroups(long long ptr long ptr ptr) advapi32.AdjustTokenGroups
@ stdcall AdjustTokenPrivileges(long long ptr long ptr ptr) advapi32.AdjustTokenPrivileges
@ stdcall AdjustTokenGroups(long long ptr long ptr ptr)
@ stdcall AdjustTokenPrivileges(long long ptr long ptr ptr)
@ stdcall AllocConsole() kernel32.AllocConsole
@ stdcall AllocateAndInitializeSid(ptr long long long long long long long long long ptr)
@ stdcall AllocateLocallyUniqueId(ptr)
@ -128,7 +128,7 @@
# @ stub CheckIfStateChangeNotificationExists
@ stdcall CheckRemoteDebuggerPresent(long ptr) kernel32.CheckRemoteDebuggerPresent
# @ stub CheckTokenCapability
@ stdcall CheckTokenMembership(long ptr ptr) advapi32.CheckTokenMembership
@ stdcall CheckTokenMembership(long ptr ptr)
# @ stub CheckTokenMembershipEx
@ stdcall ChrCmpIA(long long)
@ stdcall ChrCmpIW(long long)
@ -213,7 +213,7 @@
@ stdcall CreateProcessW(wstr wstr ptr ptr long long ptr wstr ptr ptr) kernel32.CreateProcessW
@ stdcall CreateRemoteThread(long ptr long ptr long long ptr) kernel32.CreateRemoteThread
@ stdcall CreateRemoteThreadEx(long ptr long ptr ptr long ptr ptr) kernel32.CreateRemoteThreadEx
@ stdcall CreateRestrictedToken(long long long ptr long ptr long ptr ptr) advapi32.CreateRestrictedToken
@ stdcall CreateRestrictedToken(long long long ptr long ptr long ptr ptr)
@ stdcall CreateSemaphoreExW(ptr long long wstr long long) kernel32.CreateSemaphoreExW
@ stdcall CreateSemaphoreW(ptr long long wstr) kernel32.CreateSemaphoreW
# @ stub CreateStateAtom
@ -281,8 +281,8 @@
# @ stub DsWriteNgcKeyW
@ stdcall DuplicateHandle(long long long ptr long long long) kernel32.DuplicateHandle
# @ stub DuplicateStateContainerHandle
@ stdcall DuplicateToken(long long ptr) advapi32.DuplicateToken
@ stdcall DuplicateTokenEx(long long ptr long long ptr) advapi32.DuplicateTokenEx
@ stdcall DuplicateToken(long long ptr)
@ stdcall DuplicateTokenEx(long long ptr long long ptr)
# @ stub EmptyWorkingSet
@ stdcall EncodePointer(ptr) kernel32.EncodePointer
# @ stub EncodeRemotePointer
@ -733,7 +733,7 @@
@ stdcall GetTimeFormatW(long long ptr wstr ptr long) kernel32.GetTimeFormatW
@ stdcall GetTimeZoneInformation(ptr) kernel32.GetTimeZoneInformation
@ stdcall GetTimeZoneInformationForYear(long ptr ptr) kernel32.GetTimeZoneInformationForYear
@ stdcall GetTokenInformation(long long ptr long ptr) advapi32.GetTokenInformation
@ stdcall GetTokenInformation(long long ptr long ptr)
@ stdcall GetTraceEnableFlags(int64) ntdll.EtwGetTraceEnableFlags
@ stdcall GetTraceEnableLevel(int64) ntdll.EtwGetTraceEnableLevel
@ stdcall -ret64 GetTraceLoggerHandle(ptr) ntdll.EtwGetTraceLoggerHandle
@ -789,10 +789,10 @@
@ stdcall IdnToAscii(long wstr long ptr long) kernel32.IdnToAscii
@ stdcall IdnToNameprepUnicode(long wstr long ptr long) kernel32.IdnToNameprepUnicode
@ stdcall IdnToUnicode(long wstr long ptr long) kernel32.IdnToUnicode
@ stdcall ImpersonateAnonymousToken(long) advapi32.ImpersonateAnonymousToken
@ stdcall ImpersonateLoggedOnUser(long) advapi32.ImpersonateLoggedOnUser
@ stdcall ImpersonateNamedPipeClient(long) advapi32.ImpersonateNamedPipeClient
@ stdcall ImpersonateSelf(long) advapi32.ImpersonateSelf
@ stdcall ImpersonateAnonymousToken(long)
@ stdcall ImpersonateLoggedOnUser(long)
@ stdcall ImpersonateNamedPipeClient(long)
@ stdcall ImpersonateSelf(long)
# @ stub IncrementPackageStatusVersion
@ stdcall InitOnceBeginInitialize(ptr long ptr ptr) kernel32.InitOnceBeginInitialize
@ stdcall InitOnceComplete(ptr long ptr) kernel32.InitOnceComplete
@ -873,7 +873,7 @@
@ stdcall IsThreadAFiber() kernel32.IsThreadAFiber
@ stdcall IsThreadpoolTimerSet(ptr) kernel32.IsThreadpoolTimerSet
# @ stub IsTimeZoneRedirectionEnabled
@ stdcall IsTokenRestricted(long) advapi32.IsTokenRestricted
@ stdcall IsTokenRestricted(long)
@ stdcall IsValidAcl(ptr) advapi32.IsValidAcl
@ stdcall IsValidCodePage(long) kernel32.IsValidCodePage
@ stdcall IsValidLanguageGroup(long long) kernel32.IsValidLanguageGroup
@ -992,7 +992,7 @@
# @ stub OpenPackageInfoByFullNameForUser
# @ stub OpenPrivateNamespaceW
@ stdcall OpenProcess(long long long) kernel32.OpenProcess
@ stdcall OpenProcessToken(long long ptr) advapi32.OpenProcessToken
@ stdcall OpenProcessToken(long long ptr)
@ stub OpenRegKey
@ stdcall OpenSemaphoreW(long long wstr) kernel32.OpenSemaphoreW
# @ stub OpenState
@ -1001,7 +1001,7 @@
# @ stub OpenStateExplicitForUserSid
# @ stub OpenStateExplicitForUserSidString
@ stdcall OpenThread(long long long) kernel32.OpenThread
@ stdcall OpenThreadToken(long long long ptr) advapi32.OpenThreadToken
@ stdcall OpenThreadToken(long long long ptr)
@ stdcall OpenWaitableTimerW(long long wstr) kernel32.OpenWaitableTimerW
@ stdcall OutputDebugStringA(str) kernel32.OutputDebugStringA
@ stdcall OutputDebugStringW(wstr) kernel32.OutputDebugStringW
@ -1163,7 +1163,7 @@
@ stdcall PostQueuedCompletionStatus(long long ptr ptr) kernel32.PostQueuedCompletionStatus
# @ stub PrefetchVirtualMemory
@ stub PrivCopyFileExW
@ stdcall PrivilegeCheck(ptr ptr ptr) advapi32.PrivilegeCheck
@ stdcall PrivilegeCheck(ptr ptr ptr)
@ stdcall PrivilegedServiceAuditAlarmW(wstr wstr long ptr long) advapi32.PrivilegedServiceAuditAlarmW
@ stdcall ProcessIdToSessionId(long ptr) kernel32.ProcessIdToSessionId
# @ stub ProductIdFromPackageFamilyName
@ -1349,7 +1349,7 @@
@ stdcall ResolveLocaleName(wstr ptr long) kernel32.ResolveLocaleName
@ stdcall RestoreLastError(long) kernel32.RestoreLastError
@ stdcall ResumeThread(long) kernel32.ResumeThread
@ stdcall RevertToSelf() advapi32.RevertToSelf
@ stdcall RevertToSelf()
# @ stub RsopLoggingEnabledInternal
# @ stub SHCoCreateInstance
@ stdcall SHExpandEnvironmentStringsA(str ptr long) kernel32.ExpandEnvironmentStringsA
@ -1491,7 +1491,7 @@
@ stdcall SetThreadPriorityBoost(long long) kernel32.SetThreadPriorityBoost
# @ stub SetThreadSelectedCpuSets
@ stdcall SetThreadStackGuarantee(ptr) kernel32.SetThreadStackGuarantee
@ stdcall SetThreadToken(ptr ptr) advapi32.SetThreadToken
@ stdcall SetThreadToken(ptr ptr)
@ stdcall SetThreadUILanguage(long) kernel32.SetThreadUILanguage
@ stub SetThreadpoolStackInformation
@ stdcall SetThreadpoolThreadMaximum(ptr long) kernel32.SetThreadpoolThreadMaximum
@ -1501,7 +1501,7 @@
@ stdcall SetThreadpoolWait(ptr long ptr) kernel32.SetThreadpoolWait
# @ stub SetThreadpoolWaitEx
@ stdcall SetTimeZoneInformation(ptr) kernel32.SetTimeZoneInformation
@ stdcall SetTokenInformation(long long ptr long) advapi32.SetTokenInformation
@ stdcall SetTokenInformation(long long ptr long)
@ stdcall SetUnhandledExceptionFilter(ptr) kernel32.SetUnhandledExceptionFilter
@ stdcall SetUserGeoID(long) kernel32.SetUserGeoID
@ stdcall SetWaitableTimer(long ptr long ptr ptr long) kernel32.SetWaitableTimer

View File

@ -443,3 +443,355 @@ BOOL WINAPI IsWellKnownSid( PSID sid, WELL_KNOWN_SID_TYPE type )
return FALSE;
}
/******************************************************************************
* Token functions
******************************************************************************/
/******************************************************************************
* AdjustTokenGroups (kernelbase.@)
*/
BOOL WINAPI AdjustTokenGroups( HANDLE token, BOOL reset, PTOKEN_GROUPS new,
DWORD len, PTOKEN_GROUPS prev, PDWORD ret_len )
{
return set_ntstatus( NtAdjustGroupsToken( token, reset, new, len, prev, ret_len ));
}
/******************************************************************************
* AdjustTokenPrivileges (kernelbase.@)
*/
BOOL WINAPI AdjustTokenPrivileges( HANDLE token, BOOL disable, PTOKEN_PRIVILEGES new, DWORD len,
PTOKEN_PRIVILEGES prev, PDWORD ret_len )
{
NTSTATUS status;
TRACE("(%p %d %p %d %p %p)\n", token, disable, new, len, prev, ret_len );
status = NtAdjustPrivilegesToken( token, disable, new, len, prev, ret_len );
SetLastError( RtlNtStatusToDosError( status ));
return (status == STATUS_SUCCESS) || (status == STATUS_NOT_ALL_ASSIGNED);
}
/******************************************************************************
* CheckTokenMembership (kernelbase.@)
*/
BOOL WINAPI CheckTokenMembership( HANDLE token, PSID sid_to_check, PBOOL is_member )
{
PTOKEN_GROUPS token_groups = NULL;
HANDLE thread_token = NULL;
DWORD size, i;
BOOL ret;
TRACE("(%p %s %p)\n", token, debugstr_sid(sid_to_check), is_member);
*is_member = FALSE;
if (!token)
{
if (!OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, TRUE, &thread_token))
{
HANDLE process_token;
ret = OpenProcessToken(GetCurrentProcess(), TOKEN_DUPLICATE, &process_token);
if (!ret)
goto exit;
ret = DuplicateTokenEx(process_token, TOKEN_QUERY, NULL, SecurityImpersonation,
TokenImpersonation, &thread_token);
CloseHandle(process_token);
if (!ret)
goto exit;
}
token = thread_token;
}
else
{
TOKEN_TYPE type;
ret = GetTokenInformation(token, TokenType, &type, sizeof(TOKEN_TYPE), &size);
if (!ret) goto exit;
if (type == TokenPrimary)
{
SetLastError(ERROR_NO_IMPERSONATION_TOKEN);
return FALSE;
}
}
ret = GetTokenInformation(token, TokenGroups, NULL, 0, &size);
if (!ret && GetLastError() != ERROR_INSUFFICIENT_BUFFER)
goto exit;
token_groups = heap_alloc(size);
if (!token_groups)
{
ret = FALSE;
goto exit;
}
ret = GetTokenInformation(token, TokenGroups, token_groups, size, &size);
if (!ret)
goto exit;
for (i = 0; i < token_groups->GroupCount; i++)
{
TRACE("Groups[%d]: {0x%x, %s}\n", i,
token_groups->Groups[i].Attributes,
debugstr_sid(token_groups->Groups[i].Sid));
if ((token_groups->Groups[i].Attributes & SE_GROUP_ENABLED) &&
EqualSid(sid_to_check, token_groups->Groups[i].Sid))
{
*is_member = TRUE;
TRACE("sid enabled and found in token\n");
break;
}
}
exit:
heap_free(token_groups);
if (thread_token != NULL) CloseHandle(thread_token);
return ret;
}
/*************************************************************************
* CreateRestrictedToken (kernelbase.@)
*/
BOOL WINAPI CreateRestrictedToken( HANDLE token, DWORD flags,
DWORD disable_count, PSID_AND_ATTRIBUTES disable_sids,
DWORD delete_count, PLUID_AND_ATTRIBUTES delete_privs,
DWORD restrict_count, PSID_AND_ATTRIBUTES restrict_sids, PHANDLE ret )
{
TOKEN_TYPE type;
SECURITY_IMPERSONATION_LEVEL level = SecurityAnonymous;
DWORD size;
FIXME("(%p, 0x%x, %u, %p, %u, %p, %u, %p, %p): stub\n",
token, flags, disable_count, disable_sids, delete_count, delete_privs,
restrict_count, restrict_sids, ret );
size = sizeof(type);
if (!GetTokenInformation( token, TokenType, &type, size, &size )) return FALSE;
if (type == TokenImpersonation)
{
size = sizeof(level);
if (!GetTokenInformation( token, TokenImpersonationLevel, &level, size, &size ))
return FALSE;
}
return DuplicateTokenEx( token, MAXIMUM_ALLOWED, NULL, level, type, ret );
}
/******************************************************************************
* DuplicateToken (kernelbase.@)
*/
BOOL WINAPI DuplicateToken( HANDLE token, SECURITY_IMPERSONATION_LEVEL level, PHANDLE ret )
{
return DuplicateTokenEx( token, TOKEN_IMPERSONATE|TOKEN_QUERY, NULL, level, TokenImpersonation, ret );
}
/******************************************************************************
* DuplicateTokenEx (kernelbase.@)
*/
BOOL WINAPI DuplicateTokenEx( HANDLE token, DWORD access, LPSECURITY_ATTRIBUTES sa,
SECURITY_IMPERSONATION_LEVEL level, TOKEN_TYPE type, PHANDLE ret )
{
OBJECT_ATTRIBUTES attr;
TRACE("%p 0x%08x 0x%08x 0x%08x %p\n", token, access, level, type, ret );
InitializeObjectAttributes( &attr, NULL, (sa && sa->bInheritHandle) ? OBJ_INHERIT : 0,
NULL, sa ? sa->lpSecurityDescriptor : NULL );
return set_ntstatus( NtDuplicateToken( token, access, &attr, level, type, ret ));
}
/******************************************************************************
* GetTokenInformation (kernelbase.@)
*/
BOOL WINAPI GetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS class,
LPVOID info, DWORD len, LPDWORD retlen )
{
TRACE("(%p, %s, %p, %d, %p):\n",
token,
(class == TokenUser) ? "TokenUser" :
(class == TokenGroups) ? "TokenGroups" :
(class == TokenPrivileges) ? "TokenPrivileges" :
(class == TokenOwner) ? "TokenOwner" :
(class == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
(class == TokenDefaultDacl) ? "TokenDefaultDacl" :
(class == TokenSource) ? "TokenSource" :
(class == TokenType) ? "TokenType" :
(class == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
(class == TokenStatistics) ? "TokenStatistics" :
(class == TokenRestrictedSids) ? "TokenRestrictedSids" :
(class == TokenSessionId) ? "TokenSessionId" :
(class == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
(class == TokenSessionReference) ? "TokenSessionReference" :
(class == TokenSandBoxInert) ? "TokenSandBoxInert" :
"Unknown",
info, len, retlen);
return set_ntstatus( NtQueryInformationToken( token, class, info, len, retlen ));
}
/******************************************************************************
* ImpersonateAnonymousToken (kernelbase.@)
*/
BOOL WINAPI ImpersonateAnonymousToken( HANDLE thread )
{
TRACE("(%p)\n", thread);
return set_ntstatus( NtImpersonateAnonymousToken( thread ) );
}
/******************************************************************************
* ImpersonateLoggedOnUser (kernelbase.@)
*/
BOOL WINAPI ImpersonateLoggedOnUser( HANDLE token )
{
DWORD size;
BOOL ret;
HANDLE dup;
TOKEN_TYPE type;
static BOOL warn = TRUE;
if (warn)
{
FIXME( "(%p)\n", token );
warn = FALSE;
}
if (!GetTokenInformation( token, TokenType, &type, sizeof(type), &size )) return FALSE;
if (type == TokenPrimary)
{
if (!DuplicateToken( token, SecurityImpersonation, &dup )) return FALSE;
ret = SetThreadToken( NULL, dup );
NtClose( dup );
}
else ret = SetThreadToken( NULL, token );
return ret;
}
/******************************************************************************
* ImpersonateNamedPipeClient (kernelbase.@)
*/
BOOL WINAPI ImpersonateNamedPipeClient( HANDLE pipe )
{
IO_STATUS_BLOCK io_block;
return set_ntstatus( NtFsControlFile( pipe, NULL, NULL, NULL, &io_block,
FSCTL_PIPE_IMPERSONATE, NULL, 0, NULL, 0 ));
}
/******************************************************************************
* ImpersonateSelf (kernelbase.@)
*/
BOOL WINAPI ImpersonateSelf( SECURITY_IMPERSONATION_LEVEL level )
{
return set_ntstatus( RtlImpersonateSelf( level ) );
}
/******************************************************************************
* IsTokenRestricted (kernelbase.@)
*/
BOOL WINAPI IsTokenRestricted( HANDLE token )
{
TOKEN_GROUPS *groups;
DWORD size;
NTSTATUS status;
BOOL restricted;
TRACE("(%p)\n", token);
status = NtQueryInformationToken(token, TokenRestrictedSids, NULL, 0, &size);
if (status != STATUS_BUFFER_TOO_SMALL) return set_ntstatus(status);
groups = heap_alloc(size);
if (!groups)
{
SetLastError(ERROR_OUTOFMEMORY);
return FALSE;
}
status = NtQueryInformationToken(token, TokenRestrictedSids, groups, size, &size);
if (status != STATUS_SUCCESS)
{
heap_free(groups);
return set_ntstatus(status);
}
restricted = groups->GroupCount > 0;
heap_free(groups);
return restricted;
}
/******************************************************************************
* OpenProcessToken (kernelbase.@)
*/
BOOL WINAPI OpenProcessToken( HANDLE process, DWORD access, HANDLE *handle )
{
return set_ntstatus( NtOpenProcessToken( process, access, handle ));
}
/******************************************************************************
* OpenThreadToken (kernelbase.@)
*/
BOOL WINAPI OpenThreadToken( HANDLE thread, DWORD access, BOOL self, HANDLE *handle )
{
return set_ntstatus( NtOpenThreadToken( thread, access, self, handle ));
}
/******************************************************************************
* PrivilegeCheck (kernelbase.@)
*/
BOOL WINAPI PrivilegeCheck( HANDLE token, PPRIVILEGE_SET privs, LPBOOL result )
{
BOOLEAN res;
BOOL ret = set_ntstatus( NtPrivilegeCheck( token, privs, &res ));
if (ret) *result = res;
return ret;
}
/******************************************************************************
* RevertToSelf (kernelbase.@)
*/
BOOL WINAPI RevertToSelf(void)
{
return SetThreadToken( NULL, 0 );
}
/*************************************************************************
* SetThreadToken (kernelbase.@)
*/
BOOL WINAPI SetThreadToken( PHANDLE thread, HANDLE token )
{
return set_ntstatus( NtSetInformationThread( thread ? *thread : GetCurrentThread(),
ThreadImpersonationToken, &token, sizeof(token) ));
}
/******************************************************************************
* SetTokenInformation (kernelbase.@)
*/
BOOL WINAPI SetTokenInformation( HANDLE token, TOKEN_INFORMATION_CLASS class, LPVOID info, DWORD len )
{
TRACE("(%p, %s, %p, %d)\n",
token,
(class == TokenUser) ? "TokenUser" :
(class == TokenGroups) ? "TokenGroups" :
(class == TokenPrivileges) ? "TokenPrivileges" :
(class == TokenOwner) ? "TokenOwner" :
(class == TokenPrimaryGroup) ? "TokenPrimaryGroup" :
(class == TokenDefaultDacl) ? "TokenDefaultDacl" :
(class == TokenSource) ? "TokenSource" :
(class == TokenType) ? "TokenType" :
(class == TokenImpersonationLevel) ? "TokenImpersonationLevel" :
(class == TokenStatistics) ? "TokenStatistics" :
(class == TokenRestrictedSids) ? "TokenRestrictedSids" :
(class == TokenSessionId) ? "TokenSessionId" :
(class == TokenGroupsAndPrivileges) ? "TokenGroupsAndPrivileges" :
(class == TokenSessionReference) ? "TokenSessionReference" :
(class == TokenSandBoxInert) ? "TokenSandBoxInert" :
"Unknown",
info, len);
return set_ntstatus( NtSetInformationToken( token, class, info, len ));
}