Windows Access Control List (ACL) Example 22

 

 

 

 

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.

 

Enabling and Disabling Privileges Code Snippet Example: Creating new C++ Console mode application project

 

Then, add the source file and give it a suitable name.

 

Enabling and Disabling Privileges Code Snippet Example: Adding new C++ source file to the existing VC++ project

 

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.

 

Enabling and Disabling Privileges Code Snippet Example: A sample console output

 

 

 

< Windows ACL Example 21 | Windows Access Control List (ACL) Main | Win32 Programming | Windows ACL Example 23 >