Pregunta

Tengo que ser capaz de iniciar / detener un agente de interfaz gráfica de usuario por sesión de un demonio de nivel raíz.

Se discuten

aquí , aquí y aquí .

Lo que yo quiero ser capaz de hacer es básicamente

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

pero esto sólo se inicia / detiene una instancia y se ejecuta como root en la sesión de interfaz gráfica de usuario actual. Si dejo el sudo fuera allí comenzar consigo

task_for_pid() (os/kern) failure
Couldn't switch to new bootstrap port: (ipc/send) invalid port right

He intentado jugar un poco con una variedad de otras permutaciones de bsexec (incluyendo llama a un script secundaria de bsexec con la carga / descarga de comandos), pero nunca puedo obtener la instancia para iniciar tan diferente a root y nunca en otra sesión de interfaz gráfica de usuario.

También intentado jugar un poco con su - <user> ... y sudo -u <user> ..., pero no tuvo suerte allí tampoco (como muchas personas han discutido en los artículos vinculados anteriores y en otros lugares).

¿Alguien tiene alguna idea?

EDIT: He intentado hacer esto con una herramienta envoltorio como se sugiere a continuación por Graham Lee, pero me sale el siguiente error:

launch_msg(): Socket is not connected

Este es el comando de línea de comandos, envoltura, y el guión que estoy usando (501 es el identificador de usuario y el pid 63093 de launchd para otro usuario conectado al sistema):

Línea de comandos:

sudo launchctl bsexec 63093 /path/TestSetUIDAndExecuteTool 501 /path/LoadBillingDialogAgent

Envoltura:

#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;
}

Guión:

/bin/launchctl load -S Aqua /Library/LaunchAgents/com.company.agent.plist
¿Fue útil?

Solución

El uso de launchctl bsexec es correcta, pero hay que poner en marcha una herramienta de envoltura que cae UID para el usuario de destino antes de ejecutar el ejecutable agente 'real'. Ah, y es probable que sea mejor buscar procesos loginwindow, ya que esos son los líderes de las sesiones de inicio de sesión (aunque launchd es muy probable que funcione también).

Otros consejos

Parece que cada usuario launchd casos no se están ejecutando en el mismo espacio de nombres de arranque como launchctl lanzado desde la terminal.

Mediante el uso de Dock.app como donante de PID y un poco de magia sudo:

ps aux | grep Dock.app | grep -v grep | awk '{system("sudo launchctl bsexec "$2" sudo -u "$1" launchctl load -S Aqua /Library/LaunchAgents/com.my.agent.plist")}'

es posible poner en marcha agente en todas las sesiones en ejecución.

No es ordenada, pero funciona.

Actualización:.. No funcionará en 10.7 Sí, se pondrá en marcha agente, sino que puedo ver a partir de ensayos no en el contexto correcto

Sobre la base de las discusiones aquí y este script , no pensé que una herramienta de envoltura debería ser necesario. Estos dos scripts bash pueden ayudar a otros también.

  

Agentes Unload

#!/bin/bash
for id in `ps aux | grep -v grep | grep MyAgent | awk {'print $2'}`
do
    launchctl bsexec $id launchctl unload /Library/LaunchAgents/myAgent.plist
done

Reemplazar 'MyAgent' con el nombre de su Agente de lanzamiento.

  

Agentes de carga

#!/bin/bash
for pid_uid in $(ps -axo pid,uid,args | grep -i "[l]oginwindow.app" | awk '{print $1 "," $2}'); do

    pid=$(echo $pid_uid | cut -d, -f1)
    uid=$(echo $pid_uid | cut -d, -f2)

    launchctl bsexec "$pid" chroot -u "$uid" / launchctl load /Library/LaunchAgents/myAgent.plist
done

Llamado de un demonio de raíz, esto va a cargar y descargar el agente de lanzamiento se hace referencia en myAgent.plist para todos los usuarios conectados.

Tenga en cuenta que debido a 'sin raíces' en OS X El Capitán (10.11), el uso de bsexec puede ya no funcionan, pero hasta 10.10, este debe estar bien.

Yo tenía el mismo problema. Para solucionar esto, utilizar un pid "bajo" launchd, el PID de un proceso que se ha iniciado launchd.

El pid de comprometerse a 'launchctl bsexec' se utiliza para encontrar el arranque de la derecha. Si se utiliza el pid del launchd (del contexto de usuario) que trabaja en el sistema de arranque launchd raíz. Si utiliza PE. el Finder o el pid del muelle del usuario, se puede trabajar en este "por usuario" de arranque

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top