You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
691 lines
19 KiB
691 lines
19 KiB
/*++
|
|
|
|
Copyright (c) Microsoft Corporation
|
|
|
|
Module Name:
|
|
|
|
wssid.cpp
|
|
|
|
Abstract:
|
|
|
|
This file gets the security identifier (SID) for respective user name and
|
|
groups in the current access token on a local system or a remote system.
|
|
|
|
Authors:
|
|
|
|
Christophe Robert
|
|
|
|
Revision History:
|
|
|
|
02-July-2001 : Updated by Wipro Technologies.
|
|
|
|
--*/
|
|
|
|
//common header files needed for this file
|
|
#include "pch.h"
|
|
#include "CommonHeaderFiles.h"
|
|
|
|
|
|
WsSid::WsSid ( VOID )
|
|
/*++
|
|
Routine Description:
|
|
This function intializes the members of WsSid class.
|
|
|
|
Arguments:
|
|
None
|
|
Return Value:
|
|
None
|
|
--*/
|
|
{
|
|
// initializing member variables
|
|
pSid = NULL ;
|
|
bToBeFreed = FALSE ;
|
|
}
|
|
|
|
|
|
|
|
WsSid::~WsSid ( VOID )
|
|
/*++
|
|
Routine Description:
|
|
This function deallocates the members of WsSid class.
|
|
|
|
Arguments:
|
|
None
|
|
Return Value:
|
|
None
|
|
--*/
|
|
{
|
|
|
|
// release memory
|
|
if ( bToBeFreed && pSid ){
|
|
FreeMemory ( (LPVOID *) &pSid ) ;
|
|
}
|
|
}
|
|
|
|
|
|
DWORD
|
|
WsSid::DisplayAccountName (
|
|
IN DWORD dwFormatType ,
|
|
IN DWORD dwNameFormat
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This function displays the user name and SID.
|
|
|
|
Arguments:
|
|
[IN] DWORD dwFormatType : Format type i.,e LIST, CSV or TABLE
|
|
[IN] DWORD dwNameFormat : Name Format either UPN or FQDN
|
|
|
|
Return Value:
|
|
EXIT_SUCCESS : On success
|
|
EXIT_FAILURE : On failure
|
|
--*/
|
|
{
|
|
|
|
// sub-local variables
|
|
WCHAR wszUserName[ MAX_STRING_LENGTH ];
|
|
WCHAR wszSid [ MAX_STRING_LENGTH ];
|
|
WCHAR wszGroup[MAX_STRING_LENGTH];
|
|
DWORD dwErr = 0 ;
|
|
DWORD dwColCount = 0 ;
|
|
DWORD dw = 0 ;
|
|
DWORD dwCount = 0 ;
|
|
DWORD dwArrSize = 0 ;
|
|
DWORD dwSize = 0;
|
|
DWORD dwUserLen = 0;
|
|
DWORD dwSidLen = 0;
|
|
DWORD dwUserColLen = 0;
|
|
DWORD dwSidColLen = 0;
|
|
DWORD dwSidUse = 0;
|
|
LPWSTR wszBuffer = NULL;
|
|
|
|
//initialize memory
|
|
SecureZeroMemory ( wszUserName, SIZE_OF_ARRAY(wszUserName) );
|
|
SecureZeroMemory ( wszSid, SIZE_OF_ARRAY(wszSid) );
|
|
SecureZeroMemory ( wszGroup, SIZE_OF_ARRAY(wszGroup) );
|
|
|
|
// create a dynamic array
|
|
TARRAY pColData = CreateDynamicArray();
|
|
if ( NULL == pColData)
|
|
{
|
|
// set last error and display an error message with respect
|
|
//to ERROR_NOT_ENOUGH_MEMORY
|
|
SetLastError((DWORD)E_OUTOFMEMORY);
|
|
SaveLastError();
|
|
ShowLastErrorEx (stderr, SLE_TYPE_ERROR | SLE_SYSTEM);
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
dwSize = SIZE_OF_ARRAY(wszGroup);
|
|
|
|
//if /FQDN is specified
|
|
if ( (FQDN_FORMAT == dwNameFormat) )
|
|
{
|
|
//Get the username in FQDN format
|
|
if (GetUserNameEx ( NameFullyQualifiedDN, wszGroup, &dwSize) == FALSE )
|
|
{
|
|
// GetUserNameEx() got failed due to small size specified for username.
|
|
// allocate the actual size (dwSize) of username and call the same
|
|
// function again...
|
|
wszBuffer = (LPWSTR) AllocateMemory(dwSize * sizeof(WCHAR));
|
|
if ( NULL == wszBuffer )
|
|
{
|
|
// display system error message with respect to GetLastError()
|
|
ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
if (GetUserNameEx ( NameFullyQualifiedDN, wszBuffer, &dwSize) == FALSE )
|
|
{
|
|
// display an error messaga as.. unable to get FQDN name
|
|
// as logged-on user is not a domain user
|
|
ShowMessage ( stderr, GetResString (IDS_ERROR_FQDN) );
|
|
DestroyDynamicArray(&pColData);
|
|
FreeMemory ((LPVOID*) &wszBuffer);
|
|
return EXIT_FAILURE ;
|
|
}
|
|
|
|
ShowMessage ( stdout, _X(wszBuffer));
|
|
ShowMessage ( stdout, L"\n");
|
|
FreeMemory ((LPVOID*) &wszBuffer);
|
|
DestroyDynamicArray(&pColData);
|
|
// return success
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
ShowMessage ( stdout, _X(wszGroup));
|
|
ShowMessage ( stdout, L"\n");
|
|
DestroyDynamicArray(&pColData);
|
|
// return success
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
else if ( (UPN_FORMAT == dwNameFormat ) )
|
|
{
|
|
// get the user name in UPN format
|
|
if ( GetUserNameEx ( NameUserPrincipal, wszGroup, &dwSize) == FALSE )
|
|
{
|
|
// GetUserNameEx() got failed due to small size specified for username
|
|
// allocate the actual size(dwSize) of username and call the same
|
|
// function again...
|
|
wszBuffer = (LPWSTR) AllocateMemory(dwSize * sizeof(WCHAR));
|
|
if ( NULL == wszBuffer )
|
|
{
|
|
// display system error message with respect to GetLastError()
|
|
ShowLastErrorEx ( stderr, SLE_TYPE_ERROR | SLE_SYSTEM );
|
|
return EXIT_FAILURE;
|
|
}
|
|
|
|
// get the user name in UPN format
|
|
if ( GetUserNameEx ( NameUserPrincipal, wszBuffer, &dwSize) == FALSE )
|
|
{
|
|
// display an error messaga as.. unable to get UPN name
|
|
// as logged-on user is not a domain user
|
|
ShowMessage ( stderr, GetResString (IDS_ERROR_UPN) );
|
|
// release memory
|
|
DestroyDynamicArray(&pColData);
|
|
FreeMemory ((LPVOID*) &wszBuffer);
|
|
return EXIT_FAILURE ;
|
|
}
|
|
|
|
// convert UPN name in lower case letters
|
|
CharLower ( wszBuffer );
|
|
|
|
// display UPN name
|
|
ShowMessage ( stdout, _X(wszBuffer) );
|
|
ShowMessage ( stdout, L"\n");
|
|
// release memory
|
|
DestroyDynamicArray(&pColData);
|
|
FreeMemory ((LPVOID*) &wszBuffer);
|
|
//return success
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
// convert UPN name in lower case letters
|
|
CharLower ( wszGroup );
|
|
|
|
// display UPN name
|
|
ShowMessage ( stdout, _X(wszGroup) );
|
|
ShowMessage ( stdout, L"\n");
|
|
|
|
DestroyDynamicArray(&pColData);
|
|
//return success
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
|
|
// get user name
|
|
if ( (dwErr = GetAccountName ( wszUserName, &dwSidUse)) != EXIT_SUCCESS ){
|
|
// display an error message with respect to Win32 error code
|
|
ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_SYSTEM);
|
|
DestroyDynamicArray(&pColData);
|
|
return dwErr ;
|
|
}
|
|
|
|
// convery user name in lower case letters
|
|
CharLower ( wszUserName );
|
|
|
|
// if /USER specified
|
|
if ( USER_ONLY != dwNameFormat)
|
|
{
|
|
// display SID with respect to username
|
|
if ( (dwErr = DisplaySid ( wszSid ) ) != EXIT_SUCCESS ){
|
|
DestroyDynamicArray(&pColData);
|
|
return dwErr ;
|
|
}
|
|
}
|
|
|
|
// get the length of user name
|
|
dwUserLen = StringLengthInBytes (wszUserName);
|
|
// get the length of SID
|
|
dwSidLen = StringLengthInBytes (wszSid);
|
|
|
|
//
|
|
//To avoid localization problems, get the maximum length of column name and
|
|
// values of respective columns
|
|
//
|
|
|
|
// Get the maximum length of a column name "UserName"
|
|
dwUserColLen = StringLengthInBytes( GetResString(IDS_COL_USERNAME) );
|
|
if ( dwUserColLen > dwUserLen )
|
|
{
|
|
dwUserLen = dwUserColLen;
|
|
}
|
|
|
|
// Get the maximum length of a column name "SID"
|
|
dwSidColLen = StringLengthInBytes( GetResString(IDS_COL_SID) );
|
|
if ( dwSidColLen > dwSidLen )
|
|
{
|
|
dwSidLen = dwSidColLen;
|
|
}
|
|
|
|
// defining verbose columns with the actual size
|
|
TCOLUMNS pVerboseCols[] =
|
|
{
|
|
{L"\0",dwUserLen, SR_TYPE_STRING, COL_FORMAT_STRING, NULL, NULL},
|
|
{L"\0",dwSidLen,SR_TYPE_STRING,COL_FORMAT_STRING,NULL,NULL}
|
|
};
|
|
|
|
// if /USER is specified
|
|
if ( USER_ONLY == dwNameFormat )
|
|
{
|
|
// display the user name
|
|
StringCopy (pVerboseCols[dw].szColumn , GetResString(IDS_COL_USERNAME), MAX_RES_STRING);
|
|
ShowMessage ( stdout, _X(wszUserName) );
|
|
ShowMessage ( stdout, L"\n");
|
|
|
|
// release memory
|
|
DestroyDynamicArray(&pColData);
|
|
|
|
return EXIT_SUCCESS;
|
|
}
|
|
else
|
|
{
|
|
//Load the column names for verbose mode
|
|
for( dwColCount = IDS_COL_USERNAME , dw = 0 ; dwColCount <= IDS_COL_SID;
|
|
dwColCount++, dw++)
|
|
{
|
|
StringCopy(pVerboseCols[dw].szColumn , GetResString(dwColCount), MAX_RES_STRING );
|
|
}
|
|
|
|
// get the number of columns
|
|
dwArrSize = SIZE_OF_ARRAY( pVerboseCols );
|
|
}
|
|
|
|
//Start appending to the 2D array
|
|
DynArrayAppendRow(pColData, dwArrSize);
|
|
|
|
//Insert the user name
|
|
DynArraySetString2(pColData, dwCount, USERNAME_COL_NUMBER, _X(wszUserName), 0);
|
|
|
|
//Insert the SID string
|
|
DynArraySetString2(pColData, dwCount, SID_COL_NUMBER, _X(wszSid), 0);
|
|
|
|
// 1) If the display format is CSV.. then we should not display column headings..
|
|
// 2) If /NH is specified ...then we should not display column headings..
|
|
if ( !(( SR_FORMAT_CSV == dwFormatType ) || ((dwFormatType & SR_HIDECOLUMN) == SR_HIDECOLUMN)))
|
|
{
|
|
// display the headings before displaying the username and SID
|
|
ShowMessage ( stdout, L"\n" );
|
|
ShowMessage ( stdout, GetResString ( IDS_LIST_USER_NAMES ) );
|
|
ShowMessage ( stdout, GetResString ( IDS_DISPLAY_USER_DASH ) );
|
|
}
|
|
|
|
// display the actual values for user name and SID
|
|
ShowResults(dwArrSize, pVerboseCols, dwFormatType, pColData);
|
|
|
|
// release memory
|
|
DestroyDynamicArray(&pColData);
|
|
// return success
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
WsSid::DisplayGroupName ( OUT LPWSTR wszGroupName,
|
|
OUT LPWSTR wszGroupSid,
|
|
IN DWORD *dwSidUseName)
|
|
/*++
|
|
Routine Description:
|
|
This function gets the group name and SID to display.
|
|
|
|
Arguments:
|
|
[OUT] LPWSTR wszGroupName : Stores group name
|
|
[OUT] LPWSTR wszGroupSid : Stores group SID
|
|
[IN] DWORD dwSidUseName : stores Sid use name
|
|
|
|
Return Value:
|
|
EXIT_SUCCESS : On success
|
|
EXIT_FAILURE : On failure
|
|
--*/
|
|
{
|
|
// sub-local variables
|
|
DWORD dwErr = 0 ;
|
|
DWORD dwSidUse = 0;
|
|
|
|
// display the user name
|
|
if ( (dwErr = GetAccountName ( wszGroupName, &dwSidUse) ) != EXIT_SUCCESS ){
|
|
// display an error message with respect to Win32 error code
|
|
ShowLastErrorEx(stderr, SLE_TYPE_ERROR | SLE_SYSTEM);
|
|
return dwErr ;
|
|
}
|
|
|
|
// display SID
|
|
if ( (dwErr = DisplaySid ( wszGroupSid ) ) != EXIT_SUCCESS ){
|
|
return dwErr ;
|
|
}
|
|
|
|
*dwSidUseName = dwSidUse;
|
|
|
|
// return success
|
|
return EXIT_SUCCESS;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WsSid::DisplaySid (
|
|
OUT LPWSTR wszSid
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This function gets the SID .
|
|
|
|
Arguments:
|
|
[OUT] LPWSTR wszSid : Stores SID string
|
|
|
|
Return Value:
|
|
EXIT_SUCCESS : On success
|
|
EXIT_FAILURE : On failure
|
|
--*/
|
|
{
|
|
|
|
// sub-local variable
|
|
DWORD dwErr = 0 ;
|
|
|
|
// Get SID string
|
|
if ( (dwErr = GetSidString (wszSid)) != EXIT_SUCCESS )
|
|
{
|
|
return dwErr ;
|
|
}
|
|
|
|
// return success
|
|
return EXIT_SUCCESS;
|
|
|
|
}
|
|
|
|
|
|
|
|
DWORD
|
|
WsSid::GetAccountName (
|
|
OUT LPWSTR wszAccountName,
|
|
OUT DWORD *dwSidType
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This function gets the account name and SID
|
|
|
|
Arguments:
|
|
[OUT] szAccountName : Stores user name
|
|
[OUT] dwSidType : Stores Sid use name
|
|
|
|
Return Value:
|
|
EXIT_SUCCESS : On success
|
|
EXIT_FAILURE : On failure
|
|
--*/
|
|
{
|
|
|
|
// sub-local variables
|
|
SID_NAME_USE SidUse ;
|
|
|
|
WCHAR wszUserName[ MAX_RES_STRING ];
|
|
WCHAR wszDomainName [ MAX_RES_STRING ];
|
|
DWORD dwUserLen = 0;
|
|
DWORD dwDomainLen = 0;
|
|
BOOL bNotResolved = FALSE;
|
|
|
|
// initialize the variables
|
|
SecureZeroMemory ( wszUserName, SIZE_OF_ARRAY(wszUserName) );
|
|
SecureZeroMemory ( wszDomainName, SIZE_OF_ARRAY(wszDomainName) );
|
|
|
|
// get the length of user name and group name
|
|
dwUserLen = SIZE_OF_ARRAY ( wszUserName );
|
|
dwDomainLen = SIZE_OF_ARRAY ( wszDomainName );
|
|
|
|
// enable debug privileges
|
|
if ( FALSE == EnableDebugPriv() )
|
|
{
|
|
// return WIN32 error code
|
|
return GetLastError () ;
|
|
}
|
|
|
|
// get user name and domain name with respective to SID
|
|
if ( FALSE == LookupAccountSid ( NULL, // Local System
|
|
pSid,
|
|
wszUserName,
|
|
&dwUserLen,
|
|
wszDomainName,
|
|
&dwDomainLen,
|
|
&SidUse ) ){
|
|
if ( 0 == StringLength (wszUserName, 0))
|
|
{
|
|
bNotResolved = TRUE;
|
|
StringCopy ( wszAccountName, L" ", MAX_RES_STRING );
|
|
}
|
|
else if ( ( 0 != StringLength (wszDomainName, 0) ) && ( 0 != StringLength (wszUserName, 0) ) ) {
|
|
// return WIN32 error code
|
|
return GetLastError () ;
|
|
}
|
|
|
|
}
|
|
|
|
if ( FALSE == bNotResolved)
|
|
{
|
|
// check for empty domain name
|
|
if ( 0 != StringLength ( wszDomainName, 0 ) ) {
|
|
StringCopy ( wszAccountName, wszDomainName, MAX_RES_STRING );
|
|
StringConcat ( wszAccountName, SLASH , MAX_RES_STRING);
|
|
StringConcat ( wszAccountName, wszUserName, MAX_RES_STRING );
|
|
}
|
|
else {
|
|
StringCopy ( wszAccountName, wszUserName, MAX_RES_STRING );
|
|
}
|
|
}
|
|
|
|
*dwSidType = (DWORD)SidUse;
|
|
|
|
// return success
|
|
return EXIT_SUCCESS ;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WsSid::GetSidString (
|
|
OUT LPWSTR wszSid
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This function gets the SID string.
|
|
|
|
Arguments:
|
|
[OUT] LPWSTR wszSid : Stores SID string
|
|
|
|
Return Value:
|
|
EXIT_SUCCESS : On success
|
|
EXIT_FAILURE : On failure
|
|
--*/
|
|
{
|
|
|
|
// sub-local variables
|
|
PSID_IDENTIFIER_AUTHORITY Auth ;
|
|
PUCHAR lpNbSubAuth ;
|
|
LPDWORD lpSubAuth = 0 ;
|
|
UCHAR uloop ;
|
|
WCHAR wszTmp[MAX_RES_STRING] ;
|
|
WCHAR wszStr[ MAX_RES_STRING ] ;
|
|
|
|
// initialize the variables
|
|
SecureZeroMemory ( wszTmp, SIZE_OF_ARRAY(wszTmp) );
|
|
SecureZeroMemory ( wszStr, SIZE_OF_ARRAY(wszStr) );
|
|
|
|
//check for empty
|
|
if ( NULL == pSid )
|
|
{
|
|
return EXIT_FAILURE ;
|
|
}
|
|
|
|
//Is it a valid SID
|
|
if ( FALSE == IsValidSid ( pSid ) ) {
|
|
ShowMessage ( stderr, GetResString ( IDS_INVALID_SID ) );
|
|
return EXIT_FAILURE ;
|
|
}
|
|
|
|
//Add the revision
|
|
StringCopy ( wszStr, SID_STRING, MAX_RES_STRING );
|
|
|
|
//Get identifier authority
|
|
Auth = GetSidIdentifierAuthority ( pSid ) ;
|
|
|
|
if ( NULL == Auth )
|
|
{
|
|
// return WIN32 error code
|
|
return GetLastError () ;
|
|
}
|
|
|
|
// format authority value
|
|
if ( (Auth->Value[0] != 0) || (Auth->Value[1] != 0) ) {
|
|
StringCchPrintf ( wszTmp, SIZE_OF_ARRAY(wszTmp), AUTH_FORMAT_STR1 ,
|
|
(ULONG)Auth->Value[0],
|
|
(ULONG)Auth->Value[1],
|
|
(ULONG)Auth->Value[2],
|
|
(ULONG)Auth->Value[3],
|
|
(ULONG)Auth->Value[4],
|
|
(ULONG)Auth->Value[5] );
|
|
}
|
|
else {
|
|
StringCchPrintf ( wszTmp, SIZE_OF_ARRAY(wszTmp), AUTH_FORMAT_STR2 ,
|
|
(ULONG)(Auth->Value[5] ) +
|
|
(ULONG)(Auth->Value[4] << 8) +
|
|
(ULONG)(Auth->Value[3] << 16) +
|
|
(ULONG)(Auth->Value[2] << 24) );
|
|
}
|
|
|
|
StringConcat (wszStr, DASH , SIZE_OF_ARRAY(wszStr));
|
|
StringConcat (wszStr, wszTmp, SIZE_OF_ARRAY(wszStr));
|
|
|
|
//Get sub authorities
|
|
lpNbSubAuth = GetSidSubAuthorityCount ( pSid ) ;
|
|
|
|
if ( NULL == lpNbSubAuth )
|
|
{
|
|
return GetLastError () ;
|
|
}
|
|
|
|
// loop through and get sub authority
|
|
for ( uloop = 0 ; uloop < *lpNbSubAuth ; uloop++ ) {
|
|
lpSubAuth = GetSidSubAuthority ( pSid,(DWORD)uloop ) ;
|
|
if ( NULL == lpSubAuth )
|
|
{
|
|
return GetLastError () ;
|
|
}
|
|
|
|
// convert long integer to a string
|
|
_ultot (*lpSubAuth, wszTmp, BASE_TEN) ;
|
|
StringConcat ( wszStr, DASH, SIZE_OF_ARRAY(wszStr) ) ;
|
|
StringConcat (wszStr, wszTmp, SIZE_OF_ARRAY(wszStr) ) ;
|
|
}
|
|
|
|
StringCopy ( wszSid, wszStr, MAX_RES_STRING );
|
|
|
|
// retunr success
|
|
return EXIT_SUCCESS ;
|
|
}
|
|
|
|
|
|
DWORD
|
|
WsSid::Init (
|
|
OUT PSID pOtherSid
|
|
)
|
|
/*++
|
|
Routine Description:
|
|
This function Initializes the SID
|
|
|
|
Arguments:
|
|
[OUT] PSID pOtherSid : Stores SID string
|
|
|
|
Return Value:
|
|
EXIT_SUCCESS : On success
|
|
EXIT_FAILURE : On failure
|
|
--*/
|
|
{
|
|
|
|
// sub-local variable
|
|
DWORD dwSize ;
|
|
|
|
// get the length of SID
|
|
dwSize = GetLengthSid ( pOtherSid ) ;
|
|
|
|
// allocate the memory with the actual size
|
|
pSid = (PSID) AllocateMemory ( dwSize ) ;
|
|
if ( NULL == pSid )
|
|
{
|
|
// return WIN32 error code
|
|
return GetLastError () ;
|
|
}
|
|
|
|
bToBeFreed = TRUE ;
|
|
|
|
// copy SID
|
|
if ( FALSE == CopySid ( dwSize, pSid, pOtherSid ) ){
|
|
return GetLastError () ;
|
|
}
|
|
|
|
// return success
|
|
return EXIT_SUCCESS ;
|
|
}
|
|
|
|
BOOL
|
|
WsSid::EnableDebugPriv()
|
|
/*++
|
|
Routine Description:
|
|
Enables the debug privliges for the current process so that
|
|
this utility can terminate the processes on local system without any problem
|
|
|
|
Arguments:
|
|
NONE
|
|
|
|
Return Value:
|
|
TRUE upon successfull and FALSE if failed
|
|
--*/
|
|
{
|
|
// local variables
|
|
LUID luidValue;
|
|
BOOL bResult = FALSE;
|
|
HANDLE hToken = NULL;
|
|
TOKEN_PRIVILEGES tkp;
|
|
|
|
// Retrieve a handle of the access token
|
|
bResult = OpenProcessToken( GetCurrentProcess(),
|
|
TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_QUERY, &hToken );
|
|
if ( bResult == FALSE )
|
|
{
|
|
// save the error messaage and return
|
|
SaveLastError();
|
|
return FALSE;
|
|
}
|
|
|
|
// Enable the SE_DEBUG_NAME privilege or disable
|
|
// all privileges, depends on this flag.
|
|
bResult = LookupPrivilegeValue( NULL, SE_DEBUG_NAME, &luidValue );
|
|
if ( bResult == FALSE )
|
|
{
|
|
// save the error messaage and return
|
|
SaveLastError();
|
|
CloseHandle( hToken );
|
|
return FALSE;
|
|
}
|
|
|
|
// prepare the token privileges structure
|
|
tkp.PrivilegeCount = 1;
|
|
tkp.Privileges[ 0 ].Luid = luidValue;
|
|
tkp.Privileges[ 0 ].Attributes = SE_PRIVILEGE_ENABLED;
|
|
|
|
// now enable the debug privileges in the token
|
|
bResult = AdjustTokenPrivileges( hToken, FALSE, &tkp, sizeof( TOKEN_PRIVILEGES ),
|
|
( PTOKEN_PRIVILEGES ) NULL, ( PDWORD ) NULL );
|
|
if ( bResult == FALSE )
|
|
{
|
|
// The return value of AdjustTokenPrivileges be texted
|
|
SaveLastError();
|
|
CloseHandle( hToken );
|
|
return FALSE;
|
|
}
|
|
|
|
// close the opened handle object
|
|
CloseHandle( hToken );
|
|
|
|
// enabled ... inform success
|
|
return TRUE;
|
|
}
|
|
|
|
|