Controllo della creazione di oggetti figlio in C++

È possibile usare l'elenco dati di un oggetto contenitore per controllare chi è autorizzato a creare oggetti figlio all'interno del contenitore. Ciò può essere importante perché l'autore di un oggetto viene in genere assegnato come proprietario dell'oggetto e il proprietario di un oggetto può controllare l'accesso all'oggetto.

I vari tipi di oggetti contenitore hanno diritti di accesso specifici che controllano la possibilità di creare oggetti figlio. Ad esempio, un thread deve avere KEY_CREATE_SUB_KEY accesso a una chiave del Registro di sistema per creare una sottochiave sotto la chiave. L'elenco dati di una chiave del Registro di sistema può contenere ACL che consentono o negano questo diritto di accesso. Analogamente, NTFS supporta i diritti di accesso FILE_ADD_FILE e FILE_ADD_SUBDIRECTORY per controllare la possibilità di creare file o directory in una directory.

Il ADS_RIGHT_DS_CREATE_CHILD diritto di accesso controlla la creazione di oggetti figlio in un oggetto DS (Directory Service). Tuttavia, gli oggetti DS possono contenere diversi tipi di oggetti, quindi il sistema supporta una granularità più fine del controllo. È possibile usare ACL specifici dell'oggetto per consentire o negare il diritto di creare un tipo specificato di oggetto figlio. È possibile consentire a un utente di creare un tipo di oggetto figlio impedendo all'utente di creare altri tipi di oggetti figlio.

Nell'esempio seguente viene usata la funzione SetEntriesInAcl per aggiungere un ACE specifico dell'oggetto a un elenco di controllo di accesso. Ace concede l'autorizzazione per creare un tipo specificato di oggetto figlio. Il membro grfAccessPermissions della struttura EXPLICIT_ACCESS è impostato su ADS_RIGHT_DS_CREATE_CHILD per indicare che l'ACE controlla la creazione dell'oggetto figlio. Il membro ObjectsPresent della struttura OBJECTS_AND_SID è impostato su ACE_OBJECT_TYPE_PRESENT per indicare che il membro ObjectTypeGuid contiene un GUID valido. Il GUID identifica un tipo di oggetto figlio la cui creazione è controllata.

Nell'esempio seguente pOldDACL deve essere un puntatore valido a una struttura ACL esistente. Per informazioni su come creare una struttura ACL per un oggetto, vedere Creazione di un descrittore di sicurezza per un nuovo oggetto in 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);