Предположим, что вам нужно запустить графическую утилиту конфигурации, которая требует привилегий 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 может прочитать чей угодно ˜/.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 и пробуем запустить:
xroot 'control-panel &' |
Еще проще, не правда ли?