Modifying an Object's ACLs

[This is preliminary documentation and subject to change.]

The following example adds an access-denied ACE to the DACL of an object. The example uses the GetNamedSecurityInfoEx function to get the access-control information from the existing DACL. Then it initializes an ACTRL_ACCESS_ENTRY structure with information about the access-denied ACE to be added. The SetEntriesInAccessList function merges the new ACE information into the existing access-control information. The example then calls the SetNamedSecurityInfoEx function to set the new access-control information in the object's DACL.

ACTRL_ACCESS_ENTRY      AccessEntry;
PACTRL_ACCESS           pOldAccessList, pNewAccessList;
DWORD                   dwErr;

// Get the current DACL information from the object.

dwRes = GetNamedSecurityInfoEx(
    TEXT("myfile"),    // name of the object
    SE_FILE_OBJECT,    // type of object
    DACL_SECURITY_INFORMATION,   // type of information to set
    NULL,              // provider is Windows NT
    NULL,              // name or GUID of property or property set
    &pOldAccessList,   // receives existing DACL information 
    NULL,              // receives existing SACL information 
    NULL,              // receives name of owner
    NULL);             // receives name of group

// Initialize the access list entry.

ZeroMemory(&AccessEntry, sizeof(ACTRL_ACCESS_ENTRY) );
BuildTrusteeWithName(&(AccessEntry.Trustee), "ludwig");
AccessEntry.Inheritance = NO_INHERITANCE;
AccessEntry.fAccessFlags = ACTRL_ACCESS_DENIED;

// Set provider-independent standard rights.

AccessEntry.Access = ACTRL_READ_CONTROL | ACTRL_SYNCHRONIZE | 
    ACTRL_CHANGE_ACCESS | ACTRL_DELETE; 

// Set provider-independent rights for file objects.

AccessEntry.Access |= ACTRL_FILE_READ | ACTRL_FILE_READ_ATTRIB | 
    ACTRL_FILE_READ_PROP | ACTRL_FILE_WRITE | 
    ACTRL_FILE_APPEND | ACTRL_FILE_WRITE_ATTRIB | 
    ACTRL_FILE_WRITE_PROP;

// Build an access list from the access list entry.

dwErr = SetEntriesInAccessList(
     1,                  // Number of entries in array
     AccessEntry,        // array of entries
     SET_ACCESS,         // replace any existing items
     NULL,               // property name
     pOldAccessList,     // existing access list
     &pNewAccessList);   // new access list

// Set the access-control information in the object's DACL.

dwRes = SetNamedSecurityInfoEx(
    TEXT("myfile"),              // name of the object
    SE_FILE_OBJECT,              // type of object
    DACL_SECURITY_INFORMATION,   // type of information to set
    NULL,                        // name of provider
    pNewAccessList,              // new access list 
    NULL,                        // audit list
    NULL,                        // name of owner
    NULL,                        // name of group
    NULL);                       // pointer to OVERLAPPED structure

// Free the returned buffers.

if (pOldAccessList) 
    LocalFree(pOldAccessList);
if (pNewAccessList) 
    LocalFree(pNewAccessList);
 

You can use similar code to remove all ACEs for a specified trustee. Initialize an ACTRL_ACCESS_ENTRY structure to identify the trustee, then call SetEntriesInAccessList function with the REVOKE_ACCESS flag.

The code to modify an object's SACL is similar except that it uses the SetEntriesInAuditList function and the ACTRL_AUDIT structure.

For securable objects, such as DS objects, you can use similar code to add object-specific ACEs to an object's ACL. To add object-specific ACEs, you need to create an array of ACTRL_ACCESS_ENTRY structures and call SetEntriesInAccessList for each property or property set that needs its own ACEs. For example, you would make one SetEntriesInAccessList call to add ACEs that control access to the object itself, and another call to add ACEs that control access to a property on the object.

Note that the GetSecurityInfoEx, GetNamedSecurityInfoEx, SetSecurityInfoEx, and SetNamedSecurityInfoEx functions allow you to get and set ACL information for a specified type of sub-object. For example, you could call GetSecurityInfoEx to get the ACEs that apply to a specified property on an object, merge in a new ACE for that property, and call SetSecurityInfoEx to attach the modified property-specific ACL information to the object.