web-dev-qa-db-ja.com

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

あなたがこの構造を持っているとしましょう:

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

file3は、システム上の別の場所にある別のfile3へのリンクです。

それでは、ディレクトリとその中のすべてのコンテンツをchmod 777と言いましょう。 file3内の私の/tmpはそれらの許可を受けますか?また、状況は同じだが逆になったとしましょう。

/tmp/file3 -> /directory/file3

リンク先のファイルにアクセス許可を適用した場合、リンクにどのような影響がありますか?

88
n0pe

それはあなたが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
88
peth

baraboomとpethの答えはどちらも正しいです。シンボリックリンク自体のパーミッションビットは無関係で(macOSを除く。下記参照)、シンボリックリンクのパーミッションを変更する - chmodコマンドラインツールまたはchmod()システムコールで - シンボリックリンクのターゲットに対して実行されたかのように動作します。

symlink()システムコールのSUSv4/POSIX.1-2008記述を引用するには

作成されたシンボリックリンクのファイルモードビットの値は指定されていません。 POSIX.1-2008で規定されているすべてのインタフェースは、シンボリックリンクの内容を常に読み取ることができるかのように動作します。ただし、ファイルモードビットの値は/のst_modeフィールドに返されます。statstructureは指定されていません。

ここで、「未指定」は各実装の解釈の余地を残します。詳細:

  • Linux(ext4fsを使用してテスト済み)では、シンボリックリンクが作成されたときのumaskの内容にかかわらず、stat()st_mode=0777を返します。したがってls -lは、シンボリックリンクの場合は常にlrwxrwxrwxを表示します。
  • MacOS(HFS)とFreeBSD(UFSとZFSの両方)では、シンボリックリンクはそれ自身の許可を持っています:これを達成するために内部的にPOSIX以外のlchown()システムコールを使う上記のchmod -hコマンドは変更できますstat()システムコールはst_modeに対してこの値を返します。

POSIXで規定されているように、LinuxとFreeBSDのシンボリックリンクはいつでもたどることができます。特に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番目の-> targetコマンドからの出力にls -l部分が欠落していること、およびユーザーがtargetに対する読み取り許可を持っていなくてもcat symlinkは引き続き成功し、symlinkファイルの内容を印刷したことに注意してください。)

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

5
astralblue