Verificando outros casos especiais em IRP_MJ_CREATE
Outros tratamentos de casos especiais devem ocorrer durante o tratamento de IRP_MJ_CREATE dentro do sistema de arquivos se o chamador não tiver SeChangeNotifyPrivilege. Por exemplo, um arquivo que pode ser aberto usando sua ID de arquivo ou ID de objeto pode não permitir que o chamador obtenha o caminho para esse arquivo, já que o chamador pode não ter permissão de passagem para acessar o objeto por meio da estrutura de árvore de diretório.
Os casos que talvez você queira considerar em seu sistema de arquivos:
FILE_OPEN_BY_FILE_ID — o nome do arquivo não deve ser disponibilizado para o chamador. Como essas informações (permissão de passagem) só são conhecidas durante a operação de criação e não estarão disponíveis durante uma chamada de consulta de informações de arquivo, as informações sobre a permissão de passagem devem ser computadas pelo sistema de arquivos durante o IRP_MJ_CREATE.
SL_OPEN_TARGET_DIRECTORY — o arquivo de destino pode não existir e o diretório deve ser verificado quanto ao acesso à criação de arquivos. Se o destino existir, poderá exigir uma marcar de acesso de exclusão. Normalmente, a marcar de acesso de exclusão é feita no momento da operação de renomeação durante IRP_MJ_SET_INFORMATION processamento.
FILE_SUPERSEDE e FILE_OVERWRITE — operações destrutivas exigem direitos de acesso adicionais, mesmo que o chamador não tenha solicitado explicitamente. Por exemplo, um sistema de arquivos pode exigir acesso DELETE para executar uma operação de substituição.
FILE_CREATE, FILE_OPEN_IF e FILE_OVERWRITE_IF — as operações construtivas exigem acesso ao diretório pai em que o novo objeto está sendo criado. Esse é um marcar no diretório que contém, não no próprio objeto e, portanto, semelhante ao exemplo de código anterior.
SL_FORCE_ACCESS_CHECK — se esse valor for definido no local da pilha de E/S, o marcar deverá ser executado como se a chamada fosse do modo de usuário, não do modo kernel. Portanto, as chamadas para rotinas de monitor de segurança devem especificar UserMode mesmo que a chamada tenha origem em um servidor de modo kernel.
Exclusão de arquivo/diretório — isso pode ser baseado no estado de ACL do arquivo (por exemplo, FILE_WRITE_DATA acesso permite implicitamente excluir; se você puder excluir os dados, terá permissões de exclusão efetivas no arquivo), bem como o estado da ACL do diretório (FILE_DELETE_CHILD permissão no diretório que contém, por exemplo).
O exemplo de código a seguir demonstra o tratamento de caso especial para FILE_SUPERSEDE e FILE_OVERWRITE, ambos os casos em que o acesso adicional é implicitamente exigido pelo chamador, mesmo que não tenha sido solicitado.
{
ULONG NewAccess = Supersede ? DELETE : FILE_WRITE_DATA;
ACCESS_MASK AddedAccess = 0;
PACCESS_MASK DesiredAccess =
&IrpSp->Paramters.Create.SecurityContext->DesiredAccess;
//
// If the caller does not have restore privilege, they must have write
// access to the EA and attributes for overwrite or supersede.
//
if (0 == (AccessState->Flags & TOKEN_HAS_RESTORE_PRIVILEGE)) {
*DesiredAccess |= FILE_WRITE_EA | FILE_WRITE_ATTRIBUTES;
//
// Does the caller already have this access?
//
if (AccessState->PreviouslyGrantedAccess & NewAccess) {
//
// No - they need this as well
//
*DesiredAccess |= NewAccess;
}
//
// Now check access using SeAccessCheck (omitted)
//
}
Este exemplo de código é um bom exemplo de onde a política do sistema de arquivos tem precedência. O chamador não solicitou acesso DELETE ou acesso FILE_WRITE_DATA, mas esse acesso é inerente à operação que está sendo executada com base na semântica do sistema de arquivos.