UNIX では、複数のユーザーで同一のマシンを使用することを前提に 設計されています。そこで、ファイルへのアクセス権制御、 即ち他人に見せてもよいファイル・見せたくないファイルの制御が、 UNIX において重要となります。
UNIX では、自分のホームディレクトリへ他人が勝手にファイルを書いたり、 自分のメールを他人に読まれたりされないようにすることが可能です。 また特定のグループに所属するメンバーのみ読み書き可能なファイルを 作ることもできます。 ここではこのようなファイルのアクセス権の制御について見ていきます。
自分のホームディレクトリで ls コマンドを幾つかのオプションを指定して実行すると、 およそ以下のような出力が得られます。
$ ls -Flag drwxr-xr-x 7 inex inex 1024 Sep 29 02:34 ./ drwxr-xr-x 282 root root 5120 Sep 29 20:51 ../ -rw-r--r-- 1 inex inex 266 May 12 20:12 .alias -rw-r--r-- 1 inex inex 91 May 12 20:12 .bash_profile -rw-r--r-- 1 inex inex 55 May 12 20:12 .bashrc -rw-r--r-- 1 inex inex 375 May 12 20:12 .cshrc -rw-r--r-- 1 inex inex 286 May 12 20:12 .emacs drwxr-xr-x 2 inex inex 1024 Sep 28 02:52 .ncftp/ -rw-r--r-- 1 inex inex 208 May 12 20:12 .nexrc -rw-r----- 1 inex inex 13 May 12 20:12 .qmail -rw-r----- 1 inex inex 43 Sep 30 12:30 .qmail-member drwxr-xr-x 2 inex inex 1024 May 17 19:05 .ssh/ drwxr-xr-x 2 inex inex 1024 Sep 26 23:03 lib/ drwxr-xr-x 5 inex inex 1024 Oct 2 16:11 public_html/ drwxr-xr-x 13 inex inex 2048 Sep 29 02:34 rps/ -rw-r--r-- 1 inex epnetfan 363 Jun 20 12:11 sample.txt |
この出力の最下行を例に取って、この読み方を解説します。左から順に、
-rw-r--r-- | ファイルモード |
1 | ファイルへの"リンク数" |
inex | ファイルの所有者 |
epnetfan | ファイルの属するグループ |
363 | ファイルの大きさ(バイト単位) |
Jun 20 12:11 | ファイルの最終更新時刻 |
sample.txt | ファイルの名前 |
を表しています。これらをファイルの「属性」と呼びます。 (なお、$ man ls としてみるとより詳しく分かります)
一番左側の表示の文字列はファイルの「モード」、すなわち ファイルの型(type)と利用権限(permission)を表しています。
d rwx r-x r-x
左端の1文字はファイルの型を示します。 とりうる文字と型は後述します。
続く文字列で利用権限を示しています。 利用権限の許可対象には
があり、それぞれに対する許可情報を
と読んでいます。
また利用権限には 3 種類あります。
d rwx r-x r-x ^ ^^^ ^^^ ^^^ | | | | | | | アザーズパーミッション | | | | | グループパーミッション | | | ユーザーパーミッション | ファイルの型(type)とりうる文字は、
- --- --- --- d rwx rwx rwx l s s t s S S b c Pとなっています。
左端の文字とファイルの型は、次のように対応づけられています。
- | 通常のファイル |
d | ディレクトリ |
l | シンボリックリンク |
s | ソケット |
b | ブロックデバイス |
c | キャラクタデバイス |
P | 名前つきパイプ |
また、利用権限は以下の通りです。
- | その権限が出ていない |
r | 読み込み許可 |
w | 書き込み許可 |
x | 実行許可 |
s | s ビットが立っていて、かつ実行許可 |
S | s ビットが立っていて、かつ実行不可 |
t | スティッキー(sticky) |
s ビットについては後述します。 (スティッキー(sticky)については付録参照)
※ファイルの所有者, ファイルの属するグループを変更するには chown, chgrp といったコマンドを使用します.
ファイルの利用権限を設定するには chmod コマンドを用います。 基本的な使い方は次の通りです(詳しくは man chmod )。
$ chmod <mode> file1 [file2 ...]
<mode> の部分には 0 から 7 までの数字を 3 桁並べたものが入ります。 左の桁から順にファイルの所有者、ファイルの所属グループ、 その他のユーザーに対する利用権限を示します。 各々の読みだし、書き込み、実行権限は 4, 2, 1 の数字で表され、 上の <mode> にはこの数字の和が代入されます。
許可 | 記号 | 数字 |
---|---|---|
読込 | r | 4 |
書込 | w | 2 |
実行 | x | 1 |
-rw-rw-r--
と変えたい場合、-rw-rw-r-- 42 42 4 | | | 6 6 4 <mode>となるので、
$ chmod 664 fileとすれば変更できます。
上では <mode> を数字で与えましたが、記号で与えることもできます。 <mode> の数字列の代わりに、
対象 | 操作 | 許可 |
---|---|---|
[ugao] | [+-=] | [rwxst] |
対象と操作の文字は以下の意味を表します。※許可の所はファイルモードと同じです。
対象 | 操作 | |||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
この場合、先の例と同じ設定にするには次のようにします。
$ chmod u=rw,g=rw,o=r file
s ビットは、ユーザーに立っている時は suid(セットユーアイディー)、 グループに立っている時は sgid(セットジーアイディー)と呼ばれます。
suid の例として /usr/bin/passwd を見てみます。
$ ls -l /usr/bin/passwd /etc/passwd -rw-r--r-- 1 root bin 734 Apr 19 13:25 /etc/passwd -rws--x--x 1 root bin 7736 Oct 3 1996 /usr/bin/passwd |
/etc/passwd には各自の個人情報が記録されています。 このファイルにはアザーズ書き込み許可が出ていません。 よって通常ならユーザーはパスワードを変更することができません。 そこで suid という仕組みを使います。suid ビットを立てると、 そのプログラムはプログラムの所有者の権限で実行されます。
パスワードを設定/変更する際に passwd コマンドを使いますが、 絶対パスで表記すれば、これは /usr/bin/passwd を実行しています。 この場合 /usr/bin/passwd に suid を立てているので、 /usr/bin/passwd は root の権限で実行されます。 このためパスワードを変更できるわけです。
sgid は上のグループ版です。似たようなものなので説明は割愛します。
では, 実際にファイルを作ってみてパーミッションの変更等をしてみましょう.
同席の相方と互いのファイルを見ることができるかためしてもらいますが, login, logout を繰り返すのが面倒なのでちょっとおまじないをします. まず, もう一つ kterm を立ち上げ, 今 login しているアカウント(foo さん)の 相方(bar さん)になりかわります.
$ kterm & |
< kterm をもう一つ立ち上げる. |
新しく立ち上げた kterm を用いて以下のコマンドを打ち込んでみてください.
$ whoami $ su bar $ whoami $ cd |
< 現在のログインアカウント名を尋ねる (foo だったとする) < bar になりかわる. このとき bar さんのパスワード入力が必要. < 無事 bar さんになっているか現在のアカウント名を尋ねる. < bar さんのホームディレクトリに移動しておく. |
以下, もともとあった kterm を "A ターミナル", あたらしく起動し bar さんになり変わった状態の kterm を "B ターミナル" と呼ぶことにします(もし3人の班なら同様に三つ目のktermを立ち上げてください).
では, まず A,B 両ターミナルで以下の作業をして ディレクトリとファイルを作成してください.
$ cd $ mkdir secret $ echo 'secret-word' > ./secret/word.txt $ chmod 777 secret $ chmod a+rwx secret/word.txt |
< ホームディレクトリに移動. < secret ディレクトリを作成. < 'secret-word' 部分は好きな単語に置き換える. secret ディレクトリの中に ファイルを作成. < chmod をつかって secret ディレクトリのパーミッションを変える. ただしファイルが相方から見えないようにすること. 例文の 777 だとうまくいきませんよ!! < chmod をつかって secret/word.txt ファイルのパーミッションをかえる. ただしファイルが相方から見えないようにすること. またまた a+rwx も悪例ですのでご注意を. |
foo さん, bar さん共に, 今作った相手のファイルを見てみましょう.
$ cat ~foo/secret/word.txt あるいは $ cat ~bar/secret/word.txt |
お互いに相手のファイルが見えなければ成功です. もし見られてしまった場合は, 先の chmod コマンドを 先程とは違うモードで再度実行し, 見られない様にしてください.
見られないようにする方法がわかったら, 今度はいろいろな モードにしてその違いを確かめてください. ディレクトリのモードを変えると, そのディレクトリに移動できなくなったり するはずです. cd コマンドなどを試してみてください.
最後に自分の作った word.txt を消去してください. このとき, どのようなモードだとファイル消去できないかも是非試してください. 自分の卒論などを誤って消してしまわないためにも重要な知識です!!
UNIX ではファイルモードの設定によって, 他人のファイルを見ることが可能です. 大抵の場合, 普通に作成したファイルは他人が見れる状態にあるでしょう. もし本当に見られてはこまる内容のファイルはモードを正しい設定にするように 心がけましょう. 他人がみても良い設定のファイルは基本的に "見ても良い" 訳ですが, "mail" といった文字列のつく名前のファイルやディレクトリの中, あるいは個人的な情報であることが推測できるファイルは, 仮に見れる状態にあっても絶対にみてはいけません. また, 同様に見られては困るファイルを見れる状態で置いておくことも避けましょう. こういったファイルは見た方も, 見られた方も嫌な思いをしてしまいます.
リンクには、"ハードリンク"と"シンボリックリンク"の2種類があります。
先に ls コマンドを用いた説明で、 その実行結果の左から2番目に表示される数字は、 リンク数を表すと述べたと思います。
$ ls -l sample.txt -rw-r--r-- 1 inex epnetfan 363 Jun 20 12:11 sample.txt |
これは正しくは「ハードリンク」の数を表しています。 ハードリンクの数は簡単に言うとファイルの「名前」の数を表しています。
人間は文字列(上の場合 'sample.txt')でファイルを識別しますが、 システムはファイルを「番号」として管理しています。 UNIX では、この番号を「i-ノード」と呼びます。 ファイルと i-ノード番号は1対1に対応(リンク)しています。
i-ノードという概念は、そもそも UNIX のカーネルが、それぞれのパーティションに、 装置番号(device number)を割り当て、 「ディスク」ではなく「ファイルシステム」 という論理的なレベルで処理を行うことに由来しています。 ファイルシステムは、論理的なブロックの集まりから構成され、 単位となるブロックの大きさはシステムによって異なります。
ファイルシステムは、次のような4つの部分に分けられます。
i-ノードには、次のような情報が含まれています。 ここで注意して欲しいことは、i-ノードには、ファイル名は含まれていないということです。
ls -i
とするとファイルの i-ノード番号を実際に見ることができます。
$ ls -i sample.txt 31657 sample.txt |
ハードリンクの数は、 実はそのファイルの対応している i-ノード番号を参照しているファイルの数を表しています。
したがって同じ i-ノード番号をもつ別名のファイルを作ること、 即ちファイルに複数の名前をつけることができます。 これは "ln" コマンドで実行できます。
touch コマンドで空のファイル file1 を作り試してみましょう。 通常ファイルのリンク数は1です。
$ touch file1 $ ls -l file1 -rw-r--r-- 1 inex epnetfan 0 Jun 27 02:39 file1 |
$ ln file1 file2とすると file1 に新しい名前 file2 を加える(リンクを張る)ことができます。
$ ls -l file1 file2 -rw-r--r-- 2 inex epnetfan 0 Jun 27 02:39 file1 -rw-r--r-- 2 inex epnetfan 0 Jun 27 02:39 file2 |
リンク数が2に増えています。 一方ディレクトリのリンク数は必ず2以上になります。 リンクを消すには rm コマンドを使います。
上の ln コマンドにオプション -s をつけて実行してみます。 これは「シンボリックリンク」と呼ばれ、 簡単にいうとファイルの「別名」をつけるようなものです。 類似のものに、Windows 系では「ショートカット」、MAC では「エイリアス」があります。
$ ln -s file1 file3 $ ls -l file1 file3 -rw-r--r-- 2 inex epnetfan 0 Jun 27 02:39 file1 lrwxrwxrwx 1 inex epnetfan 5 Jun 27 02:45 file3 -> file1 |
ハードリンクの場合は i-ノードを直接参照しているのに対し、 シンボリックリンクは「ファイル名」を参照しています。 従って、上の例でも file1 のリンク数も増えませんし、 file3 のリンク数も1のままです。
シンボリックリンクの特徴をみるため、 次のようにコマンドを実行してみましょう。
$ rm file1 $ cat file3 cat: file3: No such file or directory |
$ ls file3 file3 |
これはシンボリックリンクでは「ファイル名」を参照しているためです。 参照先のファイル名が消去されてしまうと、 参照していたファイルの i-ノードを見ることができなくなり、 上の例では file3 を表示しようとするとエラーが返るのです。
ハードリンクとは異なり、 ディレクトリに対するシンボリックリンクは可能です。 シンボリックリンクを消すにはやはり rm コマンドを使います。
ルートディレクトリ( / )の下には tmp というディレクトリがあります。 このディレクトリの属性は、
$ ls -l / drwxrwxrwt 6 root root 1024 Jul 1 12:16 tmp |
モードをみると誰でも読み書きができるようになっていますが、 「アザーズ」の実行許可のところに "t" (スティッキー(sticky)ビット)が立っています。
ディレクトリにスティッキービットが立っている場合、 そのディレクトリの中にあるファイルの名前の変更や消去は、 そのファイルの所有者だけが行えるようになります。
ls -l /dev
としてみると以下のような出力が得られます。
$ ls -l /dev/ total 50 -rwxr-xr-x 1 root root 14373 Nov 30 1996 MAKEDEV* -rwxr-xr-x 1 root root 28676 Nov 30 1996 MAKEDEV-C* -rw-r--r-- 1 root root 1035 Nov 30 1996 README.MAKEDEV -rw-r--r-- 1 root root 1434 Nov 30 1996 README.MAKEDEV-C lrwxrwxrwx 1 root root 4 Jan 15 21:46 X0R -> null crw-r--r-- 1 root root 10, 134 Jun 8 1996 apm_bios crw------- 1 root root 16, 1 Feb 19 1994 arp crw-rw-rw- 1 root sys 10, 3 Jul 18 1994 atibm crw-rw-rw- 1 root sys 14, 4 Jul 19 1994 audio crw-rw-rw- 1 root sys 14, 20 Jul 19 1994 audio1 brw-r----- 1 root disk 29, 0 Feb 16 1995 aztcd crw-r--r-- 1 root root 10, 128 May 25 1996 beep . . . crw-r----- 1 root disk 27, 25 Dec 8 1995 zqft1 crw-r----- 1 root disk 27, 26 Dec 8 1995 zqft2 crw-r----- 1 root disk 27, 27 Dec 8 1995 zqft3 |
ファイルモードを見ると、一番左が見慣れない c や b になっています。 このようなファイルは通常のファイルではありません。
UNIX では基本的にあらゆる物を抽象化して「ファイル」として扱います。 たとえばマウス(/dev/mouse) や画面等もファイルに抽象化して取り扱ってしまいます。
このようなファイルは「デバイスファイル(device file)」と呼ばれます。 デバイスファイルには、c で表されるキャラクタデバイスと、 b で表されるブロックデバイスがあります。
★ /dev/null ★次を実行してみましょう。
$ ls > /dev/null何も出力されません。では、これはどうでしょう?
$ cat /dev/nullやはり何も表示されません。
/dev/null というファイルは、 いかなる入力も捨ててしまう性質を持つデバイスファイルです。 コマンドの出力がうるさい時などに、リダイレクトと組み合わせて使います。
※リダイレクトについては次回、最低限 UNIX / Linux [III]で説明します。最終更新日: 2003/10/24(中神雄一) | Copyright © 2003 inex |