Puis-je lancer un programme graphique sur le bureau d'un autre utilisateur en tant que root?


39

Voici d'autres questions que je pense avoir besoin de savoir:

  • D'une session non-X? (signifiant que la racine n'est pas connectée à X)

  • Si plusieurs personnes étaient connectées à X, puis-je détecter automatiquement qui se trouvait sur quel écran et donc, par programme, sur quel écran je dois lancer l'application?

  • Puis-je lancer l'application en tant qu'utilisateur? (ok je suis sûr à 99,999% que c'est un oui)

  • Puis-je détecter si les utilisateurs du groupe X sont connectés à X?


Veillez à ce que le naga_plugged.plscript se termine (ou se place en arrière-plan), car udevil attendra sa sortie.
rozcietrzewiacz

merci j'en ai fait un démon en appelant daemon (0,0) dans le code c que naga_plugged.pl appelle en dernier. Je n'ai jamais nouveau, ils avaient des forums Unix ici. Ils devraient en faire un seul site au lieu des nouveaux domaines.
over_optimistic

Réponses:


23

Pour lancer un programme graphique sur le bureau d'un utilisateur, vous devez rechercher deux éléments: l'affichage du bureau de l'utilisateur (l'adresse) et le cookie d'autorisation à utiliser (le mot de passe).

La commande suivante doit répertorier les affichages locaux sur lesquels l'utilisateur est connecté (un par ligne) sur la plupart des ordinateurs de bureau:

who | awk -v user="$target_user" '$1 == user && $2 ~ "^:" {print $2}'

Trouver le cookie d'autorisation est un peu plus difficile. Vous devez rechercher le fichier de cookie de l'utilisateur, qui est ~/.Xauthoritypar défaut (tout ce dont vous avez besoin est l'emplacement du fichier de cookie, vous n'avez pas besoin d'en extraire le cookie). Cela fonctionne sur de nombreux systèmes, mais pas tous; cela dépend du gestionnaire d'affichage et de la façon dont il est configuré, et en particulier Gdm (le paramètre par défaut sur Ubuntu) n'a pas utilisé l'emplacement par défaut que j'ai consulté en dernier. Je n'arrive pas à trouver un moyen portable de trouver le fichier de cookie X réel. Le moyen le plus précis de découvrir est de connaître le pid du processus X et de rechercher l'argument de l' -authoption. Une autre méthode consiste à rechercher un processus s'exécutant sur ce serveur X et à récupérer sa XAUTHORITYvariable d'environnement. Si vous ne parvenez pas à trouver le fichier cookie, voirOuvrir une fenêtre sur un affichage X distant (pourquoi "Impossible d'ouvrir l'affichage")?

Une fois que vous avez les deux informations, placez l'affichage choisi dans la DISPLAYvariable d'environnement, le fichier de cookie d'autorité X choisi dans la XAUTHORITYvariable d'environnement, et le tour est joué. Peu importe l'utilisateur du programme. combinez avec susi vous aimez.


Comment votre "recherche l'argument de l'option -auth"?
rubo77

@ rubo77 Avec psou htopou…
Gilles 'SO- arrête d'être méchant'

OK, pids=$(pgrep -u $target_user nautilus)obtient le pid, et où dois-je mettre une -authoption?
rubo77

1
@ rubo77 Vous ne mettez aucune -authoption nulle part. Vous devrez peut-être le rechercher dans la ligne de commande du processus du serveur X pour déterminer ce qu'il faut mettre dans la XAUTHORITYvariable d'environnement. Si vous avez le processus d'un client, ce dont vous avez besoin n'est pas autre chose -authque la valeur de la XAUTHORITYvariable de ce client . Je ne comprends pas ce que vous essayez de faire. Vous voudrez peut-être poser une nouvelle question.
Gilles 'SO- arrête d'être méchant'

J'essaie d'utiliser vos informations ici pour résoudre le problème de la création d'une notification à l'écran initiée par root
rubo77

11

Je ne peux pas essayer cela complètement car toutes mes machines ont la racine désactivée.

Pour rechercher l'affichage d'un utilisateur, vous pouvez utiliser la whocommande. La dernière colonne de sortie est généralement l’AFFICHAGE auquel l’utilisateur est connecté. Quelque chose comme cela pourrait être utilisé pour ne saisir que l'écran (il existe probablement un moyen beaucoup plus efficace de le faire, n'hésitez pas à proposer des modifications):

