Як запустити програму GUI у графічному сеансі іншого користувача?


15

Я намагаюся розібратися, як запустити програму GUI як іншого користувача, який увійшов у систему інтерактивно, у графічному сеансі цього користувача.

Наприклад, скажіть, що у мене є два користувачі, foo та bar. Обидва зареєстровані, але поточний інтерактивний користувач foo. Я хотів би запустити Calculator.app як "бар" користувача, щоб, коли я швидко переключився на бар, я виявив, що вікно "Калькулятор" відкрите в сеансі бар.

Ось що я спробував, що не працює:

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

Це запускає Calculator.app як бар, але вікно відкривається в графічному сеансі foo.

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

Такий же ефект.

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

Запускає калькулятор як foo, а не bar.

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

Такий же ефект.

Чи є спосіб досягти цього? Я готовий розважати всіма можливими рішеннями, включаючи баш сценаріїв, AppleScript, написання програми Core Foundation або програми з какао тощо. У моїй ситуації будь-яка програма або сценарій може виконуватись як будь-який користувач, включаючи root.

Примітка. Я знаю, що це можливо за допомогою віддалених подій Apple, але я не можу це використовувати, оскільки в ситуації, яку я намагаюся зробити це, я не маю гарантії, що "Віддалені події Apple" будуть включені в налаштуваннях спільного доступу.

Будь-яка допомога буде дуже вдячна!


1
Ви спробували openкоманду, використовуючи SSH?
Матьє Ріглер

Як не дивно, значок док-станції додатка з’являється під час сеансу foo, але вікно програми з’являється в панелі. Тож це, здається, не працює, але гарна пропозиція. На жаль, немає гарантії, що захищений вхід увімкнено в потрібній мені ситуації, що призначено для інсталятора.
GuyGizmo

Я думаю, що один фрагмент цієї головоломки може містити аргумент командного рядка -psn, який ОС додає в деяких ситуаціях. Я з цим стикався в минулому, коли працював над перенесенням якогось коду в OS X. Дивіться це питання та документацію Apple, на яку він посилається.
Ешлі

станом на 10.10 нарешті нижче вказаний bsexec ідеально працює
Хофі

Відповіді:


7

Те, що ви хочете досягти, можливо, але важко. Вам потрібно запустити програму протягом відповідного сеансу користувача. З міркувань безпеки перетнути поділ сеансу користувача складно.

Вам потрібен процес, який вже запущений у сеансі іншого користувача, щоб прослухати ваш запит та запустити програму від вашого імені.

bsexec

На щастя, останні версії launchdмають таку можливість; хоча інженери Apple не рекомендували його загального використання. Використовуйте bsexecопцію в launchctl для націлювання на відповідний сеанс користувача:

 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.

Рекомендований підхід полягає в тому, щоб написати пусковий квиток на роботу та перезапустити Mac - або попросити користувача вийти з системи та знову ввійти.

Причина проблем

Проблеми пов'язані з підключенням програми до неправильного WindowServerпроцесу. Кожен сеанс користувача має окремий сервер WindowServer; цей процес обробляє користувальницький інтерфейс. Ваші попередні методи передають право власності на процес потрібному користувачеві, але підключено до власного процесу WindowServer.

Ця проблема згадується в технічній записці компанії Daemons and Agents від Apple.

Досвід

Я знаю це з особистого досвіду. Для Power Manager я писав, що pmuser існує в кожному сеансі користувача. pmuserслухає наш демон і обробляє запуски та команди кожного користувача. Незважаючи на те, що наш демон має повноваження root, нам все ж потрібен процес користувача, щоб надійно працювати в межах сеансів користувача.


Чи можете ви надати простий сценарій, наприклад, у відповіді TJ там, але такий, який працює? Або це просто занадто складно для такої речі?
Крегокс

Правильне рішення є занадто складним для короткого сценарію. В ідеалі необхідний окремий процес, схожий на батут, у сесії цільового користувача. Ось що ми мали зробити для Power Manager: dssw.co.uk/powermanager Що ви сподіваєтеся досягти?
Грем Мілн

