次の方法で共有


IRP_MJ_CREATE でのその他の特殊ケースの確認

呼び出し元が SeChangeNotifyPrivilege を持っていない場合、他の特殊なケースの処理はファイル システム内での IRP_MJ_CREATE 処理の間に行う必要があります。 たとえば、ファイル ID またはオブジェクト ID を使って開くことができるファイルでは、呼び出し元がディレクトリ ツリー構造を走査してオブジェクトに到達するためのアクセス許可を持っていない可能性があるため、呼び出し元がそのファイルへのパスを取得できない場合があります。

ファイル システムで考慮する必要があるケースは次のとおりです。

  • FILE_OPEN_BY_FILE_ID — 呼び出し元がファイルの名前を使用できないようにする必要があります。 この情報 (走査アクセス許可) は作成操作の間にだけわかり、ファイル情報照会呼び出しの間には使用できないので、IRP_MJ_CREATE の間にファイル システムで走査アクセス許可に関する情報を計算する必要があります。

  • SL_OPEN_TARGET_DIRECTORY — ターゲット ファイルが存在しない可能性があり、ファイル作成アクセスでディレクトリをチェックする必要があります。 ターゲットが存在する場合は、削除アクセス チェックが必要になることがあります。 通常、削除アクセス チェックは、IRP_MJ_SET_INFORMATION 処理の間に名前変更操作の時点で行われます。

  • FILE_SUPERSEDEFILE_OVERWRITE — 呼び出し元が明示的に要求しなかった場合でも、破壊的操作では追加のアクセス権が必要です。 たとえば、ファイル システムで置き換え操作を実行するには DELETE アクセス権が必要になる場合があります。

  • FILE_CREATEFILE_OPEN_IFFILE_OVERWRITE_IF — 作成操作では、新しいオブジェクトが作成される親ディレクトリへのアクセス権が必要です。 これは、オブジェクト自体ではなく、それを含むディレクトリでのチェックであるため、前のコード サンプルと似ています。

  • SL_FORCE_ACCESS_CHECK — この値が I/O スタックの場所に設定されている場合は、カーネル モードではなくユーザー モードからの呼び出しであるかのように、チェックを実行する必要があります。 したがって、セキュリティ モニター ルーチンの呼び出しでは、呼び出しがカーネル モード サーバーから行われた場合でも、UserMode を指定する必要があります。

  • ファイル/ディレクトリの削除 — これは、ファイルの ACL の状態 (たとえば、FILE_WRITE_DATA アクセスでは削除が暗黙的に許可されます。データを削除できる場合、ファイルに対する有効な削除アクセス許可があります) およびディレクトリの ACL の状態 (たとえば、含んでいる側のディレクトリに対する FILE_DELETE_CHILD アクセス許可) に基づいている可能性があります。

次のコード例は、FILE_SUPERSEDE と FILE_OVERWRITE に対する特殊なケースの処理を示したものです。どちらのケースも、要求されなかったとしても、呼び出し元には追加のアクセス権が暗黙的に必要です。

{
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)
    //

}

このコード サンプルは、ファイル システム ポリシーが優先される良い例です。 呼び出し元は DELETE アクセスまたは FILE_WRITE_DATA アクセスを要求しませんでしたが、ファイル システムのセマンティクスに基づいて実行される操作にはこのようなアクセスが本来含まれます。