Windows Access Control List (ACL) Example 23

 

 

 

 

Privilege and SACL Program Example

 

In the following example we will try to enable a privilege that needed in order to set the SACL using the same program example. First of all let create the PrivilegeSACLDir directory and verify the Auditing from property page (should be none).

 

Privilege and SACL Program Example: There is no auditing entries (SACL)

 

Then execute the following program which is a modified previously created program.

Create a new empty Win32 console application project. Give a suitable project name and change the project location if needed.

 

Privilege and SACL Program Example: Creating new C++ Win32 console application project

 

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

 

Privilege and SACL Program Example: Adding new  C++ source file

 

Next, add the following source code.

 

// In this program we are going to

// add Allow standard right access and set an ACE for SACL.

// This Win XP machine is logged in by user named Mike spoon

// who is a member of Administrators group...

// To access a SACL using the GetNamedSecurityInfo()

// or SetNamedSecurityInfo() functions, you have to enable

// the SE_SECURITY_NAME privilege

#include <windows.h>

#include <aclapi.h>

#include <stdio.h>

 

//********* Enabling/Disabling the 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 to find %s privilege, error: %u\n, lpszPrivilege, GetLastError());

            return FALSE;

      }

      else

            wprintf(LLookupPrivilegeValue() is OK - Privilege \%s\ was found!\n, lpszPrivilege);

     

      // Set the privilege count

      tp.PrivilegeCount = 1;

      // Assign luid to the first count

      tp.Privileges[0].Luid = luid;

     

      // If TRUE

      if(bEnablePrivilege)

      {

            tp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;

            wprintf(L\%s\ privilege successfully enabled!\n, lpszPrivilege);   

      }

      else

      {

            tp.Privileges[0].Attributes = 0;

            wprintf(L\%s\ privilege successfully disabled!\n, lpszPrivilege);

      }

     

      // Adjust to the new privilege

      if(!AdjustTokenPrivileges(

            hToken,

            FALSE,      // If TRUE, function disables all privileges,

                        // if FALSE the function modifies privileges based on the tp

            &tp,

            sizeof(TOKEN_PRIVILEGES),

            (PTOKEN_PRIVILEGES) NULL,

            (PDWORD) NULL))

      {

            wprintf(LAdjustTokenPrivileges() failed, error: %u\n, GetLastError());

            return FALSE;

      }

      else

      {

            wprintf(LAdjustTokenPrivileges() - Privilege token was adjusted successfully!\n);

      }

     

      return TRUE;

}

 

//************** Clean up routine ***************

void Cleanup(PSECURITY_DESCRIPTOR pSS, PACL pNewSACL)

{

     

      if(pSS != NULL)

            LocalFree((HLOCAL) pSS);

      else

            wprintf(LpSS was freed-up\n);

     

      if(pNewSACL != NULL)

            LocalFree((HLOCAL) pNewSACL);

      else

            wprintf(LpNewSACL was freed-up\n);

}

 

//******** The main() **********

int main(int argc, WCHAR **argv)

