Enabling and Disabling Privileges Code Snippet Example
The last program example in the previous Windows User & Groups, we failed to add the SACL to the ACL because we don’t have privilege to do that task. We already demonstrated how to enable a privilege in our earlier program example. Again, in the following program example we will try to enable the required privilege to accomplish our task. Enabling a privilege in an access token allows the process to perform system-level actions that it could not previously. Your application should thoroughly verify that the privilege is appropriate to the type of account, especially for the following powerful privileges:
Privilege constant (String) |
Display name |
SE_ASSIGNPRIMARYTOKEN_NAME (SeAssignPrimaryTokenPrivilege) |
Replace a process level token |
SE_BACKUP_NAME (SeBackupPrivilege) |
Backup files and directories |
SE_DEBUG_NAME (SeDebugPrivilege) |
Debug programs |
SE_INCREASE_QUOTA_NAME (SeIncreaseQuotaPrivilege) |
Adjust memory quotas for a process |
SE_TCB_NAME (SeTchPrivilege) |
Act as part of the operating system |
Table 1 |
Before enabling any of these potentially dangerous privileges, determine that functions or operations in your code actually require the privileges. For example, very few functions in the operating system actually require the SeTchPrivilege. The following example shows how to enable or disable a privilege in an access token. The example calls the LookupPrivilegeValue() function to get the LUID that the local system uses to identify the privilege. Then the example calls the AdjustTokenPrivileges() function, which either enables or disables the privilege that depends on the value of the bEnablePrivilege parameter. The following is a code portion used to enable/disable privilege.
BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable or disable privilege
)
{
TOKEN_PRIVILEGES tp;
// Used by local system to identify the privilege
LUID luid;
if(!LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid)) // receives LUID of privilege
{
wprintf(LLookupPrivilegeValue() failed, error %u\n, GetLastError());
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Luid = luid;
// If TRUE, enable
if(bEnablePrivilege)
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
// else, disable
else
tp.Privileges[0].Attributes = 0;
// Enable the privilege or disable all privileges
if(!AdjustTokenPrivileges(
hToken,
FALSE,
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL))
{
wprintf(LAdjustTokenPrivileges() failed, error %u\n, GetLastError());
return FALSE;
}
return TRUE;
}
The following is a working program example that enables/disables privilege.
Create a new empty Win32 console application project. Give a suitable project name and change the project location if needed.
Then, add the source file and give it a suitable name.
Next, add the following source code.
#include <windows.h>
#include <stdio.h>
// Enable/disable privilege routine
BOOL SetPrivilege(
HANDLE hToken, // access token handle
LPCTSTR lpszPrivilege, // name of privilege to enable/disable
BOOL bEnablePrivilege // to enable (or disable privilege)
)
{
// Token privilege structure
TOKEN_PRIVILEGES tp;
// Used by local system to identify the privilege
LUID luid;
if(!LookupPrivilegeValue(
NULL, // lookup privilege on local system
lpszPrivilege, // privilege to lookup
&luid)) // receives LUID of privilege
{
wprintf(LLookupPrivilegeValue() failed, error: %u\n, GetLastError());
return FALSE;
}
else
wprintf(LLookupPrivilegeValue() - \%s\ found!\n, lpszPrivilege);
// Number of privilege
tp.PrivilegeCount = 1;
// Assign luid to the 1st count
tp.Privileges[0].Luid = luid;
// Enable/disable
if(bEnablePrivilege)
{
// Enable
tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;
wprintf(L\%s\ was enabled!\n, lpszPrivilege);
}
else
{
// Disable
tp.Privileges[0].Attributes = 0;
wprintf(L\%s\ was disabled!\n, lpszPrivilege);
}
// Adjusting the new privilege
if(!AdjustTokenPrivileges(
hToken,
FALSE, // If TRUE, function disables all privileges,
// if FALSE the function modifies privilege based on the tp
&tp,
sizeof(TOKEN_PRIVILEGES),
(PTOKEN_PRIVILEGES) NULL,
(PDWORD) NULL))
{
wprintf(LAdjustTokenPrivileges() failed to adjust the new privilege, error: %u\n, GetLastError());
return FALSE;
}
else
{
wprintf(LAdjustTokenPrivileges() is OK - new privilege was adjusted!\n);
}
return TRUE;
}
int wmain(int argc, WCHAR **argv)
{
// The privilege to be adjusted
LPCTSTR lpszPrivilege = LSeSecurityPrivilege;
// Change this BOOL value to set/unset the SE_PRIVILEGE_ENABLED attribute
// Initially to enable
BOOL bEnablePrivilege = TRUE;
HANDLE hToken;
BOOL bRetVal;
// Open a handle to the access token for the calling process
if(!OpenProcessToken(GetCurrentProcess(), TOKEN_ADJUST_PRIVILEGES, &hToken))
{
wprintf(LOpenProcessToken() failed, error %u\n, GetLastError());
return FALSE;
}
else
wprintf(LOpenProcessToken() is OK, got the handle!\n);
// Call the user defined SetPrivilege() function to
// enable and set the needed privilege
bRetVal = SetPrivilege(hToken, lpszPrivilege, bEnablePrivilege);
if(!bRetVal)
{
wprintf(LFailed to enable privilege, error %u\n, GetLastError());
return FALSE;
}
else
wprintf(LThe privilege was enabled!\n);
//**************************************************
// TODO: Complete your task which need the privilege
wprintf(L\nI am completing my task that need a privilege...\n\n);
//**************************************************
// After we have completed our task, don't forget to disable the privilege
bEnablePrivilege = FALSE;
bRetVal = SetPrivilege(hToken, lpszPrivilege, bEnablePrivilege);
if(!bRetVal)
{
wprintf(LFailed to disable the privilege, error %u\n, GetLastError());
return FALSE;
}
else
wprintf(LThe privilege was disabled!\n);
return 0;
}
Build and run the project. The following screenshot is a sample output.