2007年03月12日

添付ファイルがUPできなくなった

検索で少しでもヒットするようなタイトルにしてみました(笑)

と言うわけでPukiWikiでPHPのアップデート後や、レンタルサーバなんかを使っていてある日突然ファイル添付ができなくなったときの対応。

同様の問題が一応、公式サイトにも質問が出ていますが結局解決していないので新たにエントリを起こすことにしました。

で、まず症状は以下のような感じ。

  • 「○○にアップロードしました」と表示されるのに実際はアップロードされていない
  • attachフォルダを見てみるとファイルの実体は見あたらず、アップロードした時刻のlogファイル(中身は1だけ)が作成されている
  • 本体のソースは全然弄ってないのに発症
  • PHPを古めのバージョンから最近のバージョンへアップデートしたら発症
  • もしくはレンタルサーバなどでサーバメンテ後に急に発症
そして、これの原因ですが、ズバリsafe-mode時のopen_basedirの穴が未だにぽろぽろ修正されているため。

まぁ、どのぐらいの頻度で修正されているかは

辺りを見て頂くことにして、実際今回問題になったのはこの関数
  • 注意: move_uploaded_file() は セーフモード と open_basedir の両者を考慮しています。 しかしながら、アップロードされたファイルを移動する destination パスのみ制限が設けられます。 そこでは filename がそれらの制限に抵触する可能性があるためです。 move_uploaded_file() は PHP を通じてアップロードされたファイルのみを移動できるようにすることで この操作の安全性を保証しています。
注意書きにもあるように本来、宛先PATHのみ考慮されるはずなんですが、手元のPHP4.4.6では何故か元になるアップロードPATHもこれの範疇に入っています(苦笑)

ちなみにPHPでは

にあるとおりファイルをアップロードすると、まず、アップロードフォルダ(通常は /var/tmp 辺り)書き込まれるのでそれを適宜移動するしようです。

で、実際にどのコードで問題が起こっているかというと「plugin/attach.inc.php」の193行目付近のこれ

	if (move_uploaded_file($file['tmp_name'], $obj->filename))
		chmod($obj->filename, PLUGIN_ATTACH_FILE_MODE);
ここで「move_uploaded_file」が失敗してPHPのアップロードフォルダからの移動がエラーも出ずに無かったことになっています。

たとえば

	if (move_uploaded_file($file['tmp_name'], $obj->filename)){
		chmod($obj->filename, PLUGIN_ATTACH_FILE_MODE);
	}else{
		echo 'Is not this server safe mode?';
		exit;
	}
と言うふうにコードを書き換えると見事にここで落ちている事が解ります。

で、どうしたかというと、php.iniの「upload_tmp_dir」を「open_basedir」の下に設定しただけです。

例)
open_basedir /home/hoge upload_tmp_dir /home/hoge/foo
これでうまいこと動作しました。 にしても、ほんとPHPは本気で使う言語ではないなぁと思います・・・

Posted by Takuchan at 2007年03月12日 01:35 | トラックバック(0)