BLOB機能のサポート
PostgreSQLには、データベースにファイルの内容をそのまま格納したい時に便利なBLOB(Binary Large Object)という機能がある。
ネイティブPostgreSQLには、特にBLOBに対するアクセス制御機能が備わっていないために、重要なデータを保持する場合には注意が必要である。が、それは置いておいてww
SE-PostgreSQLでは、DBMSを経由した情報フローを管理するという観点から、当然BLOBに対するアクセス制御を行う必要がある。つまり、BLOBへのread/wrtieにアクセス制御を行う必要がある。これ自体は全く難しい話ではなく、フックを一つ入れれば済むだけの話である。
頭痛のタネになったのが、サーバー側の lo_import()関数と、lo_export()関数。
Oid lo_import(text <em>filename</em>) int32 lo_export(Oid <em>loid</em>, text <em>filename</em>)
lo_import()関数は、filenameで指定されたファイルをサーバ側のファイルシステム上で検索し、それをBLOBとしてDBに叩き込む。
lo_export()関数は、loidで指定されたBLOBを、filenameとして指定されたサーバ側ファイルシステム上のファイルとして書き込む。
このファイル入出力を行うのは SE-PostgreSQLサーバプロセスであり、クライアントプロセスではない。
ファイルに対するアクセス制御も、SE-PostgreSQLサーバプロセス <--> ファイル間でOSがフックして行われる。このため、クライアントプロセスの権限に関係なくSE-PostgreSQLサーバプロセスの書き出した物として扱われる。
ここで私の採った方法は、blob:{import export}というアクセスベクタを新たに追加したというもの。ここでのポイントは、import/exportの対象が SE-PostgreSQL のサーバプロセスであること。
つまり、以下のようなデータフローを記述できるようになる。
SE-PostgreSQL blob:read Binary Large Client Process <------------- Object (BLOG) | | blob:export SE-PostgreSQL file:write Exported +---------------------> Server Process ------------> Files
SE-PostgreSQLは最初に、BLOB→Clientのread権限をチェックし、次にClient→Serverのexport権限をチェックする。
そして、Server→Fileのfile:write権限がOSによって行われ、lo_export()の処理が行われる。
ここでの考え方は、lo_export()の処理では一旦クライアントがBLOBのデータを参照し、それをサーバに転送する。そして、サーバがそれをファイルに書き出すというもの。
あくまでも、ファイルとのI/Oを行っている主体はサーバプロセスであるので矛盾は生じない。