¿Puedo iniciar un programa gráfico en el escritorio de otro usuario como root?

39

Las siguientes son otras preguntas que creo que necesito saber:

  • ¿De una sesión no X? (lo que significa que la raíz no está conectada a X)

  • Si varias personas iniciaran sesión en X, ¿podría detectar automáticamente quién estaba en qué pantalla y, por lo tanto, detectar mediante programación qué pantalla necesito para iniciar la aplicación?

  • ¿Puedo iniciar la aplicación como usuario? (ok, estoy 99.999% seguro de que esto es un sí)

  • ¿Puedo detectar si los usuarios del grupo X están conectados a X?

xenoterracida
fuente
Tenga cuidado de que el naga_plugged.plscript termine (o se bifurca en segundo plano), porque udevestará esperando a que salga.
rozcietrzewiacz
gracias Lo convertí en un demonio llamando a daemon (0,0) en el código c que naga_plugged.pl llama al último. Nunca supe que tenían foros de Unix aquí. Deben hacer que sea todo un sitio en lugar de los nuevos dominios.
over_optimistic

Respuestas:

23

Para iniciar un programa gráfico en el escritorio de un usuario, debe encontrar dos cosas: en qué pantalla se encuentra el escritorio del usuario (la dirección) y qué cookie de autorización usar (la contraseña).

El siguiente comando debe enumerar las pantallas locales en las que el usuario ha iniciado sesión (una por línea) en la mayoría de los dispositivos:

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

Encontrar la cookie de autorización es un poco más difícil. Debe buscar el archivo de cookies del usuario, que es el ~/.Xauthoritypredeterminado (todo lo que necesita es la ubicación del archivo de cookies, no necesita extraer la cookie de él). Eso funciona en muchos sistemas, pero no en todos; depende del administrador de pantalla y de cómo está configurado, y en particular Gdm (el predeterminado en Ubuntu) no usó la ubicación predeterminada la última vez que busqué. No puedo pensar en una forma portátil de descubrir el archivo de cookies X real. La forma más precisa de averiguarlo es averiguar el pid del proceso X y buscar el argumento de la -authopción. Otra forma es encontrar un proceso que se ejecute en ese servidor X y tomar su XAUTHORITYvariable de entorno. Si tiene problemas para encontrar el archivo cookie, veaAbrir una ventana en una pantalla X remota (¿por qué "No se puede abrir la pantalla")?

Una vez que tenga ambas piezas de información, coloque la pantalla elegida en la DISPLAYvariable de entorno, el archivo de cookie de autoridad X elegido en la XAUTHORITYvariable de entorno, y estará listo. No importa a qué usuario se ejecuta el programa; combina con susi quieres.

Gilles 'SO- deja de ser malvado'
fuente
¿Cómo "buscas el argumento de la opción -auth"?
rubo77
@ rubo77 Con pso htopo ...
Gilles 'SO- deja de ser malvado'
De acuerdo, entonces pids=$(pgrep -u $target_user nautilus)obtiene el pid, y ¿dónde tengo que poner una -authopción?
rubo77
1
@ rubo77 No pone una -authopción en ningún lado. Es posible que deba buscarlo en la línea de comandos del proceso del servidor X para averiguar qué poner en la XAUTHORITYvariable de entorno. Si tiene el proceso de un cliente, lo que necesita no es nada -authmás que el valor de la XAUTHORITYvariable de ese cliente . No entiendo lo que intentas hacer. Es posible que desee hacer una nueva pregunta.
Gilles 'SO- deja de ser malvado'
Intento usar su información aquí para resolver cómo Crear una notificación en la pantalla iniciada por root
rubo77
11

No puedo probar esto por completo ya que todas mis máquinas tienen la raíz deshabilitada.

Para encontrar en qué pantalla está un usuario, puede usar el whocomando. La última columna de salida suele ser la PANTALLA en la que el usuario ha iniciado sesión. Algo como esto podría usarse para capturar solo la pantalla (es probable que haya una forma mucho más eficiente de hacer esto, no dude en ofrecer ediciones):

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

