Affectation de la sécurité à un nouveau fichier sur IRP_MJ_CREATE
La dernière tâche de la gestion des créations consiste à affecter la sécurité au nouveau fichier. Bien que le modèle de sécurité Windows prenne en charge l’héritage (les entrées ACE individuelles sont marquées de telle sorte qu’elles sont héritées lors de la création de nouveaux fichiers ou répertoires), cela est implémenté en dehors du système de fichiers. Ainsi, la majeure partie de la logique dans le système de fichiers est dédiée au stockage du nouveau descripteur de sécurité. Voici un exemple de routine :
NTSTATUS FsdAssignInitialSecurity( PIRP_CONTEXT IrpContext,
PFCB Fcb, PFCB Directory)
{
NTSTATUS status = STATUS_SUCCESS;
BOOLEAN CreateDir = ((IrpContext->IrpSp->Parameters.Create.Options
& FILE_DIRECTORY_FILE)==FILE_DIRECTORY_FILE);
PACCESS_STATE AccessState =
IrpContext->IrpSp->Parameters.Create.SecurityContext->AccessState;
PSECURITY_DESCRIPTOR SecurityDescriptor = NULL;
//
// Make sure the parent directory's security descriptor is loaded.
//
(void) FsdLoadSecurityDescriptor(IrpContext, Directory);
//
// don't care about the return code here, as it is handled later
//
if (Directory->SecurityDescriptor == NULL) {
//
// If the parent has no security, then we are outside
// of the normal Windows paradigm.
//
// The child (that is, the target of the create) will also have
// a NULL SD.
//
// Note that you can always assign security to the file object
// explicitly at later on.
//
return STATUS_SUCCESS;
}
//
// Now create the security descriptor.
//
status = SeAssignSecurity(Directory->SecurityDescriptor,
AccessState->SecurityDescriptor,
&SecurityDescriptor,
CreateDir,
&AccessState->SubjectSecurityContext,
IoGetFileObjectGenericMapping(),
PagedPool);
if (!NT_SUCCESS(status)) {
return status;
}
//
// Associate the SD with the file; use our own storage so when
// cleanup occurs it is unnecessary to know if the storage came from the
// security reference monitor.
//
Fcb->SecurityDescriptorLength =
RtlLengthSecurityDescriptor( SecurityDescriptor );
Fcb->SecurityDescriptor = ExAllocatePoolWithTag(PagedPool,
Fcb->SecurityDescriptorLength, 'DSyM');
if (!Fcb->SecurityDescriptor) {
//
// There is no paged pool.
//
SeDeassignSecurity(&SecurityDescriptor);
Fcb->SecurityDescriptorLength = 0;
return STATUS_NO_MEMORY;
}
RtlCopyMemory(Fcb->SecurityDescriptor, SecurityDescriptor,
Fcb->SecurityDescriptorLength);
SeDeassignSecurity(&SecurityDescriptor);
//
// Store the SD persistently (this is file system specific).
//
(void) FsdStoreSecurityDescriptor(IrpContext, Fcb);
return STATUS_SUCCESS;
}
Notez que la logique de construction du descripteur de sécurité initial (compréhension de l’héritage, par exemple) n’est pas gérée dans le système de fichiers. Cela est conforme au modèle simple de gestion des descripteurs de sécurité au sein de la couche des systèmes de fichiers.