Мне нужно иметь возможность запускать / останавливать агента графического интерфейса для сеанса из демона корневого уровня.
Подобные вопросы обсуждаются здесь , здесь и здесь .
То, что я хочу сделать, это в основном
for num in `ps ax | grep [s]bin/launchd | cut -c 1-5`;
do
if [ $num -ne 1 ];
then
sudo launchctl bsexec $num launchctl (un)load -S Aqua /Library/LaunchAgents/com.mycompany.mydaemon.plist;
fi;
done
, но это запускает / останавливает только один экземпляр и запускается от имени пользователя root в текущем сеансе графического интерфейса. Если я оставлю sudo там, я получу
task_for_pid() (os/kern) failure
Couldn't switch to new bootstrap port: (ipc/send) invalid port right
Я пытался возиться с множеством других перестановок bsexec (включая вызов вторичного сценария из bsexec с помощью команды load / unload), но я никогда не смогу запустить экземпляр как что-либо, кроме root, и никогда другой сеанс графического интерфейса.
Я также пытался возиться с su - <user> ...
и sudo -u <user> ...
, но и там мне не повезло (как многие люди обсуждали в приведенных выше статьях и в других местах).
У кого-нибудь есть мысли?
EDIT:
Я попытался сделать это с помощью инструмента-обертки, как предложено ниже Грэмом Ли, но я получаю следующую ошибку:
launch_msg(): Socket is not connected
Это команда, оболочка и скрипт командной строки, которые я использую (501 - это идентификатор пользователя, а 63093 - идентификатор запуска для другого пользователя, вошедшего в систему):
Командная строка:
sudo launchctl bsexec 63093 /path/TestSetUIDAndExecuteTool 501 /path/LoadBillingDialogAgent
Wrapper:
#import <Foundation/Foundation.h>
int main (int argc, const char * argv[]) {
NSAutoreleasePool * pool = [[NSAutoreleasePool alloc] init];
if (argc != 3) {
NSLog(@"Tool called with improper arguments");
return -1;
}
int uid = [[NSString stringWithUTF8String:argv[1]] intValue];
// TODO: REMOVE
NSLog(@"Setting uid to |%i|", uid);
setuid(uid);
// TODO: REMOVE
char *command = (char *)argv[2];
NSLog(@"Executing command |%s|", command);
system(command);
[pool drain];
return 0;
}
Сценарий:
/bin/launchctl load -S Aqua /Library/LaunchAgents/com.company.agent.plist