linux – ファイルのパーミッションはシンボリックリンクにどのように適用されますか?

file-permissions linux permissions symbolic-link unix

このような構造になっているとしましょう

+ directory
-- file1
-- file2
-- file3 -> /tmp/file3

file3は、システム上のどこか別のfile3へのリンクです

さて、私がchmod 777ディレクトリとその中のすべてのコンテンツを持っているとしましょう。/tmp にある私の file3 はこれらのパーミッションを受けますか?また、同じ状況を逆にしたとします

/tmp/file3 -> /directory/file3

リンク先のファイルにパーミッションを適用した場合、リンクにどのような影響がありますか?

  99  n0pe  2011-06-27


ベストアンサー

chmodの呼び出し方と、実行しているプラットフォームに依存します

例えば、Linuxシステムでは、man chmodはこう言います

chmod はシンボリックリンクのパーミッションを変更することはありません; chmod システムコールはそのパーミッションを変更することはできません。シンボリックリンクのパーミッションは決して使われないので、これは問題ではありません。しかし、コマンドラインにリストされたシンボリックリンクごとに、chmodはポインテッド・ツー・ファイルのパーミッションを変更します。 対照的に、chmodは再帰的なディレクトリ・トラバースの間に遭遇したシンボリック・リンクを無視します

しかし、Macでは、以下のようなオプションを使って、シンボリックリンクのパーミッションを変更するためにchmodを使うことができます(man chmodから)

-h ファイルがシンボリックリンクの場合、リンク先のファイルではなく、リンク自体のモードを変更します

例として、この回答の残りの部分では、Linuxマシンを使用していると仮定します

最初のケースでchmod -R 777 directoryを実行して再帰的にパーミッションを変更した場合はリンク先に影響はありませんが、chmod 777 directory/*を実行した場合は影響があります

あなたが直接リンクターゲットのパーミッションを変更した場合、それらのパーミッションは(manページとbaraboomが言うように、実際のリンクパーミッションは何のために使用されていませんので)を介して実行されます


イラストのテストログ

$ mkdir dir && touch dir/file{1,2} /tmp/file3 && ln -s {/tmp,dir}/file3
$ ls -l dir/* /tmp/file3
-rw-r--r-- 1 user group  0 2011-06-27 22:02 /tmp/file3
-rw-r--r-- 1 user group  0 2011-06-27 22:02 dir/file1
-rw-r--r-- 1 user group  0 2011-06-27 22:02 dir/file2
lrwxrwxrwx 1 user group 10 2011-06-27 22:02 dir/file3 -> /tmp/file3

$ chmod -R 777 dir && ls -l dir/* /tmp/file3
-rw-r--r-- 1 user group  0 2011-06-27 22:02 /tmp/file3
-rwxrwxrwx 1 user group  0 2011-06-27 22:02 dir/file1
-rwxrwxrwx 1 user group  0 2011-06-27 22:02 dir/file2
lrwxrwxrwx 1 user group 10 2011-06-27 22:02 dir/file3 -> /tmp/file3

$ chmod 700 dir/* && ls -l dir/* /tmp/file3
-rwx------ 1 user group  0 2011-06-27 22:02 /tmp/file3
-rwx------ 1 user group  0 2011-06-27 22:02 dir/file1
-rwx------ 1 user group  0 2011-06-27 22:02 dir/file2
lrwxrwxrwx 1 user group 10 2011-06-27 22:02 dir/file3 -> /tmp/file3

98  peth  2011-06-27


baraboom さんと peth さんの答えはどちらも正しいです。シンボリックリンクのパーミッションビットはそれ自体には関係がなく (macOS を除く; 以下を参照)、シンボリックリンクのパーミッションを変更することは chmod コマンドラインツールや chmod() システムコールによって、あたかもシンボリックリンクのターゲットに対して実行されたかのように振る舞うだけです

SUSv4/POSIX.1-2008 の symlink() システムコールの説明を引用します

作成されたシンボリックリンクのファイルモードビットの値は不定である。POSIX.1-2008 で指定されたすべてのインタフェースは、stat 構造体の st_mode フィールドで返されるファイルモードビットの値が不特定であることを除いて、シンボリックリンクの内容が常に読み取れるように振る舞わなければならない

ここで、「不特定」は、各実施形態に解釈の余地を残す。具体的に

  • Linux (ext4fs を使ってテスト) では、シンボリックリンクが作成されたときの umask が何であったかに関わらず、 stat()st_mode=0777 を返します; したがって ls -l はシンボリックリンクに対しては常に lrwxrwxrwx を表示します
  • macOS (HFS) と FreeBSD (UFS と ZFS の両方) では、シンボリックリンクはそれ自身のパーミッションを持っています。上述の chmod -h コマンドはこのリンクパーミッションを変更することができます (内部的には、POSIX 以外の lchown() システムコールを使って変更します)

Linux と FreeBSD のシンボリックリンクは、POSIX で指定されているように、常に追従することができます。特に FreeBSD では、これはシンボリックリンクのファイルモードがアクセス制御に全く影響しないことを意味します

一方、macOSはPOSIXを少し壊しています。シンボリックリンクは読み込み権限に関係なく辿ることができますが、readlink()は読み込み権限がないとEACCES(Permission denied)で失敗します

$ sudo ln -shf target symlink
$ sudo chmod -h 444 symlink
$ ls -l symlink
lr--r--r--  1 root  staff  1 Mar 14 13:05 symlink -> target
$ sudo chmod -h 000 symlink
$ ls -l symlink

ls: symlink: Permission denied
l---------  1 root  staff  1 Mar 14 13:05 symlink
$ echo kthxbye > target
$ cat symlink
kthxbye

(2番目のls -lコマンドの出力では-> targetの部分が欠けていること、cat symlinkではsymlinkの読み込み権限がないにもかかわらずcat symlinkが成功してtargetファイルの内容を印刷していることに注意)

NetBSD は明らかに symperm という名前の特別なマウントオプションを提供しているようですが、これが設定されていると、シンボリックリンクの読み取り/実行権限が readlink() とリンクトラバーサルを制御するようになります

6  astralblue  2017-03-14


  1. (どのプロセスでも使用されていないことを確認した後)リンクファイルを削除します
  2. 777-umask=必須のファイルパーミッションになるようにumaskを設定します
  3. リンクファイルを新たに作成します

-1  AVA  2015-10-02


タイトルとURLをコピーしました