Comment lancer une application GUI dans une session graphique d'un autre utilisateur?

15

J'essaie de comprendre comment lancer une application GUI en tant qu'un autre utilisateur connecté de manière interactive, dans la session graphique de cet utilisateur.

Par exemple, disons que j'ai deux utilisateurs, foo et bar. Les deux sont connectés, mais l'utilisateur interactif actuel est foo. Je voudrais lancer Calculator.app en tant que "barre" de l'utilisateur, de sorte que lorsque je passe rapidement de l'utilisateur à la barre, je trouve que la fenêtre de la calculatrice est ouverte dans la session de la barre.

Voici ce que j'ai essayé qui ne fonctionne pas:

sudo -u bar /Applications/Calculator.app/Contents/MacOS/Calculator

Cela lance Calculator.app sous forme de barre, mais la fenêtre s'ouvre dans la session graphique de foo.

sudo -u bar osascript -e "tell application \"Calculator\" to activate"

Même effet.

sudo -u bar open "/Applications/Calculator.app"

Lance la calculatrice comme foo, pas bar.

launchctl asuser [uid of bar] [any of the above commands]

Même effet.

Existe-t-il un moyen d'y parvenir? Je suis prêt à envisager toutes sortes de solutions possibles, y compris les scripts bash, AppleScript, l'écriture d'un programme Core Foundation ou Cocoa, etc. Dans ma situation, n'importe quel programme ou script peut s'exécuter comme n'importe quel utilisateur, y compris root.

Remarque: je suis conscient qu'il est possible d'utiliser des événements Apple distants, mais je ne peux pas l'utiliser car dans la situation où j'essaie de le faire, je n'ai aucune garantie que les "événements Apple distants" seront activés dans les préférences de partage.

Toute aide serait grandement appréciée!

GuyGizmo
la source
1
Avez-vous essayé la opencommande en utilisant SSH?
Matthieu Riegler
Curieusement, l'icône du dock de l'application apparaît dans la session de foo, mais la fenêtre de l'application apparaît dans la barre. Cela ne semble donc pas fonctionner, mais c'est une bonne suggestion. Malheureusement, il n'y a aucune garantie que la connexion sécurisée est activée dans la situation dont j'ai besoin, qui concerne un installateur.
GuyGizmo
Je pense qu'une pièce de ce puzzle pourrait impliquer l'argument de ligne de commande -psn, que le système d'exploitation ajoute dans certaines situations. J'ai rencontré cela dans le passé lorsque je travaillais sur le portage de code vers OS X. Voir cette question et la documentation Apple qu'elle référence.
Ashley
à partir de 10h10 enfin le bsexec mentionné ci-dessous fonctionne parfaitement
Hofi

Réponses:

7

Ce que vous voulez réaliser est possible mais difficile. Vous devez lancer l'application dans la session utilisateur appropriée. Pour des raisons de sécurité, il est difficile de franchir le fossé de session utilisateur.

Vous avez besoin d'un processus déjà en cours d'exécution dans la session de l'autre utilisateur pour écouter votre demande et lancer l'application en votre nom.

Launchd's Bsexec

Heureusement, les versions récentes de launchdont cette capacité; bien que les ingénieurs d'Apple n'aient pas recommandé son utilisation générale. Utilisez l' bsexecoption dans launchctl pour cibler la session utilisateur appropriée:

 bslist [PID | ..] [-j]
          This prints out Mach bootstrap services and their respective states. While the namespace
          appears flat, it is in fact hierarchical, thus allowing for certain services to be only avail-
          able to a subset of processes. The three states a service can be in are active ("A"), inactive
          ("I") and on-demand ("D").

          If [PID] is specified, print the Mach bootstrap services available to that PID. If [..] is
          specified, print the Mach bootstrap services available in the parent of the current bootstrap.
          Note that in Mac OS X v10.6, the per-user Mach bootstrap namespace is flat, so you will only
          see a different set of services in a per-user bootstrap if you are in an explicitly-created
          bootstrap subset.

          If [-j] is specified, each service name will be followed by the name of the job which regis-
          tered it.

 bsexec PID command [args]
          This executes the given command in the same Mach bootstrap namespace hierachy as the given
          PID.

 bstree [-j]
          This prints a hierarchical view of the entire Mach bootstrap tree. If [-j] is specified, each
          service name will be followed by the name of the job which registered it.  Requires root priv-
          ileges.

L'approche recommandée consiste à écrire un ticket de travail launchd et à redémarrer le Mac - ou à demander à l'utilisateur de se déconnecter et de se reconnecter.

Cause des problèmes

Les problèmes proviennent du fait que l'application est connectée au mauvais WindowServerprocessus. Chaque session utilisateur a un WindowServer distinct; ce processus gère l'interface utilisateur. Vos méthodes antérieures placent la propriété du processus avec le bon utilisateur mais connecté à votre propre processus WindowServer.

Ce problème est mentionné dans la note technique sur les démons et les agents d'Apple.

Expérience

Je le sais par expérience personnelle. Pour Power Manager, j'ai écrit pmuser pour exister dans chaque session utilisateur. pmuserécoute notre démon et gère les lancements et commandes par utilisateur. Bien que notre démon ait l'autorité root, nous avions toujours besoin d'un processus par utilisateur pour fonctionner de manière fiable dans les sessions utilisateur.

