Как сделать процесс, не являющийся родительским, порождающим корневой дочерний процесс под MacOS / X? - PullRequest
1 голос
/ 03 октября 2019

У меня есть обычный старый процесс MacOS / X GUI, запускаемый пользователем, дважды щелкающим значок, и поэтому он запускается с привилегиями этого пользователя.

То, что я хотел бы сделать, это иметьэтот процесс GUI порождает дочерний процесс и связывается с дочерним процессом через его стандартный ввод / вывод. Это все выполнимо и работает.

Хитрость заключается в том, что я хотел бы, чтобы дочерний процесс выполнялся от имени пользователя root, поскольку дочернему процессу необходимо будет выполнить некоторые действия, требующие доступа с правами root.

Я ожидаю, что для этого потребуется открыть диалоговое окно с просьбой ввести пароль администратора, и это нормально для этого варианта использования.

Один из способов сделать это состоит в том, чтобы родительский процесс выполнил команду оболочки следующим образом:

/usr/bin/osascript -e 'do shell script "/bin/bash ./my_script.sh" with administrator privileges'

... и my_script.sh запустил программу, представляющую дочерний процесс,который, я думаю, будет работать, но есть ли более элегантный способ сделать это (то есть тот, который не требует записи сценария оболочки где-то на диск и дает более удобный для пользователя запрос пароля, чем тот, который довольно загадочно говорит "osascript хочет внести изменения ")?

1 Ответ

0 голосов
/ 05 октября 2019

Я наконец смог заставить его работать, изучив исходный код для cocoasudo , как упомянуто nm

Сложная часть заключалась в том, что AuthorizationExecuteWithPrivileges дает дочернему процессу euid («эффективный идентификатор пользователя») 0 / root, чтобы он мог делать вещи, требующие root-доступа, но это не меняет uid дочернего процесса («реальный идентификатор пользователя»));для него остается значение идентификатора пользователя родительского процесса, поэтому на самом деле не рассматривается остальной системой как корневой процесс.

Эта деталь вызвала ряд вещейв моем shell-скрипте работать некорректно при запуске таким способом;с одной стороны, при выполнении сценария с использованием /bin/bash, даже если whoami указывает, что он выполняется от имени пользователя root, действия, требующие доступа с правами root (например, копирование файла в каталог, доступный только для записи с правами root), по-прежнему завершаются ошибкой. Любопытно, что /bin/sh, похоже, не страдает от этой проблемы.

Другим важным камнем преткновения было то, что моему сценарию нужно было вызвать launchctl load -w com.mycompany.myproduct.plist, чтобы запустить System LaunchDaemon, но launchctl основывает свое решение наустанавливать ли службу как специфичную для пользователя по сравнению с общесистемной на основе реального идентификатора пользователя, так что моя служба всегда будет устанавливаться как специфичная для пользователя служба (работающая без корневого доступа и запускаемая только при входе текущего пользователя)чем в качестве общесистемной службы, работающей от имени пользователя root.

После долгих догадок и поисков, я был направлен в раздел «Советы и подсказки» в нижней части Apple Tech Note TN2083 , в котором говорится:

ВАЖНО: Для того, чтобы это работало правильно, вы должны запустить launchctl от имени пользователя root (и его EUID, и RUID должны быть 0). Это гарантирует, что launchctl связывается с основным экземпляром launchd.

... и, поскольку (AFAIK) нет системного инструмента командной строки для вызова setuid(0), мне пришлосьнаписать свой собственный маленький инструмент запуска сценариев на C:

int main(int argc, char ** argv)
{
   if (argc >= 2)
   {
      if (setuid(0) == 0)   // make us really root, not just "effectively root"
      {
         system(argv[1]);  // then run the specified script file
         return 0;
      }
      else perror("setuid");
   }
   else printf("Usage:  setuid_script_launcher <path_to_script>\n");

   return 10;
}

Это было намного больше работы, чем я думаю, чтобы было понять, но теперь все работает. Я описываю это здесь, чтобы избавить следующего человека от боли.

...