Estou tentando descobrir como iniciar um aplicativo GUI como outro usuário conectado interativamente, na sessão gráfica do usuário.
Por exemplo, digamos que eu tenha dois usuários, foo e bar. Ambos estão conectados, mas o usuário interativo atual é foo. Gostaria de iniciar o Calculator.app como usuário "bar", para que, quando eu mudo rapidamente para o bar, descubro que a janela Calculadora está aberta na sessão do bar.
Aqui está o que eu tentei que não funciona:
sudo -u bar /Applications/Calculator.app/Contents/MacOS/Calculator
Isso inicia o Calculator.app como barra, mas a janela é aberta na sessão gráfica do foo.
sudo -u bar osascript -e "tell application \"Calculator\" to activate"
O mesmo efeito.
sudo -u bar open "/Applications/Calculator.app"
Inicia a Calculadora como foo, não como barra.
launchctl asuser [uid of bar] [any of the above commands]
O mesmo efeito.
Existe alguma maneira de conseguir isso? Estou disposto a oferecer todo tipo de solução possível, incluindo scripts de bash, AppleScript, criação de um programa Core Foundation ou Cocoa e assim por diante. Na minha situação, qualquer programa ou script pode ser executado como qualquer usuário, incluindo o root.
Nota: Estou ciente de que é possível usar o Apple Events remoto, mas não posso usá-lo, pois, na situação em que estou tentando fazer isso, não tenho garantia de que o "Apple Remote Events" será ativado nas preferências de compartilhamento.
Qualquer ajuda seria muito apreciada!
fonte
open
comando usandoSSH
?Respostas:
O que você deseja alcançar é possível, mas difícil. Você precisa iniciar o aplicativo dentro da sessão de usuário apropriada. Por motivos de segurança, é difícil atravessar a divisão da sessão do usuário.
Você precisa de um processo já em execução na sessão do outro usuário para ouvir sua solicitação e iniciar o aplicativo em seu nome.
bsexec do launchd
Felizmente, versões recentes de
launchd
têm essa capacidade; embora os engenheiros da Apple não tenham recomendado seu uso geral. Use absexec
opção no launchctl para direcionar a sessão de usuário apropriada:A abordagem recomendada é escrever um tíquete de trabalho iniciado e reiniciar o Mac - ou solicitar ao usuário que efetue logout e logon novamente.
Causa dos problemas
Os problemas decorrem da conexão do aplicativo ao
WindowServer
processo errado . Cada sessão do usuário possui um WindowServer separado; esse processo lida com a interface do usuário. Seus métodos anteriores colocam a propriedade do processo com o usuário certo, mas conectado ao seu próprio processo WindowServer.Esse problema é mencionado na nota técnica de Daemons and Agents da Apple.
Experiência
Sei disso por experiência pessoal. Para o Power Manager, escrevi pmuser para existir em cada sessão do usuário.
pmuser
ouve nosso daemon e lida com os lançamentos e comandos por usuário. Apesar de nosso daemon ter autoridade root, ainda precisamos de um processo por usuário para trabalhar de maneira confiável nas sessões do usuário.fonte
Nenhuma das respostas bsexec acima funciona no El Capitan (10.11), devido ao SIP (System Integration Protection) fechar as portas. O "launchctl asuser" funciona, mas precisa ser executado como root. O comando abaixo funciona no El Capitan (e nos SO mais recentes):
Observe que 501 é o ID do usuário para meu outro usuário.
fonte
bruno.medeiros@brunojcm-macbook:~ $ sudo launchctl asuser 501 open /Applications/Firefox.app
LSOpenURLsWithRole() failed with error -600 for the file /Applications/Firefox.app
sudo launchctl asuser $(id -u <user_id_name>) <app>
. Dito isto, eu recebo um erro diferente doposix_spawn(): 13: Permission denied
mesmo se eu correr com o mesmo ID de usuário que eu estou logado com (e possui a sessão) parasudo launchctl asuser $(id -u mtylutki) /Applications/Calculator.app
Como finalmente a 10.10 fornece uma implementação "launchctl bsexec" correta, você pode usar:
homem diz
Portanto, como parâmetro PID, você pode usar o pid do processo de janela de login apropriado . O UID é o ID do usuário que possui a janela de login e o GID é o grupo principal.
Isso funciona bem para qualquer comando e, é claro, para tarefas launchd (fe launchchagents), também como finalmente:
fonte
task_for_pid(): 0x5
erro para isso, onde verifiquei se o PID está correto.Você pode usar o Finder como host para as permissões corretas
osascript -e "tell application \"Finder\" to open (\"${app}\" as POSIX file as alias)"
. Dessa forma, ele será iniciado por qualquer contexto da GUI que lançou o Finder.fonte
Isso funciona via ssh:
mas se tentar pelo Terminal.app, ele abrirá o TextEdit na GUI do usuário atual.
Se não tiver certeza de que
ssh
está ativado, talvez você possa habilitá-lo temporariamentee desativá-lo novamente depois, se necessário?
Caso contrário, estou perplexo.
Testado em 10.9.
fonte
Simples
depois execute os comandos normalmente.
fonte
bar
, mas ainda seriam executados nafoo
sessão gráfica da sessão.