{

      // Name of object, here we will add an ACE for a directory

      LPTSTR pszObjName = LC:\\PrivilegeSACLDir;

      // Ttype of object, file or directory, a directory

      SE_OBJECT_TYPE ObjectType = SE_FILE_OBJECT;

      // Access mask for new ACE equal to 0X11000000 - GENERIC_ALL and ACCESS_SYSTEM_SECURITY

      DWORD dwAccessRights = 0X11000000;

      // ACCESS_MODE AccessMode = SET_AUDIT_FAILURE;

      // Type of ACE, set audit for success

      ACCESS_MODE AccessMode = SET_AUDIT_SUCCESS;

      // Inheritance flags for new ACE. The OBJECT_INHERIT_ACE and CONTAINER_INHERIT_ACE flags

      // are not propagated to an inherited ACE.

      DWORD dwInheritance = NO_PROPAGATE_INHERIT_ACE;

      // Format of trustee structure, the trustee is name

      TRUSTEE_FORM TrusteeForm = TRUSTEE_IS_NAME;

      // The needed privilege

      LPCTSTR lpszPrivilege = LSeSecurityPrivilege;

      // The new trustee for the ACE is set to Mike spoon,

      // a normal user of Administrators group

      LPTSTR pszTrustee = LMike spoon;

      // Result

      DWORD dwRes = 0;

      // Existing and new SACL pointers...

      PACL pOldSACL = NULL, pNewSACL = NULL;

      // Security descriptor

      PSECURITY_DESCRIPTOR pSS = NULL;

      // EXPLICIT_ACCESS structure

      EXPLICIT_ACCESS ea;

      // Change this BOOL value to set/unset the SE_PRIVILEGE_ENABLED attribute

      BOOL bEnablePrivilege = TRUE;

      // Handle to the running process that is this (running) program

      HANDLE hToken;

      BOOL bRetVal = FALSE;

 

 

      // Verify the object name validity

      if(pszObjName == NULL)

      {

            wprintf(LThe object name is invalid, error %u\n, GetLastError());

            return ERROR_INVALID_PARAMETER;

      }

      else

            wprintf(LThe object name is valid\n);

     

      //*************** Get the handle to the process ********************

      // 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 1;

      }

      else

            wprintf(LOpenProcessToken() is OK, got the handle!\n);

     

      //******* Enabling privilege ********

      // Call the user defined SetPrivilege() function to enable privilege

      bRetVal = SetPrivilege(hToken, lpszPrivilege, bEnablePrivilege);

      // Verify

      if(!bRetVal)

      {

            wprintf(LFailed to enable the privilege, error %u\n\n, GetLastError());

            return 1;

      }

      else

            wprintf(LPrivilege was successfully enabled!\n\n);

      //******* End enabling privilege ********

     

      // By assuming that we have enabled the required privilege,

      // accomplish our task. Here, get a pointer to the existing SACL

      dwRes = GetNamedSecurityInfo(pszObjName,

            ObjectType,

            SACL_SECURITY_INFORMATION,

            NULL, NULL, NULL,

            &pOldSACL, &pSS);

     

      // Verify

      if(dwRes != ERROR_SUCCESS)

      {

            wprintf(LGetNamedSecurityInfo() failed, error %u\n, dwRes);

            Cleanup(pSS, pNewSACL);

            return 1;

      }

      else

            wprintf(LGetNamedSecurityInfo() is OK!\n);

     

      // Initialize an EXPLICIT_ACCESS structure for the new ACE.

      // For more ACE entries, declare an array of the EXPLICIT_ACCESS structure

      SecureZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));

      ea.grfAccessPermissions = dwAccessRights;

      ea.grfAccessMode = AccessMode;

      ea.grfInheritance= dwInheritance;

      ea.Trustee.TrusteeForm = TrusteeForm;

     

      // Other structure elements that might be needed...

      // ea.Trustee.TrusteeType = TRUSTEE_IS_GROUP;

      // ea.Trustee.TrusteeType = TRUSTEE_IS_USER;

 

      // The trustee is Mike spoon

      ea.Trustee.ptstrName = pszTrustee;

      // Create a new ACL that merges the new ACE into the existing ACL.

      dwRes = SetEntriesInAcl(1, &ea, pOldSACL, &pNewSACL);

      if(dwRes != ERROR_SUCCESS)

      {

            wprintf(LSetEntriesInAcl() failed, error %u\n, dwRes);

            Cleanup(pSS, pNewSACL);

            return 1;

      }

      else

            wprintf(LSetEntriesInAcl() - ACL was successfully merged!\n);

     

      // Attach the new ACL as the object's SACL.

      dwRes = SetNamedSecurityInfo(pszObjName,

            ObjectType,

            SACL_SECURITY_INFORMATION,

            NULL, NULL, NULL,

            pNewSACL);

     

      if(dwRes != ERROR_SUCCESS)

      {

            wprintf(LSetNamedSecurityInfo() failed, error %u\n, dwRes);

            Cleanup(pSS, pNewSACL);

            return 1;

      }

      else

            wprintf(LSetNamedSecurityInfo() - New ACE/SACL was successfully set!\n\n);

     

      // Disable the privilege

      //****************** Disabling privilege *******************

      bEnablePrivilege = FALSE;

      bRetVal = SetPrivilege(hToken, lpszPrivilege, bEnablePrivilege);

      // Verify

      if(!bRetVal)

      {

            wprintf(L\nFailed to disable the privilege, error %u\n, GetLastError());

            return 1;

      }

      else

            wprintf(L\nPrivilege was successfully disabled!\n);

      //****************** End disabling privilege ***************

     

      // Close the process handle by calling the CloseHandle(hToken)

      CloseHandle(hToken);

     

      return 0;

}

 

Build and run the project. The following screenshot is a sample output.

 

Privilege and SACL Program Example: A sample console  output with privilege enabled and disabled

 

Well, it seems that we have enabled the privilege successfully and set the SACL.  Let verify through the PrivilegeSACLDir directory property, the Advanced Security Settings property page.

 

Privilege and SACL Program Example:  With privilege enabled, the SACL can be set (SACL)

 

 

 

< Windows ACL Example 22 | Windows Access Control List (ACL) Main | Win32 Programming | Windows ACL Example 24 >