Page suivante Page précédente Table des matières

7. Les applications X avec un identificateur d'utilisateur (User-id) différent

Supposez que vous vouliez faire tourner un outil graphique de configuration qui nécessite d'avoir les privilèges du compte root alors que la session X actuelle se déroule sous votre compte. Cela peut sembler étrange au premier abord, mais le serveur X ne permettra pas à cet outil d'accéder à votre unité d'affichage. Comment cela est-il possible alors que root peut normalement tout faire ? Et comment contourner ce problème ?

Élargissons le propos au cas où l'on veut faire tourner une application X, sous un identificateur d'utilisateur clientuser, alors que la session X a été lancée par serveruser. Si vous avez lu le paragraphe sur les cookies, il est évident que clientuser ne peut pas accéder à votre unité d'affichage : ~clientuser/.Xauthority ne contient le cookie magique qui permet d'accéder à l'unité d'affichage. Le cookie correct se trouve dans ~serveruser/.Xauthority.

7.1 Plusieurs utilisateurs sur le même hôte

Naturellement, tout ce qui marche pour un X distant marchera aussi pour un X à partir d'un identificateur d'utilisateur différent (particulièrement slogin localhost -l clientuser). Et ici l'hôte client et l'hôte serveur sont précisément les mêmes. Cependant, quand les deux hôtes sont les mêmes, il y a quelques raccourcis pour transférer le cookie magique.

On supposera que l'on utilise su pour passer d'un identificateur utilisateur à l'autre. Essentiellement, il faut écrire un script qui appelle su, mais enveloppe la commande que su exécute d'un peu de code qui effectue les tâches nécessaires pour le X distant. Ces tâches nécessaires sont l'initialisation de la variable DISPLAY et le transfert du cookie magique.

L'initialisation de DISPLAY est relativement facile ; il faut simplement définir DISPLAY="$DISPLAY" avant d'exécuter l'argument de la commande su. Donc, il faut simplement faire :

su - clientuser -c "env DISPLAY="$DISPLAY" clientprogram &"

Ce n'est pas tout, il faut encore transférer le cookie. On peut le retrouver en utilisant xauth list "$DISPLAY". Cette commande renvoie le cookie dans un format qui convient pour le mettre dans xauth; ce dont nous avons justement besoin ! Donc, on met le cookie obtenu dans xauth dans le commande su, on initialise DISPLAY ici, et on lance la commande désirée

su - clientuser -c "xauth add `xauth list $DISPLAY`; \
                    exec env DISPLAY=$DISPLAY clientprogram"

On peut écrire un script pour réaliser tout cela, en le paramètrant avec clientuser et clientprogram. Améliorons un peu le script pendant que nous y sommes, ça va le rendre un peu moins compréhensible mais un peu plus robuste. Le tout ressemble à cela :

#!/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 '$*'"

Je pense que c'est portable et que cela fonctionne suffisamment correctement dans la plupart des circonstances. Le seul défaut auquel je pense en ce moment est dû à l'utilisation de '$*', les guillemets simples dans command vont perturber les guillemets de l'argument('$*') de la commande su. Si cela entraîne quelque chose de vraiment gênant, envoyez-moi un courrier électronique.

Nommez le script /usr/local/bin/xsu, et vous pouvez faire :

xsu clientuser 'command &'

Facile, non ?

7.2 Root est l'utilisateur client

Évidemment, tout ce qui marche pour un client non root doit fonctionner pour root. Cependant, avec root vous pouvez faire cela encore plus facilement, car celui-ci peut lire le fichier ~/.Xauthority de tout le monde. Il n'y a pas besoin de transférer le cookie. Tout ce qu'il y a à faire consiste à initialiser DISPLAY, et à faire pointer XAUTHORITY sur ~serveruser/.Xauthority. Donc, vous pouvez écrire :

su - -c "exec env DISPLAY='$DISPLAY' \
                  XAUTHORITY='${XAUTHORITY-$HOME/.Xauthority}' \
                  command"

Et, en mettant cela dans un script, cela donne quelque chose comme 

#!/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 '$*'"

Nommez le script /usr/local/bin/xroot, et vous pouvez faire :

xroot 'control-panel &'

Encore plus facile, non ??


Page suivante Page précédente Table des matières