Zuweisen von Sicherheit zu einer neuen Datei auf IRP_MJ_CREATE
Die letzte Aufgabe bei der Erstellungsverarbeitung besteht darin, der neuen Datei Sicherheit zuzuweisen. Während das Windows-Sicherheitsmodell Vererbung unterstützt (einzelne ACE-Einträge werden so markiert, dass sie beim Erstellen neuer Dateien oder Verzeichnisse geerbt werden), wird dies außerhalb des Dateisystems implementiert. Daher ist der Großteil der Logik innerhalb des Dateisystems für die Speicherung des neuen Sicherheitsdeskriptors vorgesehen. Hier sehen Sie eine Beispielroutine:
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;
}
Beachten Sie, dass die Logik zum Erstellen des anfänglichen Sicherheitsdeskriptors (z. B. Vererbung) nicht innerhalb des Dateisystems behandelt wird. Dies entspricht dem einfachen Modell für die Verarbeitung von Sicherheitsbeschreibungen innerhalb der Dateisystemebene.