PHPのセーフモードを理解できていなかったので、自分なりに調べた結果をまとめてみる。
これは自分が使っているCORESERVER向けのものなので、他のレンタルサーバーを使用している場合は異なる場合があります。
また、勝手な解釈のため間違っている場合があります。(指摘お願い)
まず、セーフモードがOFFのときはどうなるか。
セーフモードOFFの場合
所有者の違いによるアクセス制限はパーミッションによってのみ。
ブラウザアクセスしてスクリプトを動かすと"apache"というユーザー名、"other"権限で動かす。
例)
スクリプト設置者を"user"とする。
それぞれの実体はマークで表す
■スクリプト
◇ディレクトリ/ファイル
--------------------------------------------------------
■スクリプト(PHP)からディレクトリ/ファイル作成 (権限:apache, 所有者:user)
↓作成
◇dir/file (所有者:apache mod:700)
×
↑
↑権限が"apache"(other)のためパーミッションによりアクセス不可
↑
■作成後、スクリプト(PHP)からアクセス (権限:apache, 所有者:user)
--------------------------------------------------------
この後、dir/fileのパーミッションをchmod()で"707"に変更
--------------------------------------------------------
◇dir/file (所有者:apache mod:707)
↑
↑権限が"apache"(other)だが、パーミッション"707"によりアクセス可
↑
■スクリプト(PHP)からアクセス (権限:apache, 所有者:user)
--------------------------------------------------------
パーミッション"707"(otherアクセス可)に変更したことにより、同じサーバー内の他ユーザーからもアクセス可能になってしまう。
これではセキュリティに問題があるので、運営側が以下のセーフモードで強制的に他ユーザーからのアクセスを不可にする。
セーフモードONの場合
ディレクトリ/ファイルの所有者(UID)と、アクセスを行おうとしているスクリプト(PHP)の所有者が違う場合にスクリプトからのファイルアクセスをできなくする。
それを判断しているのはOSレベルではなくPHP各種関数。
セーフモードにより制限を受けるか無効となる関数
http://jp.php.net/manual/ja/features.safe-mode.functions.php
パーミッションは関係なく所有者だけで判断する。
ブラウザアクセスしてスクリプトを動かすと"apache"というユーザー名、"other"権限で動かすのは同じ。
例)
スクリプト設置者を"user"とする。
--------------------------------------------------------
■スクリプト(PHP)からディレクトリ/ファイル作成 (権限:apache, 所有者:user)
↓作成
◇dir/file (所有者:apache)
×
↑アクセス不可
↑ファイル所有者が"apache"、スクリプト所有者が"user"のため不一致。
↑
■作成後、スクリプト(PHP)からアクセス (権限:apache, 所有者:user)
--------------------------------------------------------
これにより同じサーバーでもユーザーが違う場合は強制的にアクセス不可になるが、外(ブラウザ)からのアクセスではユーザーが"apache"という特別なものになるためスクリプトからもアクセスできなくなってしまう。
セーフモードの場合はパーミッションを変えても意味がないので、CGIモードで動作させる。
(CGIモードについては後で調査)
※参考
その他、mkdir()など個別の動作アリ。
php ディレクトリを作成し、ファイルをコピーする方法
http://sb.xrea.com/showthread.php?t=11906
以下コピペ
---------------
safe mode=ONのサーバの場合についてです。
●そのphpプログラムを通常動作させる場合
・mkdir()ができるが、その後のcopy()ができない。
・mkdir()で作成されたディレクトリの所有者はapache。
・mkdir()では、0x707などのmodが指定して作成できないため、その後のchmod()を使って変更する。
●そのphpプログラムをcgi版として動作させる場合
・mkdir()ができ、その後のcopy()もできる。
・mkdir()で作成されたディレクトリの所有者は自分自身。
・mkdir()では、0x707などのmodが指定して作成する。
・その後のchmod()を使ってのmod変更はできない。
・session_start()をすると、セッションユーザが異なってしまうため、warningが表示され、セッションが維持されない。
解決策(今回の場合です。常に当てはまる訳ではないと思います。)
・phpプログラムをcronを使って別に動作させる。
・cronなので、cgi版で動作させることができる。
・プログラムからsession_start()をはずす(使用しない)。
・cronが動作するまでの間ファイルが存在しないので、コピーされたファイルへのリンクを生成する際にis_file()を使ってコピーが完了している (99/index.phpが存在する)かをチェックし、まだコピーがされていなければ別ファイル(上記で言えば、 hogehoge.php?hoge=99)へのリンクをするようにする。
---------------
セーフモードの束縛
http://zone.maple4ever.net/blog/archives/657/
これは自分が使っているCORESERVER向けのものなので、他のレンタルサーバーを使用している場合は異なる場合があります。
また、勝手な解釈のため間違っている場合があります。(指摘お願い)
まず、セーフモードがOFFのときはどうなるか。
セーフモードOFFの場合
所有者の違いによるアクセス制限はパーミッションによってのみ。
ブラウザアクセスしてスクリプトを動かすと"apache"というユーザー名、"other"権限で動かす。
例)
スクリプト設置者を"user"とする。
それぞれの実体はマークで表す
■スクリプト
◇ディレクトリ/ファイル
--------------------------------------------------------
■スクリプト(PHP)からディレクトリ/ファイル作成 (権限:apache, 所有者:user)
↓作成
◇dir/file (所有者:apache mod:700)
×
↑
↑権限が"apache"(other)のためパーミッションによりアクセス不可
↑
■作成後、スクリプト(PHP)からアクセス (権限:apache, 所有者:user)
--------------------------------------------------------
この後、dir/fileのパーミッションをchmod()で"707"に変更
--------------------------------------------------------
◇dir/file (所有者:apache mod:707)
↑
↑権限が"apache"(other)だが、パーミッション"707"によりアクセス可
↑
■スクリプト(PHP)からアクセス (権限:apache, 所有者:user)
--------------------------------------------------------
パーミッション"707"(otherアクセス可)に変更したことにより、同じサーバー内の他ユーザーからもアクセス可能になってしまう。
これではセキュリティに問題があるので、運営側が以下のセーフモードで強制的に他ユーザーからのアクセスを不可にする。
セーフモードONの場合
ディレクトリ/ファイルの所有者(UID)と、アクセスを行おうとしているスクリプト(PHP)の所有者が違う場合にスクリプトからのファイルアクセスをできなくする。
それを判断しているのはOSレベルではなくPHP各種関数。
セーフモードにより制限を受けるか無効となる関数
http://jp.php.net/manual/ja/features.safe-mode.functions.php
パーミッションは関係なく所有者だけで判断する。
ブラウザアクセスしてスクリプトを動かすと"apache"というユーザー名、"other"権限で動かすのは同じ。
例)
スクリプト設置者を"user"とする。
--------------------------------------------------------
■スクリプト(PHP)からディレクトリ/ファイル作成 (権限:apache, 所有者:user)
↓作成
◇dir/file (所有者:apache)
×
↑アクセス不可
↑ファイル所有者が"apache"、スクリプト所有者が"user"のため不一致。
↑
■作成後、スクリプト(PHP)からアクセス (権限:apache, 所有者:user)
--------------------------------------------------------
これにより同じサーバーでもユーザーが違う場合は強制的にアクセス不可になるが、外(ブラウザ)からのアクセスではユーザーが"apache"という特別なものになるためスクリプトからもアクセスできなくなってしまう。
セーフモードの場合はパーミッションを変えても意味がないので、CGIモードで動作させる。
(CGIモードについては後で調査)
※参考
その他、mkdir()など個別の動作アリ。
php ディレクトリを作成し、ファイルをコピーする方法
http://sb.xrea.com/showthread.php?t=11906
以下コピペ
---------------
safe mode=ONのサーバの場合についてです。
●そのphpプログラムを通常動作させる場合
・mkdir()ができるが、その後のcopy()ができない。
・mkdir()で作成されたディレクトリの所有者はapache。
・mkdir()では、0x707などのmodが指定して作成できないため、その後のchmod()を使って変更する。
●そのphpプログラムをcgi版として動作させる場合
・mkdir()ができ、その後のcopy()もできる。
・mkdir()で作成されたディレクトリの所有者は自分自身。
・mkdir()では、0x707などのmodが指定して作成する。
・その後のchmod()を使ってのmod変更はできない。
・session_start()をすると、セッションユーザが異なってしまうため、warningが表示され、セッションが維持されない。
解決策(今回の場合です。常に当てはまる訳ではないと思います。)
・phpプログラムをcronを使って別に動作させる。
・cronなので、cgi版で動作させることができる。
・プログラムからsession_start()をはずす(使用しない)。
・cronが動作するまでの間ファイルが存在しないので、コピーされたファイルへのリンクを生成する際にis_file()を使ってコピーが完了している (99/index.phpが存在する)かをチェックし、まだコピーがされていなければ別ファイル(上記で言えば、 hogehoge.php?hoge=99)へのリンクをするようにする。
---------------
セーフモードの束縛
http://zone.maple4ever.net/blog/archives/657/