Как убрать вещи, которые не принадлежат текущему пользователю, так же, как это делает Finder? - PullRequest
4 голосов
/ 24 июня 2019

Я пишу инструмент, который предлагает возможность удалить выбранные элементы (файлы, папки).Обычно я звонил бы -[NSFileManager trashItemAtURL:...] для каждого из этих предметов, как это также объясняется в этом и этом ТА вопросе.

Однако они не работают при попытке удалить файлы из каталога, принадлежащего другому пользователю, например root .В этом случае мой инструмент будет предлагать ту же опцию, что и Finder, то есть попросить пользователя авторизовать операцию, указав учетные данные пользователя Admin, и тогда мое приложение будет перемещать элементы в корзину, как это делает Finder.

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

Однако проблема в этом, что привилегированный помощник запускается от имени пользователя root, без ведома текущего пользователя, под которым запускается мое приложение.В результате, когда он удаляет файл, он попадает в папку корзины пользователя root, а не, как это делает Finder, в папку корзины пользователя.

Как мне решить эту проблему, т.е. как переместить элементы, не принадлежащие пользователю, в корзину текущего пользователя вместо корзины пользователя root?

Есть ли какой-то трюк?Можно ли использовать это, что позволило бы мне продолжать использовать одну из существующих функций повторного использования корзины?

Самостоятельное перемещение не будет работать должным образом, потому что для Верните для работы, * 1033 корзины* Файл должен быть обновлен, и для этого нет API, AFAIK.

1 Ответ

1 голос
/ 30 июня 2019

У меня почти найдено решение:

Анализ

Когда запущен помощник, например, из launchd или через AuthorizationExecuteWithPrivileges (под macOS 10.15), он может работать от имени пользователя root, не имея сведений о вошедшем в систему пользователе, поэтому он не может определить папку корзины пользователя.

Как ни странно, переменные окружения (см. man env) могут даже отображать текущийимя пользователя и домашний каталог, но реальный идентификатор пользователя , который можно запросить с помощью getuid(), вернет 0 (root), что также приведет к NSUserName() и NSHomeDirectory(), возвращающему информацию пользователя root,И, похоже, что trashItemAtURL и связанные функции полагаются на NSHomeDirectory() для определения местоположения папки «Корзина».

Полуфабрикаты

К счастью, есть способ изменить реальный идентификатор пользователя , с setreuid.

Поэтому в моем тестировании, когда я звоню setreuid (501, 0) (501 - это идентификатор пользователя, вошедшего в систему), тогда trashItemAtURL действительно перемещаетсяфайл в папку «Корзина» пользователя, действительно, вместе с автоматическим переименованием, где это необходимо.

Однако, это не заставляет Put Back работать так, как было быпри удалении того же файла с помощью Finder.

Как заставить Put Back работать

Похоже, причина того, что Put Back не работает, связана с более глубокой проблемой:давняя ошибка в среде macOS, см. этот отчет об ошибках .

Что в основном означает: это лучшее, что мы можем из него исправить, пока Apple не исправит основную ошибку.

Единственная работающая альтернатива, чтобы сделать Вернуть Работа заключается в том, чтобы попросить Finder уничтожить элементы с помощью AppleEvents / AppleScript.

...