Posso iniciar um programa gráfico na área de trabalho de outro usuário como root?

39

A seguir estão outras perguntas que acho que preciso saber:

  • De uma sessão não X? (o que significa que o root não está logado no X)

  • Se várias pessoas estivessem logadas no X, eu poderia detectar automaticamente quem estava em qual tela e, assim, detectar programaticamente em qual tela preciso iniciar o aplicativo?

  • Posso iniciar o aplicativo como usuário? (ok, tenho 99,999% de certeza de que isso é um sim)

  • Posso detectar se os usuários do grupo X estão conectados ao X?

xenoterracida
fonte
Tome cuidado para que o naga_plugged.plscript termine (ou bifurque-se em segundo plano), pois udevestará aguardando sua saída.
rozcietrzewiacz
obrigado, eu criei um daemon chamando daemon (0,0) no código c que naga_plugged.pl chama por último. Eu nunca soube que eles tinham fóruns unix aqui. Eles devem fazer com que tudo seja um site em vez dos novos domínios.
over_optimistic

Respostas:

23

Para iniciar um programa gráfico na área de trabalho de um usuário, você precisa encontrar duas coisas: qual tela a área de trabalho do usuário está (o endereço) e qual cookie de autorização usar (a senha).

O comando a seguir deve listar as exibições locais nas quais o usuário está conectado (um por linha) na maioria das unidades:

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

Encontrar o cookie de autorização é um pouco mais difícil. Você precisa procurar o arquivo de cookies do usuário, que é o ~/.Xauthoritypadrão (tudo o que você precisa é o local do arquivo de cookies, não é necessário extrair o cookie). Isso funciona em muitos sistemas, mas não em todos; depende do gerenciador de exibição e de como é configurado, e em particular o Gdm (o padrão no Ubuntu) não usou o local padrão pela última vez que olhei. Não consigo pensar em uma maneira portátil de descobrir o arquivo de cookie X real. A maneira mais precisa de descobrir é descobrir o detalhe do processo X e procurar o argumento para a -authopção. Outra maneira é encontrar um processo em execução no servidor X e pegar sua XAUTHORITYvariável environmentemnt. Se você tiver problemas para encontrar o arquivo de cookie, consulteAbrir uma janela em um monitor X remoto (por que "Não é possível abrir o monitor")?

Depois de ter as duas informações, coloque a exibição escolhida na DISPLAYvariável de ambiente, o arquivo de cookie da autoridade X escolhido na XAUTHORITYvariável de ambiente e você estará definido. Não importa em qual usuário o programa é executado; combine com suse quiser.

Gilles 'SO- parar de ser mau'
fonte
Como você "procura o argumento para a opção -auth"?
rubo77
@ rubo77 Com psou htopou…
Gilles 'SO- stop
OK, então pids=$(pgrep -u $target_user nautilus)recebe o pid, e onde eu tenho que colocar uma -authopção?
rubo77
11
@ rubo77 Você não coloca uma -authopção em lugar algum. Pode ser necessário procurá-lo na linha de comando do processo do servidor X para descobrir o que colocar na XAUTHORITYvariável de ambiente. Se você possui o processo de um cliente, o que você precisa não é nada, -authmas o valor da XAUTHORITYvariável desse cliente . Não entendo o que você está tentando fazer. Você pode fazer uma nova pergunta.
Gilles 'SO- stop be evil'
Eu tento usar a sua informação aqui para resolver como Criar uma notificação na tela iniciada pela raiz
rubo77
11

Não posso tentar isso completamente, pois todas as minhas máquinas têm o root desativado.

Para descobrir em qual tela um usuário está, você pode usar o whocomando A última coluna de saída é geralmente o DISPLAY no qual o usuário está conectado. Algo assim pode ser usado para capturar apenas a tela (provavelmente existe uma maneira muito mais eficiente de fazer isso, fique à vontade para oferecer edições):

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

Em seguida, para lançar um comando gráfico X nessa exibição:

DISPLAY=:0 firefox &

onde: 0 seria substituído por qualquer exibição que você encontrasse no primeiro comando e o firefox seria substituído pelo comando que você deseja executar. Você pode colocar isso em um script de shell e apenas usar uma variável.

A próxima parte é a parte que não testei, mas não vejo por que não deveria ser possível:

su username -c "DISPLAY=:0 firefox"

para iniciar o comando X como esse usuário.

Steven D
fonte
11
Só porque o root está desabilitado não significa que as coisas não são executadas como root;) Na verdade, eu preciso executar isso como um script que esteja sendo executado como root.
Xenoterracide
@xenoterracide, certo. Tudo o que eu quis dizer foi que não podia testá-lo em todas as circunstâncias possíveis. Ou seja, eu apenas testei como root usando sudo -ie não podia ter certeza se os resultados seriam diferentes do que executá-lo depois de efetuar o login como root diretamente. :-)
Steven D
Eu tive que modificar um pouco quem. Isso who | grep xeno| awk '{print $5}' | sed 's/[(|)]//g' | grep -v ^$ parece funcionar ...
xenoterracide
por que alguém usa grep e sed quando já existe awk na cadeia está além de mim.
sim ... "learn awk" está na minha lista de tarefas há um tempo.
Steven D
4

Você pode ver como isso é acido. Por exemplo, quando emite comandos xscreensaver ou apaga a tela para cada usuário que executa a sessão X ou X.

Por exemplo, no Ubuntu, este arquivo contém itens relacionados:

/etc/acpi/lid.sh

Contém este loop:

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
fonte
Especificamente, o código é em /usr/share/acpi-support/power-funcs. Ele chama fgconsolepara encontrar o Linux vt ativo, depois procura um servidor X exibido nesse console e descobre o usuário a partir daí. Em seguida, ele é usado ~/.Xauthoritycomo o cookie X, que, a menos que haja algo que esteja faltando, significa que ele não poderá realmente se conectar ao servidor X (a configuração padrão do Ubuntu, usando gdm, não armazena os cookies X na casa do usuário diretório).
Gilles 'SO- stop be evil'
@Gilles lid.sh, por exemplo, não chama getXconsole. Portanto, fgconsole não é usado. Atualizei a resposta com o trecho em mente. E realmente funciona no Ubuntu. A tela fica em branco quando fecho a tampa.
maxschlepzig 5/09/10
11
No ubuntu 14.04 eu recebo o errogetXuser: command not found
rubo77 16/10
1

Uma extensão da resposta de Gilles é como encontrar o arquivo de cookie. Uma maneira de fazer isso pode ser depois que você definir a DISPLAYvariável de ambiente (conforme descrito por Gilles), use stracepara encontrar o xhostacesso aos arquivos . Eu posso pensar em algo assim no BASH:

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

A saída do código acima será semelhante a:

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

Como você pode ver claramente, o arquivo de cookie aparecerá diretamente aqui.

Bichoy
fonte
0

Em minha pesquisa para encontrar uma maneira elegante de exibir tarefas da GUI ou X em ambientes limitados, como regras do udev ou do superusuário, criei recentemente uma ferramenta para se ajustar a ela ( para obter mais detalhes ).

xpub é um script de shell para obter as variáveis ​​do ambiente de exibição do X em relação ao atual ou a um determinado TTY.

Este é um exemplo com uma regra do udev:

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

$env{ENV}: se o usuário-tty atual iniciar o X, remova-o.

O princípio é o mesmo para uma linha de comando usando export:

export $(xpub) ; su ${XUSER} -c 'notify-send Hello'
Thomas Venries
fonte
11
Eu sugiro que você deixe claro que você é o autor desse script xpub.
Dmitry Grigoryev