/etc/init.d/xxx 内での su

デーモンを一般ユーザの権限で使おうと、/etc/init.d/ 以下の起動スクリプトの中で su コマンドを使用する場合がある。しかし、SELinuxが有効の場合落とし穴があるので注意。
1. unconfined_t から initrc_exec_t を実行する形になるので、スクリプトはinitrc_tドメインで動作する。
2. suコマンドは認証にPAMを使用するが「require session pam_selinux.so open multiple」行が存在するため、複数のコンテキストに遷移可能な場合はどのコンテキストでセッションを開始するか選択する。
3. initrc_tドメインでsuコマンドを動かした場合、多くのコンテキストに遷移可能である(そりゃそうだ、ApacheからPostgreSQLから、なんだってここが起点になる)。そのため、セッションを実行するコンテキストの入力が促される。
4. よって、/etc/init.d/xxx スクリプトで su コマンドを使うと、スクリプトが入力待ちになったまま返ってこなくなる。

例えばPostgreSQLのように、デーモンを一般ユーザ権限で動かしたい場合にどうするかを見てみると、実は su コマンドは使用していないようだ。以下は、/etc/init.d/postgresql の一部

# For SELinux we need to use 'runuser' not 'su'
if [ -x /sbin/runuser ]
then
SU=runuser
else
SU=su
fi

suコマンドを使っていない。
/sbin/runuserなら確かに認証を要求されないし、こういった用途であれば必要十分かもしれない。

気が付きにくいかもしれないが、結構ハマりやすいかもしれない。

この話は一応、RedHatEL4-U2でのお話ということです。
本文にはその辺書いてなかった…。あべし orz