Graham Miln
la source
Pourriez-vous fournir un script simple, comme dans la réponse de TJ, mais qui fonctionne? Ou est-ce simplement trop complexe pour une telle chose?
cregox
La bonne solution est trop complexe pour un script court. Idéalement, un processus de type trampoline distinct est requis dans la session utilisateur cible. Voici ce que nous devions faire pour Power Manager: dssw.co.uk/powermanager Qu'espérez-vous réaliser?
Graham Miln
Dans l'espoir de réaliser exactement ce qui est dit dans le titre: lancer une application gui dans la session d'un autre utilisateur . "Points bonus" si l'autre utilisateur n'a pas besoin d'être connecté ou s'il peut être connecté par programme. En particulier, je veux plusieurs Google Drive. Cela fonctionne si je me connecte simplement manuellement et que c'est sous les éléments de connexion de cet utilisateur dans les préférences système. Un processus de trampoline n'apporterait pas les points bonus, mais si c'est le seul moyen, quelle est précisément la recommandation des ingénieurs Apple contre cela? Je pensais que ce serait précisément pour faire de tels scripts de piratage simples! : P
cregox
@Cawas veuillez poser cette question comme une nouvelle question et vous concentrer sur l'objectif de vouloir plusieurs disques Google, plutôt que sur la manière dont cela pourrait être réalisé. Le changement de focus aidera la question à ne pas être marquée comme doublon.
Graham Miln
Assez juste et fait .
cregox
7

Aucune des réponses de bsexec ci-dessus ne fonctionne sur El Capitan (10.11), en raison de la protection de l'intégration du système (SIP) fermant les ports. "launchctl asuser" fonctionne, mais nécessite d'être exécuté en tant que root. La commande ci-dessous fonctionne sur El Capitan (et les OS les plus récents):

sudo launchctl asuser 501 open /Applications/Calculator.app

Notez que 501 est l'ID utilisateur de mon autre utilisateur.

Boris Vidolov
la source
Ceci est mon résultat bruno.medeiros@brunojcm-macbook:~ $ sudo launchctl asuser 501 open /Applications/Firefox.appLSOpenURLsWithRole() failed with error -600 for the file /Applications/Firefox.app
:,
@BrunoJCM êtes-vous sûr que 501 est le code d'identification de l'utilisateur avec lequel vous souhaitez l'ouvrir? Il est un peu plus clair si la commande est quelque chose comme: sudo launchctl asuser $(id -u <user_id_name>) <app>. Cela dit, j'obtiens une erreur différente de posix_spawn(): 13: Permission deniedmême si je lance avec le même ID utilisateur avec lequel je suis connecté (et propriétaire de la session) poursudo launchctl asuser $(id -u mtylutki) /Applications/Calculator.app
Marcus
2

Enfin, 10.10 fournit une implémentation correcte de "launchctl bsexec" que vous pouvez utiliser:

sudo /bin/launchctl bsexec PID chroot -u UID -g GID / open /Applications/TextWrangler.app

l'homme dit

Cela exécute la commande donnée dans un contexte d'exécution aussi similaire que possible au PID cible.

Ainsi, en tant que paramètre PID, vous pouvez utiliser le pid du processus de connexion approprié . L'UID est l'ID utilisateur de l'utilisateur propriétaire de cette fenêtre de connexion et le GID est son groupe principal.

Cela fonctionne très bien pour n'importe quelle commande et bien sûr pour les jobs launchd (par exemple les lanceurs) également comme:

/bin/launchctl bsexec 104 chroot -u 501 -g 20 / /bin/launchctl load -S Aqua /Library/LaunchAgents/com.youragent.plist 2>&1
Hofi
la source
Je ne sais pas si cela est vrai pour les autres, mais j'obtiens task_for_pid(): 0x5maintenant une erreur pour cela, où j'ai vérifié que le PID est correct.
Marcus
1

Vous pouvez utiliser le Finder comme hôte pour les bonnes autorisations osascript -e "tell application \"Finder\" to open (\"${app}\" as POSIX file as alias)". De cette façon, il sera lancé via n'importe quel contexte GUI lancé Finder.

Atishay Jain
la source
0

Cela fonctionne via ssh:

#!/bin/bash

PID=$(ps auxwww | egrep "^bar" |\
fgrep /System/Library/CoreServices/loginwindow.app/Contents/MacOS/loginwindow |\
awk '{print $2}')

sudo launchctl bsexec "$PID" open -a TextEdit

mais si vous l'essayez via Terminal.app, il ouvre TextEdit dans l'interface graphique de l'utilisateur actuel.

Si vous n'êtes pas sûr que ce sshsoit activé, vous pouvez peut-être l'activer temporairement

sudo launchctl load -w /System/Library/LaunchDaemons/ssh.plist

et le désactiver à nouveau par la suite si nécessaire?

Sinon, je suis perplexe.

Testé le 10.9.

TJ Luoma
la source
Il ouvre l'application comme vous le dites, mais il l'ouvre dans la session utilisateur actuelle et non dans la session de l'autre utilisateur comme demandé.
cregox
-1

Facile

sudo su name_of_user

puis exécutez les commandes normalement.

Logiciel PandB
la source
Les commandes seraient exécutées par bar, mais s'exécuteraient toujours dans foola session graphique de.
John N
Désolé, oui, je suis confus à propos de la question, n'est pas exécuté sur foo session graphique.
PandB Software