Сподіваючись досягти саме того, що сказано в назві: запустіть програму gui в сеансі іншого користувача . "Бонусні бали", якщо іншому користувачеві не потрібно входити в систему або якщо він може входити програмно. Зокрема, я хочу декілька дисків google. Він працює, якщо я просто входжу вручну і це знаходиться під пунктами входу цього користувача в системні налаштування. Процес батуту не принесе бонусних балів, але якщо це єдиний спосіб, то що саме рекомендує інженерам Apple проти цього? Я думав, що це саме для таких простих скриптів для злому! : P
Крегокс

@Cawas, будь ласка, задайте це як нове запитання та зосередитесь на цілі - бажати декількох дисків Google, а не на тому, як це можна досягти. Зміна фокусу допоможе питання не бути позначеним як дублікат.
Грем Мілн

Досить справедливо і зроблено .
Крегокс

7

Жоден з bsexec не відповідає вищевказаній роботі над El Capitan (10.11) через захист інтеграції системи (SIP), що закриває порти. "startctl asuser" працює, але його потрібно запускати як root. Команда нижче працює на El Capitan (і останні ОС):

sudo launchctl asuser 501 open /Applications/Calculator.app

Зауважте, що 501 є userid для мого іншого користувача.


Це мій результат: bruno.medeiros@brunojcm-macbook:~ $ sudo launchctl asuser 501 open /Applications/Firefox.appі отримавLSOpenURLsWithRole() failed with error -600 for the file /Applications/Firefox.app
BrunoJCM

@BrunoJCM ви впевнені, що 501 - це ідентифікаційний код користувача для користувача, з яким ви хочете його відкрити? Це трохи ясніше , якщо команда що - щось на кшталт: sudo launchctl asuser $(id -u <user_id_name>) <app>. Це означає, що я отримую іншу помилку, posix_spawn(): 13: Permission deniedнавіть якщо я працюю з тим самим ідентифікатором користувача, з яким я ввійшов (і володіє сеансом) дляsudo launchctl asuser $(id -u mtylutki) /Applications/Calculator.app
Marcus

2

Оскільки нарешті 10.10 забезпечує правильну реалізацію "startctl bsexec", яку ви можете використовувати:

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

каже людина

Це виконує задану команду в максимально схожому контексті виконання з цільовим PID.

Отже, як параметр PID, ви можете використовувати pid відповідного процесу входу в систему . UID - це ідентифікатор користувача, який має власник цього вікна входу, а GID - це його основна група.

Це добре працює для будь-якої команди та, звичайно, для запущених завдань (fe startchagents), нарешті, як:

/bin/launchctl bsexec 104 chroot -u 501 -g 20 / /bin/launchctl load -S Aqua /Library/LaunchAgents/com.youragent.plist 2>&1

Не впевнений, що це правда для інших, але я отримую task_for_pid(): 0x5помилку в цьому, де я перевірив, чи PID правильний.
Маркус

1

Ви можете використовувати Finder як хост для правильних дозволів osascript -e "tell application \"Finder\" to open (\"${app}\" as POSIX file as alias)". Таким чином він запускатиметься через будь-який контекст GUI, який запускається Finder.


0

Це працює через 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

але якщо спробувати його через Terminal.app, він відкриє TextEdit в GUI поточного користувача.

Якщо ви не впевнені, що sshце ввімкнено, можливо, ви можете тимчасово його ввімкнути

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

і відключити його знову, якщо потрібно?

Інакше я застряг.

Випробувано 10.9.


Він відкриває додаток, як ви говорите, але він відкриває його в поточному сеансі користувача, а не в сеансі іншого користувача, як вимагається.
Крегокс

-1

Простий

sudo su name_of_user

потім виконувати команди нормально.


Команди виконуватимуться bar, але все одно виконуються в fooграфічному сеансі.
Джон N

Вибачте, так, я не плутаю питання, не виконується на графічній сесії.
Програмне забезпечення PandB
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.