Назначение безопасности новому файлу в IRP_MJ_CREATE
Последней задачей в обработке создания является назначение безопасности новому файлу. Хотя модель безопасности Windows поддерживает наследование (отдельные записи ACE помечаются таким образом, что они наследуются при создании новых файлов или каталогов), это реализуется вне файловой системы. Таким образом, основная часть логики в файловой системе предназначена для хранения нового дескриптора безопасности. Ниже приведен пример подпрограммы:
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;
}
Обратите внимание, что логика создания начального дескриптора безопасности (например, понимание наследования) не обрабатывается в файловой системе. Это соответствует простой модели обработки дескрипторов безопасности на уровне файловой системы.