|
|
// --------------------------------------------------------------------------
// Module Name: TokenInformation.h
//
// Copyright (c) 1999-2000, Microsoft Corporation
//
// Class to get information about either the current thread/process token or
// a specified token.
//
// History: 1999-10-05 vtan created
// 2000-02-01 vtan moved from Neptune to Whistler
// --------------------------------------------------------------------------
#include "StandardHeader.h"
#include "TokenInformation.h"
// --------------------------------------------------------------------------
// CTokenInformation::CTokenInformation
//
// Arguments: hToken = Optional user token to get information on.
//
// Returns: <none>
//
// Purpose: Duplicates the given token if provided. Otherwise the thread
// token is opened or the process token if that doesn't exist.
//
// History: 1999-10-05 vtan created
// --------------------------------------------------------------------------
CTokenInformation::CTokenInformation (HANDLE hToken) : _hToken(hToken), _hTokenToRelease(NULL), _pvGroupBuffer(NULL), _pvPrivilegeBuffer(NULL), _pvUserBuffer(NULL), _pszUserLogonName(NULL), _pszUserDisplayName(NULL)
{ if (hToken == NULL) { if (OpenThreadToken(GetCurrentThread(), TOKEN_QUERY, FALSE, &_hToken) == FALSE) { TBOOL(OpenProcessToken(GetCurrentProcess(), TOKEN_QUERY, &_hToken)); } if (_hToken != NULL) { _hTokenToRelease = _hToken; } } }
// --------------------------------------------------------------------------
// CTokenInformation::~CTokenInformation
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Releases resources used by the object.
//
// History: 1999-10-05 vtan created
// --------------------------------------------------------------------------
CTokenInformation::~CTokenInformation (void)
{ ReleaseMemory(_pszUserLogonName); ReleaseMemory(_pszUserDisplayName); ReleaseMemory(_pvUserBuffer); ReleaseMemory(_pvPrivilegeBuffer); ReleaseMemory(_pvGroupBuffer); ReleaseHandle(_hTokenToRelease); }
// --------------------------------------------------------------------------
// CTokenInformation::GetLogonSID
//
// Arguments: <none>
//
// Returns: PSID
//
// Purpose: Gets token information for the token groups. Walks the groups
// looking for the SID with SE_GROUP_LOGON_ID and returns a
// pointer to this SID. This memory is available for the scope
// of the object.
//
// History: 1999-10-05 vtan created
// --------------------------------------------------------------------------
PSID CTokenInformation::GetLogonSID (void)
{ PSID pSID;
pSID = NULL; if ((_hToken != NULL) && (_pvGroupBuffer == NULL)) { GetTokenGroups(); } if (_pvGroupBuffer != NULL) { ULONG ulIndex, ulLimit; TOKEN_GROUPS *pTG;
pTG = reinterpret_cast<TOKEN_GROUPS*>(_pvGroupBuffer); ulLimit = pTG->GroupCount; for (ulIndex = 0; (pSID == NULL) && (ulIndex < ulLimit); ++ulIndex) { if ((pTG->Groups[ulIndex].Attributes & SE_GROUP_LOGON_ID) != 0) { pSID = pTG->Groups[ulIndex].Sid; } } } return(pSID); }
// --------------------------------------------------------------------------
// CTokenInformation::GetUserSID
//
// Arguments: <none>
//
// Returns: PSID
//
// Purpose: Gets token information for the token user. This returns the
// SID for the user of the token. This memory is available for
// the scope of the object.
//
// History: 1999-10-05 vtan created
// --------------------------------------------------------------------------
PSID CTokenInformation::GetUserSID (void)
{ PSID pSID;
if ((_pvUserBuffer == NULL) && (_hToken != NULL)) { DWORD dwReturnLength;
dwReturnLength = 0; (BOOL)GetTokenInformation(_hToken, TokenUser, NULL, 0, &dwReturnLength); _pvUserBuffer = LocalAlloc(LMEM_FIXED, dwReturnLength); if ((_pvUserBuffer != NULL) && (GetTokenInformation(_hToken, TokenUser, _pvUserBuffer, dwReturnLength, &dwReturnLength) == FALSE)) { ReleaseMemory(_pvUserBuffer); _pvUserBuffer = NULL; } } if (_pvUserBuffer != NULL) { pSID = reinterpret_cast<TOKEN_USER*>(_pvUserBuffer)->User.Sid; } else { pSID = NULL; } return(pSID); }
// --------------------------------------------------------------------------
// CTokenInformation::IsUserTheSystem
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Gets token information for the token user. This returns
// whether the user is the local system.
//
// History: 1999-12-13 vtan created
// --------------------------------------------------------------------------
bool CTokenInformation::IsUserTheSystem (void)
{ static const LUID sLUIDSystem = SYSTEM_LUID;
ULONG ulReturnLength; TOKEN_STATISTICS tokenStatistics;
return((GetTokenInformation(_hToken, TokenStatistics, &tokenStatistics, sizeof(tokenStatistics), &ulReturnLength) != FALSE) && RtlEqualLuid(&tokenStatistics.AuthenticationId, &sLUIDSystem)); }
// --------------------------------------------------------------------------
// CTokenInformation::IsUserAnAdministrator
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Gets token information for the token user. This returns
// whether the user is a member of the local administrator group.
//
// History: 92-05-06 davidc created
// 1999-11-06 vtan stolen
// --------------------------------------------------------------------------
bool CTokenInformation::IsUserAnAdministrator (void)
{ bool fIsAnAdministrator; PSID pAdministratorSID; static SID_IDENTIFIER_AUTHORITY sSystemSidAuthority = SECURITY_NT_AUTHORITY;
fIsAnAdministrator = false;
if (NT_SUCCESS(RtlAllocateAndInitializeSid(&sSystemSidAuthority, 2, SECURITY_BUILTIN_DOMAIN_RID, DOMAIN_ALIAS_RID_ADMINS, 0, 0, 0, 0, 0, 0, &pAdministratorSID))) { BOOL fAdmin = FALSE;
if (CheckTokenMembership(_hToken, pAdministratorSID, &fAdmin)) { fIsAnAdministrator = !!fAdmin; } (void*)RtlFreeSid(pAdministratorSID); } return(fIsAnAdministrator); }
// --------------------------------------------------------------------------
// CTokenInformation::UserHasPrivilege
//
// Arguments: <none>
//
// Returns: bool
//
// Purpose: Gets token information for the token user. This returns
// whether the user is a member of the local administrator group.
//
// History: 2000-04-26 vtan created
// --------------------------------------------------------------------------
bool CTokenInformation::UserHasPrivilege (DWORD dwPrivilege)
{ bool fUserHasPrivilege;
fUserHasPrivilege = false; if ((_hToken != NULL) && (_pvPrivilegeBuffer == NULL)) { GetTokenPrivileges(); } if (_pvPrivilegeBuffer != NULL) { ULONG ulIndex, ulLimit; TOKEN_PRIVILEGES *pTP; LUID luidPrivilege;
luidPrivilege.LowPart = dwPrivilege; luidPrivilege.HighPart = 0; pTP = reinterpret_cast<TOKEN_PRIVILEGES*>(_pvPrivilegeBuffer); ulLimit = pTP->PrivilegeCount; for (ulIndex = 0; !fUserHasPrivilege && (ulIndex < ulLimit); ++ulIndex) { fUserHasPrivilege = (RtlEqualLuid(&pTP->Privileges[ulIndex].Luid, &luidPrivilege) != FALSE); } } return(fUserHasPrivilege); }
// --------------------------------------------------------------------------
// CTokenInformation::GetUserName
//
// Arguments: <none>
//
// Returns: WCHAR
//
// Purpose: Looks up the account name of the implicit token..
//
// History: 2000-08-31 vtan created
// --------------------------------------------------------------------------
const WCHAR* CTokenInformation::GetUserName (void)
{ if (_pszUserLogonName == NULL) { DWORD dwUserNameSize, dwReferencedDomainSize; SID_NAME_USE eUse; WCHAR *pszReferencedDomain;
dwUserNameSize = dwReferencedDomainSize = 0; (BOOL)LookupAccountSid(NULL, GetUserSID(), NULL, &dwUserNameSize, NULL, &dwReferencedDomainSize, &eUse); pszReferencedDomain = static_cast<WCHAR*>(LocalAlloc(LMEM_FIXED, dwReferencedDomainSize * sizeof(WCHAR))); if (pszReferencedDomain != NULL) { _pszUserLogonName = static_cast<WCHAR*>(LocalAlloc(LMEM_FIXED, dwUserNameSize * sizeof(WCHAR))); if (_pszUserLogonName != NULL) { if (LookupAccountSid(NULL, GetUserSID(), _pszUserLogonName, &dwUserNameSize, pszReferencedDomain, &dwReferencedDomainSize, &eUse) == FALSE) { ReleaseMemory(_pszUserLogonName); } } (HLOCAL)LocalFree(pszReferencedDomain); } } return(_pszUserLogonName); }
// --------------------------------------------------------------------------
// CTokenInformation::GetUserDisplayName
//
// Arguments: <none>
//
// Returns: WCHAR
//
// Purpose: Returns the display name of the implicit token.
//
// History: 2000-08-31 vtan created
// --------------------------------------------------------------------------
const WCHAR* CTokenInformation::GetUserDisplayName (void)
{ if (_pszUserDisplayName == NULL) { const WCHAR *pszUserName;
pszUserName = GetUserName(); if (pszUserName != NULL) { USER_INFO_2 *pUserInfo;
if (NERR_Success == NetUserGetInfo(NULL, pszUserName, 2, reinterpret_cast<LPBYTE*>(&pUserInfo))) { const WCHAR *pszUserDisplayName;
if (pUserInfo->usri2_full_name[0] != L'\0') { pszUserDisplayName = pUserInfo->usri2_full_name; } else { pszUserDisplayName = pszUserName; } _pszUserDisplayName = static_cast<WCHAR*>(LocalAlloc(LMEM_FIXED, (lstrlen(pszUserDisplayName) + sizeof('\0')) * sizeof(WCHAR))); if (_pszUserDisplayName != NULL) { lstrcpy(_pszUserDisplayName, pszUserDisplayName); } TW32(NetApiBufferFree(pUserInfo)); } } } return(_pszUserDisplayName); }
// --------------------------------------------------------------------------
// CTokenInformation::LogonUser
//
// Arguments: See the platform SDK under LogonUser.
//
// Returns: DWORD
//
// Purpose: Calls advapi32!LogonUserW with supplied credentials using
// interactive logon type. Returns the error code as a DWORD
// rather than the standard Win32 API method which allows the
// filtering of certain error codes.
//
// History: 2001-03-28 vtan created
// --------------------------------------------------------------------------
DWORD CTokenInformation::LogonUser (const WCHAR *pszUsername, const WCHAR *pszDomain, const WCHAR *pszPassword, HANDLE *phToken)
{ DWORD dwErrorCode;
if (::LogonUserW(const_cast<WCHAR*>(pszUsername), const_cast<WCHAR*>(pszDomain), const_cast<WCHAR*>(pszPassword), LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, phToken) != FALSE) { dwErrorCode = ERROR_SUCCESS; } else { *phToken = NULL; dwErrorCode = GetLastError();
// Ignore ERROR_PASSWORD_MUST_CHANGE and ERROR_PASSWORD_EXPIRED.
if ((dwErrorCode == ERROR_PASSWORD_MUST_CHANGE) || (dwErrorCode == ERROR_PASSWORD_EXPIRED)) { dwErrorCode = ERROR_SUCCESS; } } return(dwErrorCode); }
// --------------------------------------------------------------------------
// CTokenInformation::IsSameUser
//
// Arguments: hToken1 = Token of one user.
// hToken2 = Token of other user.
//
// Returns: bool
//
// Purpose: Compares the user SID of the tokens for a match.
//
// History: 2001-03-28 vtan created
// --------------------------------------------------------------------------
bool CTokenInformation::IsSameUser (HANDLE hToken1, HANDLE hToken2)
{ PSID pSID1; PSID pSID2; CTokenInformation tokenInformation1(hToken1); CTokenInformation tokenInformation2(hToken2);
pSID1 = tokenInformation1.GetUserSID(); pSID2 = tokenInformation2.GetUserSID(); return((pSID1 != NULL) && (pSID2 != NULL) && (EqualSid(pSID1, pSID2) != FALSE)); }
// --------------------------------------------------------------------------
// CTokenInformation::GetTokenGroups
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Gets token information for the token user. This function
// allocates the memory for the token groups. This memory is
// available for the scope of the object.
//
// History: 1999-11-06 vtan created
// --------------------------------------------------------------------------
void CTokenInformation::GetTokenGroups (void)
{ DWORD dwReturnLength;
dwReturnLength = 0; (BOOL)GetTokenInformation(_hToken, TokenGroups, NULL, 0, &dwReturnLength); _pvGroupBuffer = LocalAlloc(LMEM_FIXED, dwReturnLength); if ((_pvGroupBuffer != NULL) && (GetTokenInformation(_hToken, TokenGroups, _pvGroupBuffer, dwReturnLength, &dwReturnLength) == FALSE)) { ReleaseMemory(_pvGroupBuffer); _pvGroupBuffer = NULL; } }
// --------------------------------------------------------------------------
// CTokenInformation::GetTokenPrivileges
//
// Arguments: <none>
//
// Returns: <none>
//
// Purpose: Gets token privileges for the token user. This function
// allocates the memory for the token privileges. This memory is
// available for the scope of the object.
//
// History: 2000-04-26 vtan created
// --------------------------------------------------------------------------
void CTokenInformation::GetTokenPrivileges (void)
{ DWORD dwReturnLength;
dwReturnLength = 0; (BOOL)GetTokenInformation(_hToken, TokenPrivileges, NULL, 0, &dwReturnLength); _pvPrivilegeBuffer = LocalAlloc(LMEM_FIXED, dwReturnLength); if ((_pvPrivilegeBuffer != NULL) && (GetTokenInformation(_hToken, TokenPrivileges, _pvPrivilegeBuffer, dwReturnLength, &dwReturnLength) == FALSE)) { ReleaseMemory(_pvPrivilegeBuffer); _pvPrivilegeBuffer = NULL; } }
|