次のページ
前のページ
目次へ
root 特権の必要な、グラフィカルな設定ツールを実行したいとしましょう。しかし、
X セッションは普通のアカウントで実行しています。始めは奇妙に思うかも
しれませんが、X サーバはツールがディスプレイにアクセスすることを許しません。
root で普通に何かしたい時に、どうすれば可能ですか?
そしてどうすればこの問題を回避できますか?
ユーザ ID clientuser で X アプリケーションを起動したいが X セッションは
serveruser で起動されているという、一般的な状況にしましょう。クッキーの
セクションを読んでいれば、なぜ clientuser がディスプレイに
アクセスできないのか分かるはずです。
~clientuser/.Xauthority はディスプレイにアクセスするための
正しいマジッククッキーを含んでいません。正しいクッキーは
~serveruser/.Xauthority にあります。
もちろん、リモート X で動作するものは、異なるユーザ ID の X でも同じように
動作します (端的には slogin localhost -l clientuser )。
クライアントホストとサーバホストがたまたま同じだというだけです。しかし、
両方のホストが同じ時、マジッククッキーの転送には近道があります。
ユーザ ID の切り替えに su を使うと仮定します。
基本的に、行わなければならないことは、su を呼ぶスクリプトを書き、
そこで su の行うコマンドを、リモート X に必要な処理を行う
適切なコードでラップすることです。
必要な処理とは
DISPLAY 変数の設定とマジッククッキーの転送です。
DISPLAY の設定は比較的簡単です――su コマンドを実行する前に、
その引数として DISPLAY="$DISPLAY" を定義するだけです。
以下のようにします。
su - clientuser -c "env DISPLAY=$DISPLAY clientprogram &"
これだけでは動作しません。さらにクッキーの転送を行う必要があります。
クッキーの取得は xauth list "$DISPLAY" を使えば可能です。
このコマンドがクッキーのリストに用いる書式は、たまたま
xauth add コマンドに与える際の書式に合致しています
――ちょうど必要としていたものです。
当然パイプでクッキーを渡したいところです。残念ながら、su は
その標準入力からパスワードを読もうとするので、su コマンドにパイプで渡す
ことは簡単ではありません。ここでも都合のいいことには、
シェルスクリプトの内部では
ファイル記述子をいじり回すことができますので、これが可能になります。
clientuser と clientprogram をパラメータ化し汎用化したスクリプトを
書きます。読みやすさは少し犠牲にして頑強になるように、スクリプトを改善
しましょう。以下のようになります。
#!/bin/sh
if [ $# -lt 2 ]
then echo "usage: `basename $0` clientuser command" >&2
exit 2
fi
CLIENTUSER="$1"
shift
# FD 4 becomes stdin too
exec 4>&0
xauth list "$DISPLAY" | sed -e 's/^/add /' | {
# FD 3 becomes xauth output
# FD 0 becomes stdin again
# FD 4 is closed
exec 3>&0 0>&4 4>&-
exec su - "$CLIENTUSER" -c \
"xauth -q <&3
exec env DISPLAY='$DISPLAY' "'"$SHELL"'" -c '$*' 3>&-"
}
ほとんどの状況で、移植性と動作に十分だと考えます。
現在著者が考えうる欠点は、'$*' を使っているため、
command 内部でシングルクォートを用いると
su コマンドの引数 ('$*' ) が壊れてしまうことです。
もし他にもなにか深刻な間違いがあったら、著者に email を書き送って
ください。
スクリプトを /usr/local/bin/xsu とすれば
xsu clientuser 'command &'
とできます。
パスワードを使う限り、これ以上そう簡単にはできません。
ええ、(sudo ) を使う方法もありますね。でもここでは扱いません。
当然、root ではないクライアントユーザが root で動作することも同様にできます。
しかし、root はすべての人の ~/.Xauthority ファイルを読むことが
できるので、root の場合はより簡単です。クッキーを送る必要がありません。
DISPLAY 環境変数を設定し、XAUTHORITY が
~serveruser/.Xauthority を見るように設定するだけです。つまり:
su - -c "exec env DISPLAY='$DISPLAY' \
XAUTHORITY='${XAUTHORITY-$HOME/.Xauthority}' \
command"
これをスクリプト中に書くと以下のようになるでしょう。
#!/bin/sh
if [ $# -lt 1 ]
then echo "usage: `basename $0` command" >&2
exit 2
fi
su - -c "exec env DISPLAY='$DISPLAY' \
XAUTHORITY='${XAUTHORITY-$HOME/.Xauthority}' \
"'"$SHELL"'" -c '$*'"
スクリプトを /usr/local/bin/xroot とすれば
xroot 'control-panel &'
とできます。
でも、もし xsu をすでに設定してあれば、
このようにしなければならない理由はありません。
次のページ
前のページ
目次へ
|