who | grep -m1 ^username.*\( | awk '{print $5}' | sed 's/[(|)]//g'

Ensuite, pour lancer une commande graphique X sur cet affichage:

DISPLAY=:0 firefox &

où: 0 serait remplacé par tout ce que vous auriez trouvé dans la première commande et firefox serait remplacé par la commande que vous voulez exécuter. Vous pouvez mettre cela dans un script shell et simplement utiliser une variable.

La partie suivante est la partie que je n'ai pas testée, mais je ne vois pas pourquoi cela ne devrait pas être possible:

su username -c "DISPLAY=:0 firefox"

pour lancer la commande X en tant qu’utilisateur.


1
Ce n'est pas parce que root est désactivé que les choses ne sont pas exécutées en tant que root;) J'ai besoin de l'exécuter en tant que script exécuté en tant que root.
xenoterracide

@xenoterracide, à droite. Tout ce que je voulais dire, c'est que je ne pouvais pas le tester dans toutes les circonstances possibles. C'est-à-dire que je ne l'ai testé qu'en tant qu'utilisateur root sudo -iet je ne pouvais pas être sûr que les résultats seraient différents de leur exécution après la connexion directe en tant qu'utilisateur root. :-)
Steven D

Je devais modifier le qui un peu. Cela who | grep xeno| awk '{print $5}' | sed 's/[(|)]//g' | grep -v ^$ semble fonctionner ...
xenoterracide

pourquoi quiconque utilise grep et sed alors qu'il y a déjà un awk dans la chaîne me dépasse.

oui ... "learn awk" est sur ma liste de tâches depuis un moment maintenant.
Steven D

4

Vous pourriez regarder comment acpid le fait. Par exemple, lorsqu’il émet des commandes xscreensaver ou vide l’écran pour chaque utilisateur exécutant X ou X-session.

Par exemple, sous Ubuntu, ce fichier contient des éléments connexes:

/etc/acpi/lid.sh

Contient cette boucle:

for x in /tmp/.X11-unix/*; do
    displaynum=`echo $x | sed s#/tmp/.X11-unix/X##`
    getXuser;
    if [ x"$XAUTHORITY" != x"" ]; then
        export DISPLAY=":$displaynum"
        grep -q off-line /proc/acpi/ac_adapter/*/state
        if [ $? = 1 ]
            then
            if pidof xscreensaver > /dev/null; then 
                su $user -c "xscreensaver-command -unthrottle"
            fi
        fi
        if [ x$RADEON_LIGHT = xtrue ]; then
            [ -x /usr/sbin/radeontool ] && radeontool light on
        fi
        if [ `pidof xscreensaver` ]; then
            su $user -c "xscreensaver-command -deactivate"
        fi
        su $user -c "xset dpms force on"
    fi
done

Plus précisément, le code est dans /usr/share/acpi-support/power-funcs. Il appelle fgconsolepour rechercher le vt Linux actif, puis recherche un serveur X à afficher sur cette console et recherche l'utilisateur à partir de là. Ensuite, il utilise ~/.Xauthorityle cookie X, ce qui signifie qu'il ne pourra pas se connecter au serveur X (à moins que quelque chose ne me manque annuaire).
Gilles 'SO- arrête d'être méchant'

@Gilles lid.sh, par exemple, n’appelle pas getXconsole. Ainsi, fgconsole n'est pas utilisé. J'ai mis à jour la réponse avec l'extrait de code que j'avais en tête. Et cela fonctionne réellement sur Ubuntu. L'écran est masqué lorsque je ferme le couvercle.
maxschlepzig

1
Dans ubuntu 14.04, je reçois l'erreurgetXuser: command not found
rubo77

1

Une extension de Gilles pour répondre est comment trouver le fichier cookie. Une façon de le faire peut être après avoir défini la DISPLAYvariable d'environnement (comme décrit par Gilles), utilisée stracepour trouver l' xhostaccès aux fichiers . Je peux penser à quelque chose comme ça dans BASH:

# Set the DISPLAY variable first
DISPLAY = :0.0
# Use strace on xhost
strace xhost 2>&1 | grep access

La sortie du code ci-dessus ressemblera à:

access("/etc/ld.so.preload", R_OK)      = -1 ENOENT (No such file or directory)
access("/home/someuser/.Xauthority", R_OK) = 0

Comme vous pouvez le voir clairement, le fichier cookie apparaîtra directement ici.


0

Dans mes recherches pour trouver un moyen élégant d'afficher une tâche graphique ou X à partir d'environnements limités, tels que les règles udev ou le super-utilisateur, j'ai récemment créé un outil qui s'y adapterait ( pour plus de détails ).

xpub est un script shell permettant d'obtenir les variables de l'environnement d'affichage X concernant le TTY actuel ou donné.

Voici un exemple avec une règle udev:

IMPORT{program}="/usr/bin/xpub", \
RUN+="/bin/su $env{XUSER} -c '/usr/bin/notify-send Hello'"

$env{ENV}: si l'utilisateur en cours lance X, sinon le supprime.

Le principe est le même pour une ligne de commande utilisant export:

export $(xpub) ; su ${XUSER} -c 'notify-send Hello'

1
Je vous suggère de préciser que vous êtes l'auteur de ce script xpub.
Dmitry Grigoryev
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.