Allowing Access Using Windows NT 4.0 Functions

This example adds an access-allowed ACE to the DACL of an object. The example uses the GetNamedSecurityInfo function to get the existing DACL. Then it uses the BuildExplicitAccessWithName and SetEntriesInAcl functions to merge a new ACE with any existing ACEs in the DACL. Finally, the example calls the SetNamedSecurityInfo function to attach the new DACL to the object's security descriptor.

DWORD AddAceToAcl (LPTSTR lpObjectName, SE_OBJECT_TYPE ObjectType) 
{
DWORD dwRes;
PACL pOldDACL, pNewDACL;
PSECURITY_DESCRIPTOR pSD;
EXPLICIT_ACCESS ea;

if (NULL == lpObjectName) 
    return ERROR_INVALID_PARAMETER;

// get a pointer to the existing DACL

dwRes = GetNamedSecurityInfo(lpObjectName, ObjectType, 
      DACL_SECURITY_INFORMATION,  
      NULL, NULL, &pOldDACL, NULL, &pSD);
if (ERROR_SUCCESS != dwRes) 
    return dwRes;

// initialize an EXPLICIT_ACCESS structure to allow access

ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
BuildExplicitAccessWithName(&ea, "duke", GENERIC_READ, 
        SET_ACCESS, NO_INHERITANCE);

// create an new ACL by merging the EXPLICIT_ACCESS structure
// with the existing DACL

dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);
if (ERROR_SUCCESS != dwRes) 
    goto Cleanup;

// attach the new ACL as the object's DACL

dwRes = SetNamedSecurityInfo(lpObjectName, ObjectType, 
      DACL_SECURITY_INFORMATION,  
      NULL, NULL, pNewDACL, NULL);

// free the buffers returned by SetEntriesInAcl 
//   and GetNamedSecurityInfo

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

return dwRes;
}