Controlando a criação de objeto filho em C++

Você pode usar a DACL de um objeto de contêiner para controlar quem tem permissão para criar objetos filho dentro do contêiner. Isso pode ser importante porque o criador de um objeto normalmente é atribuído como proprietário do objeto e o proprietário de um objeto pode controlar o acesso ao objeto.

Os vários tipos de objetos de contêiner têm direitos de acesso específicos que controlam a capacidade de criar objetos filho. Por exemplo, um thread deve ter KEY_CREATE_SUB_KEY acesso a uma chave do Registro para criar uma subchave sob a chave. A DACL de uma chave do Registro pode conter ACEs que permitem ou negam esse direito de acesso. Da mesma forma, o NTFS dá suporte aos direitos de acesso FILE_ADD_FILE e FILE_ADD_SUBDIRECTORY para controlar a capacidade de criar arquivos ou diretórios em um diretório.

O ADS_RIGHT_DS_CREATE_CHILD direito de acesso controla a criação de objetos filho em um objeto DS (serviço de diretório). No entanto, os objetos DS podem conter diferentes tipos de objetos, portanto, o sistema dá suporte a uma granularidade mais fina de controle. Você pode usar ACEs específicas do objeto para permitir ou negar o direito de criar um tipo especificado de objeto filho. Você pode permitir que um usuário crie um tipo de objeto filho, impedindo que o usuário crie outros tipos de objetos filho.

O exemplo a seguir usa a função SetEntriesInAcl para adicionar uma ACE específica do objeto a uma ACL. A ACE concede permissão para criar um tipo especificado de objeto filho. O membro grfAccessPermissions da estrutura EXPLICIT_ACCESS é definido como ADS_RIGHT_DS_CREATE_CHILD para indicar que o ACE controla a criação do objeto filho. O membro ObjectsPresent da estrutura OBJECTS_AND_SID é definido como ACE_OBJECT_TYPE_PRESENT para indicar que o membro ObjectTypeGuid contém um GUID válido. O GUID identifica um tipo de objeto filho cuja criação está sendo controlada.

No exemplo a seguir, pOldDACL deve ser um ponteiro válido para uma estrutura de ACL existente. Para obter informações sobre como criar uma estrutura de ACL para um objeto, consulte Criando um descritor de segurança para um novo objeto em 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);