[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.