PHPでのファイル操作において、Linuxシステム上の権限設定に関する注意点が存在します。特にファイルアップロード処理における権限設定は、セキュリティ面で重要です。
@chmod($filePath, 0666 & ~umask());
この式では、ファイルのアクセス権を適切に設定するための計算が行われています。Linuxにおける~(チルダ)記号はホームディレクトリを示すものですが、ここではビット演算子としての役割を果たしています。
public function move(string $directory, string $name = null)
{
if ($this->isValid()) {
if ($this->test) {
return parent::move($directory, $name);
}
$destination = $this->getTargetFile($directory, $name);
set_error_handler(function ($type, $msg) use (&$error) { $error = $msg; });
$moved = move_uploaded_file($this->getPathname(), $destination);
restore_error_handler();
if (!$moved) {
throw new FileException(sprintf('ファイル "%s" を "%s" に移動できませんでした (%s).', $this->getPathname(), $destination, strip_tags($error)));
}
@chmod($destination, 0666 & ~umask());
return $destination;
}
switch ($this->error) {
case \UPLOAD_ERR_INI_SIZE:
throw new IniSizeFileException($this->getErrorMessage());
case \UPLOAD_ERR_FORM_SIZE:
throw new FormSizeFileException($this->getErrorMessage());
case \UPLOAD_ERR_PARTIAL:
throw new PartialFileException($this->getErrorMessage());
case \UPLOAD_ERR_NO_FILE:
throw new NoFileException($this->getErrorMessage());
case \UPLOAD_ERR_CANT_WRITE:
throw new CannotWriteFileException($this->getErrorMessage());
case \UPLOAD_ERR_NO_TMP_DIR:
throw new NoTmpDirFileException($this->getErrorMessage());
case \UPLOAD_ERR_EXTENSION:
throw new ExtensionFileException($this->getErrorMessage());
}
throw new FileException($this->getErrorMessage());
}
このコードでは、アップロードされたファイルの最終的なアクセス権を制御する処理が含まれています。特に以下の行が重要です。
@chmod($destination, 0666 & ~umask());
この計算式の背景にはLinuxの権限体系が関係しています。
ll -a
-rw-r--r--. 1 root root 176 Dec 29 2013 .bashrc
drwx------. 22 root root 4096 Nov 11 15:25 .cache
上記の出力結果の構成要素は以下の通りです:
- ①ファイルタイプ
- ②アクセス権限
- ③リンク数
- ④所有者ユーザー
- ⑤所属グループ
- ⑥ファイルサイズ
- ⑦最終変更日時
- ⑧ファイル名
アクセス権限の計算方法について説明します。
r 4
w 2
x 1
- 0
例として:
- rw- --- --- → 4+2=6 → 600
- rw- r-- r-- → 4+2=6, 4=4, 4=4 → 644
- rwx r-x r-x → 4+2+1=7, 4+1=5, 4+1=5 → 755
umaskコマンドはデフォルトのファイル権限を制御するための重要な設定です。
vi /etc/profile
if [ $UID -gt 199 ] && [ "`/usr/bin/id -gn`" = "`/usr/bin/id -un`" ]; then
umask 002
else
umask 022
fi
umaskの基本的な動作:
- umaskはユーザーがファイルを作成する際の初期権限を決定するマスク値
- システム全体に影響を与えるため、/etc/profileで設定される
- デフォルトではファイルが666(読取・書込)、ディレクトリが777(読取・書込・実行)
- 特殊権限(SUID:4, SGID:2, SBIT:1)は最上位ビットで表される
- 管理者のumaskは通常0022、一般ユーザーは0002
以上の仕組みから、以下のコードが有効な理由が理解できます。
@chmod($destination, 0666 & ~umask());
この式は、管理者ユーザーでも一般ユーザーでも安定した権限設定が可能になります。