Platform SDK: Access Control

Controlling Child Object Creation

You can use the DACL of a container object to control who is allowed to create child objects within the container. This can be important because the creator of an object is typically assigned as the object's owner, and an object's owner can control access to the object.

The various types of container objects have specific access rights that control the ability to create child objects. For example, a thread must have KEY_CREATE_SUB_KEY access to a registry key in order to create a subkey under the key. The DACL of a registry key can contain ACEs that allow or deny this access right. Similarly, the NTFS file system supports the FILE_ADD_FILE and FILE_ADD_SUBDIRECTORY access rights for controlling the ability to create files or directories in a directory.

Windows 2000: The ADS_RIGHT_DS_CREATE_CHILD access right controls the creation of child objects in a directory service (DS) object. However, DS objects can contain different types of objects, so the system supports a finer granularity of control. You can use object-specific ACEs to allow or deny the right to create a specified type of child object. You can allow a user to create one type of child object while preventing the user from creating other types of child objects.

The following code fragment uses the SetEntriesInAcl function to add an object-specific ACE to an ACL. The ACE grants permission to create a specified type of child object. The grfAccessPermissions member of the EXPLICIT_ACCESS structure is set to ADS_RIGHT_DS_CREATE_CHILD to indicate the ACE controls child object creation. The ObjectFlags member of the OBJECTS_AND_SID structure is set to OBJECT_TYPE_PRESENT to indicate that the ObjectType member contains a valid GUID. The GUID identifies a type of child object whose creation is being controlled.

DWORD dwRes;
PACL pOldDACL;
PACL pNewDACL = NULL;
GUID guidChildObjectType;   // GUID of object to control creation of
PSID pTrusteeSID;           // trustee for new ACE
EXPLICIT_ACCESS ea;
OBJECTS_AND_SID ObjectsAndSID;

// Initialize an OBJECTS_AND_SID structure with object type GUIDs and 
// the SID of the trustee for the new ACE. 

ZeroMemory(&ObjectsAndSID, sizeof(OBJECTS_AND_SID));
ObjectsAndSID.ObjectFlags = OBJECT_TYPE_PRESENT;
ObjectsAndSID.ObjectType = guidChildObjectType;
ObjectsAndSID.InheritedObjectType  = GUID_NULL;
ObjectsAndSID.pSID = pTrusteeSID;

// Initialize an EXPLICIT_ACCESS structure for the new ACE. 

ZeroMemory(&ea, sizeof(EXPLICIT_ACCESS));
ea.grfAccessPermissions = ADS_RIGHT_DS_CREATE_CHILD;
ea.grfAccessMode = GRANT_ACCESS;
ea.grfInheritance= NO_INHERITANCE;
ea.Trustee.TrusteeForm = TRUSTEE_IS_OBJECTS_AND_SID;
ea.Trustee.ptstrName = (LPTSTR) &ObjectsAndSID;

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

dwRes = SetEntriesInAcl(1, &ea, pOldDACL, &pNewDACL);