Запуск приложения от другого пользователя
Предположим, что вам нужно запустить графическую утилиту конфигурации,
которая требует привилегий root. Тем не менее, ваш сеанс под X запущен от
обычного пользователя. Это может показаться странным, но X-сервер
не даст утилите доступа к вашему экрану. Как это может
быть возможным, если обычно root может делать все что угодно? И как мне
решить эту проблему?
Давайте обобщим ситуацию. Итак, вы хотите запустить X-клиент от другого
пользователя clientuser, а X-сервер запущен пользователем serveruser. Если
вы внимательно читали раздел, посвященный авторизационным записям, вам
ясно, почему clientuser не имеет доступа к дисплею:
˜clientuser/.Xauthority не содержит правильной авторизационной записи для
доступа к вашему дисплею. Правильная авторизационная запись находится в
˜clientuser/.Xauthority.
Разные пользователи на одной машине
Конечно, все что работает на удаленной машине, аналогично работает для
другого пользователя на той же машине. Просто клиент и сервер это одна и та
же машина. Тем не менее, в данном случае существует несколько кратчайших
путей передать авторизационную запись.
Допустим, что вы используете su для переключения между пользователями. То
есть все, что вы должны сделать, это написать скрипт, запускающий su с
командами, необходимыми для запуска X-клиента: установить переменную
DISPLAY и передать авторизационную запись.
Установить переменную DISPLAY сравнительно просто; надо определить
DISPLAY="$DISPLAY" перед запуском команды su. Итак, вы можете просто
сделать:
su - clientuser -c "env DISPLAY=$DISPLAY clientprogram &" |
Это пока не сработает, потому что мы все еще не передали авторизационную
запись. Мы можем извлечь запись при помощи команды xauth list "$DISPLAY".
Эта команда выдает список авторизационных записей в формате, в котором их
можно загрузить обратно в xauth; то что нам нужно! Так что нам осталось
передать авторизационную запись в xauth и установить переменную DISPLAY в
команде su.
su - clientuser -c "xauth add `xauth list $DISPLAY`; \
exec env DISPLAY=$DISPLAY clientprogram" |
Вы можете написать скрипт, похожий на этот, указав правильные clientuser и
clientprogram. Но давайте улучшим скрипт, сделав его менее удобочитаемым,
но более универсальным:
#!/bin/sh
if [ $# -lt 2 ]
then echo "usage: `basename $0` clientuser command" >&2
exit 2
fi
CLIENTUSER="$1"; shift
exec su - "$CLIENTUSER" -c "xauth add `xauth list \"$DISPLAY\"`; \
exec env DISPLAY='$DISPLAY' "'"$SHELL"'" -c '$*'" |
Я думаю, он достаточно универсален и работает для большинства случаев.
Единственный недостаток, который я могу найти прямо сейчас, это
использование одинарных кавычек вместе с двойными кавычками в аргументах
команды su ('$*'). Если это считается совершенно неправильным, напишите мне.
Назовите скрипт /usr/local/bin/xsu и попробуйте запустить его:
xsu clientuser 'command &' |
Просто, не правда ли?
Root-клиент
Очевидно, все, что работает для обычных пользователей, будет работать и для
root. Тем не менее, в случае с root вы можете сделать это даже проще, т.к.
root может прочитать чей угодно ˜/.Xauthority. Так что нет необходимости
передавать записи авторизации. Все, что вам нужно сделать, это установить
переменную 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 и пробуем запустить:
Еще проще, не правда ли?