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


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

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

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

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

В следующем примере функция 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);