Luego, para iniciar un comando gráfico X en esa pantalla:

DISPLAY=:0 firefox &

donde: 0 se reemplazaría con la pantalla que encontraste en el primer comando y firefox se reemplazaría con el comando que quieras ejecutar. Podría poner esto en un script de shell y simplemente usar una variable.

La siguiente parte es la parte que no he probado, pero no veo por qué no debería ser posible hacerlo:

su username -c "DISPLAY=:0 firefox"

para iniciar el comando X como ese usuario.

Steven D
fuente
1
El hecho de que la raíz esté deshabilitada no significa que las cosas no se ejecuten como raíz;) De hecho, necesito ejecutar esto como un script que se ejecuta como raíz.
xenoterracide
@xenoterracide, a la derecha. Todo lo que quería decir era que no podía probarlo en todas las circunstancias posibles. Es decir, solo lo probé como root usando sudo -iy no podía estar seguro de si los resultados serían diferentes de ejecutarlo después de iniciar sesión directamente como root. :-)
Steven D
Tuve que modificar un poco a quién. Esto who | grep xeno| awk '{print $5}' | sed 's/[(|)]//g' | grep -v ^$ parece funcionar ...
xenoterracide
por qué alguien usa grep and sed cuando ya hay un awk en la cadena está más allá de mí.
sí ... "learn awk" ha estado en mi lista de tareas por un tiempo.
Steven D
4

Podrías ver cómo lo hace acpid. Por ejemplo, cuando emite comandos xscreensaver o deja en blanco la pantalla para cada usuario que ejecuta X o X-session.

Por ejemplo, en Ubuntu, este archivo contiene cosas relacionadas:

/etc/acpi/lid.sh

Contiene este bucle:

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
maxschlepzig
fuente
Específicamente, el código está en /usr/share/acpi-support/power-funcs. Llama fgconsolepara encontrar el vt de Linux activo, luego busca un servidor X que se muestre en esta consola y descubre al usuario desde allí. Luego se usa ~/.Xauthoritycomo la cookie X, que a menos que haya algo que me falta, significa que en realidad no podrá conectarse al servidor X (la configuración predeterminada de Ubuntu, usando gdm, no almacena las cookies X en el hogar del usuario directorio).
Gilles 'SO- deja de ser malvado'
@Gilles lid.sh, por ejemplo, no llama a getXconsole. Por lo tanto, fgconsole no se utiliza. Actualicé la respuesta con el fragmento que tenía en mente. Y en realidad funciona en Ubuntu. La pantalla queda en blanco cuando cierro la tapa.
maxschlepzig
1
En ubuntu 14.04 me sale el errorgetXuser: command not found
rubo77
1

Una extensión de la respuesta de Gilles es cómo encontrar el archivo cookie. Una forma de hacerlo puede ser después de configurar la DISPLAYvariable de entorno (como lo describe Gilles), usar stracepara encontrar el xhostacceso a los archivos . Puedo pensar en algo así en BASH:

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

El resultado del código anterior se verá así:

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

Como puede ver claramente, el archivo de cookies aparecerá directamente aquí.

Bichoy
fuente
0

En mi investigación para encontrar una forma elegante de mostrar la GUI o la tarea X desde un entorno limitado, como las reglas de udev o del superusuario, recientemente creé una herramienta para encajar con ella ( para más detalles ).

xpub es un script de shell para obtener las variables del entorno de visualización X con respecto al TTY actual o dado.

Este es un ejemplo con una regla udev:

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

$env{ENV}: si current-tty-user inicia X, de lo contrario, elimínelo.

El principio es el mismo para una línea de comandos que utiliza export:

export $(xpub) ; su ${XUSER} -c 'notify-send Hello'
Thomas Venries
fuente
1
Le sugiero que deje en claro que usted es el autor de este script xpub.
Dmitry Grigoryev