RPi2でubuntu14.04LTS(7)pam-scriptでbashログイン非依存なスクリプト実行
pam-scriptでLightDMに対応
LightDMでログインするとbashログインを経由せずにx-windowセッションが開始されるので、.bash_profileと.bash_logoutが実行されず、ホームディレクトリのファイルをtmpfsに逃がす仕掛けがうまく働きません。
これを解決するため、pam-scriptでセッション開始/終了時にスクリプトをフックさせることにします。
まずはインストール。
1 |
sudo apt-get -y install libpam-script |
pam-scriptはユーザー認証処理の特定のタイミングでスクリプトをフックする仕組みです。
/usr/share/libpam-scriptに既定のファイル名のスクリプトを置くことで、セッション開始/終了時に任意の処理を噛ませることができます。
また、bashでもLightDMでも同じように動作してくれます。
スクリプト作成
セッション開始時に実行されるスクリプト/usr/share/libpam-script/pam_script_ses_openを新規作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 |
#!/bin/bash . /usr/share/libpam-script/temporize.list temporize() { if [ ! -L /home/$1 ]; then if [ ! -e /tmp/$1 ]; then if [ -e /home/$1 ]; then cp -ra /home/$1 /tmp/$1 else if [ -d /home/$1 ]; then mkdir -p /tmp/$1 else touch /tmp/$1 fi chown $PAM_USER:$PAM_USER /tmp/$1 fi fi rm -rf /home/$1 ln -s /tmp/$1 /home/$1 fi } [ ! -e /home/$PAM_USER ] && exit 0 [ `w -h | grep -c "^$PAM_USER[ \t]"` -ne "0" ] && exit 0 mkdir -p /tmp/$PAM_USER chown $PAM_USER:$PAM_USER /tmp/$PAM_USER for f in ${ITEMS[@]}; do temporize $PAM_USER/$f done |
セッション終了時に実行されるスクリプトは/usr/share/libpam-script/pam_script_ses_closeです。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 |
#!/bin/bash . /usr/share/libpam-script/temporize.list permanent() { if [ -L /home/$1 ]; then rm /home/$1 fi if [ ! -e /home/$1 -a -e /tmp/$1 ]; then cp -ra /tmp/$1 /home/$1 fi rm -rf /tmp/$1 } [ ! -e /home/$PAM_USER ] && exit 0 [ `w -h | grep -c "^$PAM_USER[ \t]"` -ne "0" ] && exit 0 for f in ${ITEMS[@]}; do permanent $PAM_USER/$f done rm -rf /tmp/$PAM_USER |
pam-scriptはリブート、シャットダウン時の面倒は見てくれないので、まとめて/homeに書き戻すスクリプトwritebackhomeを新規作成します。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#!/bin/bash . /usr/share/libpam-script/temporize.list permanent() { if [ -L /home/$1 ]; then rm /home/$1 fi if [ ! -e /home/$1 -a -e /tmp/$1 ]; then cp -ra /tmp/$1 /home/$1 fi rm -rf /tmp/$1 } for u in `ls /tmp`; do [ `cat /etc/passwd | grep -c "^$u:"` -ne "1" ] && continue [ ! -e /home/$u ] && continue for f in ${ITEMS[@]}; do permanent $u/$f done rm -rf /tmp/$u done |
これらのスクリプトは、スクリプトtemporizeから若干変更しました。
ユーザー名を$USERではなく$PAM_USERで受け取っていること、ホームディレクトリが存在するか確認している、退避するファイル名を別ファイルに追い出している、ファイルだけでなくディレクトリにも対応、などの変更を加えています。
退避するファイル名は/usr/share/libpam-script/temporize.listに記述します。
1 |
ITEMS=(".bash_history" ".Xauthority" ".xsession-errors") |
古い処理の削除と修正
.bash_profileからスクリプトの呼び出しを削除します。
1 |
# /usr/local/bin/temporize login |
.bash_logoutからもスクリプトの呼び出しを削除します。
1 2 3 4 5 6 7 8 9 |
# ~/.bash_logout: executed by bash(1) when login shell exits. # when leaving the console clear the screen to increase privacy if [ "$SHLVL" = 1 ]; then [ -x /usr/bin/clear_console ] && /usr/bin/clear_console -q fi # /usr/local/bin/temporize logout |
/etc/init.d/transientlogからtemporizeに代えてwritebackhomeを実行させます。
102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 |
do_stop() { # Return # 0 if daemon has been stopped # 1 if daemon was already stopped # 2 if daemon could not be stopped # other if a failure occurred # /usr/local/bin/temporize shutdown /usr/local/bin/writebackhome [ -f $LOCKFILE ] || return 1 # Check if I am root [ `id -u` -eq 0 ] || return 2 # Merge back to permanent storage cp -rfup $VARLOG -T $VARLOGPERM # The following cannot fail... or can it? umount -l $VARLOG umount -l $VARLOGPERM rm -f $LOCKFILE return 0 } |
ここでは分かりやすくするためにコメントアウトしていますが、行削除で構いません。
使わなくなったスクリプトは削除しておきます。
1 |
sudo rm /usr/local/bin/temporize |