Поделиться через


Управление созданием дочерних объектов в C++

DaCL объекта контейнера можно использовать для управления тем, кто может создавать дочерние объекты в контейнере. Это может быть важно, так как создатель объекта обычно назначается владельцем объекта, а владелец объекта может управлять доступом к объекту.

Различные типы объектов контейнера имеют определенные права доступа, которые управляют возможностью создания дочерних объектов. Например, поток должен иметь доступ уровня KEY_CREATE_SUB_KEY к ключу реестра, чтобы создать подраздел в данном ключе. DACL раздела реестра может содержать службы управления доступом, которые разрешают или запрещают доступ. Аналогичным образом NTFS поддерживает FILE_ADD_FILE и FILE_ADD_SUBDIRECTORY права доступа для управления возможностью создания файлов или каталогов в каталоге.

Право доступа ADS_RIGHT_DS_CREATE_CHILD регулирует создание дочерних объектов в объекте службы каталогов (DS). Однако объекты DS могут содержать различные типы объектов, поэтому система поддерживает более подробную детализацию управления. Можно использовать для определённых объектов, чтобы разрешить или запретить право создать определённый тип дочернего объекта. Пользователь может создать один тип дочернего объекта, не позволяя пользователю создавать другие типы дочерних объектов.

В следующем примере используется функция SetEntriesInAcl для добавления ACE, специфичного для конкретного объекта, в ACL. ACE предоставляет разрешение на создание указанного типа дочернего объекта. grfAccessPermissions элемент структуры EXPLICIT_ACCESS установлен в ADS_RIGHT_DS_CREATE_CHILD, чтобы указать, что ACE управляет созданием дочернего объекта. Элемент ObjectsPresent структуры OBJECTS_AND_SID имеет значение ACE_OBJECT_TYPE_PRESENT, чтобы указать, что элемент ObjectTypeGuid содержит валидный GUID. GUID определяет тип дочернего объекта, создание которого контролируется.

В следующем примере pOldDACL должен быть допустимым указателем на существующую структуру ACL. Для получения информации о том, как создать структуру ACL для объекта, см. раздел Создание дескриптора безопасности для нового объекта на C++.

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

// pOldDACL must be a valid pointer to an existing ACL structure.

// guidChildObjectType must be the GUID of an object type 
// that is a possible child of the object associated with pOldDACL.
 
// 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.ObjectsPresent = ACE_OBJECT_TYPE_PRESENT;
ObjectsAndSID.ObjectTypeGuid = guidChildObjectType;
ObjectsAndSID.InheritedObjectTypeGuid  = GUID_NULL;
ObjectsAndSID.pSid = (SID *)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);