Platform SDK: Access Control

Modifying an Object's ACLs

This example adds an ACE to an object's DACL. The sample code uses the GetSecurityInfo function to get the existing DACL. Then it fills an EXPLICIT_ACCESS structure with information about an ACE and uses the SetEntriesInAcl function to merge the new ACE with any existing ACEs in the DACL. Finally, the example calls the SetSecurityInfo function to attach the new DACL to the object's security descriptor.

The ACCESS_MODE parameter determines the type of new ACE and also how the new ACE is combined with any existing ACEs for the specified trustee.

You can use similar code to work with a SACL. Specify SACL_SECURITY_INFORMATION in the GetSecurityInfo and SetSecurityInfo functions to get and set the object's SACL. Use the SET_AUDIT_SUCCESS, SET_AUDIT_FAILURE, and REVOKE_ACCESS flags in the AccessMode parameter.

Windows 2000: You can use this code to add an object-specific ACE to the DACL of a directory service object. To specify the GUIDs in an object-specific ACE, set the TrusteeForm parameter to TRUSTEE_IS_OBJECTS_AND_NAME or TRUSTEE_IS_OBJECTS_AND_SID and set the pszTrustee parameter to be a pointer to an OBJECTS_AND_NAME or OBJECTS_AND_SID structure.

DWORD AddAceToObjectsSecurityDescriptor (
    HANDLE hObject,             // handle to object
    SE_OBJECT_TYPE ObjectType,  // type of object
    LPTSTR pszTrustee,          // trustee for new ACE
    TRUSTEE_FORM TrusteeForm,   // format of TRUSTEE structure
    DWORD dwAccessRights,       // access mask for new ACE
    ACCESS_MODE AccessMode,     // type of ACE
    DWORD dwInheritance         // inheritance flags for new ACE
) 
{
DWORD dwRes;
PACL pOldDACL = NULL, pNewDACL = NULL;
PSECURITY_DESCRIPTOR pSD = NULL;
EXPLICIT_ACCESS ea;

if (NULL == hObject) 
    return ERROR_INVALID_PARAMETER;

// Get a pointer to the existing DACL.

dwRes = GetSecurityInfo(hObject, ObjectType, 
      DACL_SECURITY_INFORMATION,
      NULL, NULL, &pOldDACL, NULL, &pSD);
if (ERROR_SUCCESS != dwRes) {
    printf( "GetSecurityInfo Error %u\n", dwRes );
    goto Cleanup; 
}  

// Initialize an EXPLICIT_ACCESS structure for the new ACE. 

ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = dwAccessRights;
ea.grfAccessMode = AccessMode;
ea.grfInheritance= dwInheritance;
ea.Trustee.TrusteeForm = TrusteeForm;
ea.Trustee.ptstrName = pszTrustee;

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

dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
if (ERROR_SUCCESS != dwRes)  {
    printf( "SetEntriesInAcl Error %u\n", dwRes );
    goto Cleanup; 
}  

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

dwRes = SetSecurityInfo(hObject, ObjectType, 
      DACL_SECURITY_INFORMATION,
      NULL, NULL, pNewDACL, NULL);
if (ERROR_SUCCESS != dwRes)  {
    printf( "SetSecurityInfo Error %u\n", dwRes );
    goto Cleanup; 
}  

Cleanup:

    if(pSD != NULL) 
        LocalFree((HLOCAL) pSD); 
    if(pNewDACL != NULL) 
        LocalFree((HLOCAL) pNewDACL); 

    return dwRes;
}