実UID, 実行UID

Posted on Wed 01 January 2014 in blog

プロセスはいくつかのIDを持っている。 あまり深く考えず、実UIDと実行UIDについて考える。

実UID(UID)

  • 呼び出し元のプロセス(親プロセス)の実ユーザーID。
  • 普通にログインして、何かプロセスをシェルから走らせる場合、ログインシェルのUIDがログインユーザーIDなので、ログインユーザーIDになる。

実効UID

  • 呼び出し元のプロセス(親プロセス)の実効ユーザーID。
  • ファイルアクセスに影響。
  • 普通にログインして、何かプロセスをシェルから走らせる場合、ログインシェルのUIDがログインユーザーIDなので、ログインユーザーIDになる。
  • ただし、SUID ビットがあるときは、それに従う。

SUID, SGID, スティッキービット

SUID, SGID

それぞれ setuid, setgidのこと。
まず、 SUID(SGID) ビットが立っているファイルについて見る。
$ ls -l
-rwsr-xr-x 1 root root 51096 5月 26 2012 /usr/bin/passwd
このように、sというビットがユーザーパーミッションを表す部分(SGIDのときは、グループパーミッション部分)に立っている。
さて、パーミッションを見ると passwd はどんなユーザーでも実行できる。
実行した場合、実効UIDがファイルの所有ユーザーとして実行される。(SGIDビットが立っているときは、所有グループが実効GIDになる。)
この仕組みが必要な理由は、例えば、一般ユーザーが自身のパスワードを変更するために、/etc/shadow を書き換える必要がある。しかし、一般ユーザー権限では書き換えることができない。これを解決するためである。
SUID, SGID ビットの設定は以下のようにする。
# SUID ビットを立てる
$ chmod 4770 foo
# SGID ビットを立てる
$ chmod 2770 bar

# 別の方法として、 +sx を使う方法がある
# SUID
$ chmod u+sx foo
# SGID
$ chmod g+sx bar

スティッキービット

(元々は違うけど、)ディレクトリ配下のファイルの削除についての設定。
典型例は /tmp。
このディレクトリの持つ特徴を考えてみよう。
  • 誰でもファイルを作成できる。
  • 自分の作ったファイルを削除できる。
ここまでであれば、
# /tmp : 誰でもファイルを作成できる
$ sudo chmod 777 tmp

# 試しに、適当なファイルを作成・削除できるか試す
$ cd tmp
$ touch user
$ rm user

# root ユーザーでもファイルを作成してみる
$ sudo touch root
  • 他のユーザーのファイルは一般ユーザーは削除できない。
# 先ほどの tmp ではこれが満たされていない
$ rm root #=> 消える!!
これは当たり前で、tmp のパーミッションが 777。ディレクトリの write ができるということは、ファイルの新規作成・削除ができる。
では、 tmp はどのように実現すれば良いだろうか。
そんな時に、スティッキービットが役に立つ。
# スティッキービットを立てる
$ sudo chmod 1777 ../tmp

# 別の方法として、 +t を使う方法がある。
$ sudo chmod a+rwxt ../tmp
スティッキービットをディレクトリに立てておくと、ファイルやディレクトリの所有者しか削除できなくなる。

まとめ

  • 実効UID, 実効GID でファイルアクセスの管理がなされる
  • SUID, SGIDビットを使って、実行したユーザーと実効UID, 実効GID を変更できる。
  • スティッキービットを使えば、誰でも新規にファイルを作れるが、消すのは本人のみ、というディレクトリを作成できる。