Controlar la creación de objetos secundarios en C++

Puede usar la DACL de un objeto contenedor para controlar quién puede crear objetos secundarios dentro del contenedor. Esto puede ser importante porque el creador de un objeto se suele asignar como propietario del objeto y el propietario de un objeto puede controlar el acceso al objeto.

Los distintos tipos de objetos de contenedor tienen derechos de acceso específicos que controlan la capacidad de crear objetos secundarios. Por ejemplo, un subproceso debe tener KEY_CREATE_SUB_KEY acceso a una clave del Registro para crear una subclave en la clave. La DACL de una clave del Registro puede contener ACE que permiten o deniegan este derecho de acceso. Del mismo modo, NTFS admite los derechos de acceso FILE_ADD_FILE y FILE_ADD_SUBDIRECTORY para controlar la capacidad de crear archivos o directorios en un directorio.

El ADS_RIGHT_DS_CREATE_CHILD derecho de acceso controla la creación de objetos secundarios en un objeto de servicio de directorio (DS). Sin embargo, los objetos DS pueden contener diferentes tipos de objetos, por lo que el sistema admite una granularidad más fina del control. Puede usar ASE específicos del objeto para permitir o denegar el derecho a crear un tipo especificado de objeto secundario. Puede permitir que un usuario cree un tipo de objeto secundario al mismo tiempo que impide que el usuario cree otros tipos de objetos secundarios.

En el ejemplo siguiente se usa la función SetEntriesInAcl para agregar una ACE específica del objeto a una ACL. La ACE concede permiso para crear un tipo especificado de objeto secundario. El miembro grfAccessPermissions de la estructura EXPLICIT_ACCESS se establece en ADS_RIGHT_DS_CREATE_CHILD para indicar que la ACE controla la creación del objeto secundario. El miembro ObjectsPresent de la estructura OBJECTS_AND_SID se establece en ACE_OBJECT_TYPE_PRESENT para indicar que el miembro ObjectTypeGuid contiene un GUID válido. El GUID identifica un tipo de objeto secundario cuya creación se está controlando.

En el ejemplo siguiente, pOldDACL debe ser un puntero válido a una estructura de ACL existente. Para obtener información sobre cómo crear una estructura de ACL para un objeto, vea Crear un descriptor de seguridad para un nuevo objeto en 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);