I had an application that needs to do very frequent privileged work.I used to achieve these work by AuthorizationExecuteWithPrivileges(). And I would like to follow the recommended way by using SMJobBless with XPC (a privileged helper over XPC communication). However, I got 2 questions about the unstalling the privileged helper (helper for short below).
I noticed that SMJobRemove had been marked as deprecated and there is no other API as replacement of it now. So I would like to understand what is the supposed or recommended approach to unstall the helper now?
More background of this question:
My application can be installed by a simple drag from with the dmg packege. And the uninstall process is also just by draging to the Trash.
The first time the app starts, it will try to bless the helper with asking the authentication/authorization from a user. Subsequently, it will not bother users next time startup or when communicating with the helper for privileged works.
The reason that I need to uninstall the helper is for the helper version compatibility. There could be multiple versions of the application with potential different version of helpers co-existing in a user's system. So an idea is that each application with an exactly version number will install and communicate with a helper with a specified version as well (i.e. application 1.0.0 <-> helper-100 / application 2.0.1 <-> helper-201 ...). Therefore, to avoid leaking such a number of helpers in the disk when the applications are removed, I would like to unstall (remove) the helper[ver_num] when a specific version of applications are removed.
Furthermore, when to trigger the uninstall process?
My current idea is that when the first time the application starts, it will register the folder path where the application is in in the helper (over XPC) plist. The helper will then watch the folder change over the paths (if there are multi applications with that version exists). Once all the applications of that version with different paths registered in helper are removed, the helper will fork a subprocess to uninstall the helper (by SMJobRemove??).
If the above thinking are not on a correct direction, could you have any suggestion about these 2 questions?
I noticed that SMJobRemove had been marked as deprecated and there is no other API as replacement of it now.
SMJobRemove
is not the logical opposite of
SMJobBless
:
copies the privileged helper tool, creates a launchd property list file inSMJobBless
, and loads the job into/Library/LaunchDaemons/
launchd
unloads the job fromSMJobRemove
launchd
As such,
SMJobRemove
is the logical opposite of
SMJobSubmit
.
There is, alas, no logical opposite of
SMJobBless
)-:
Furthermore, when to trigger the uninstall process?
There isn’t a good way to do this automatically.
My current idea is that when the first time the application starts, it will register the folder path where the application is in in the helper (over XPC) plist.
This approach is unlikely to yield a reliable solution. There are just too many ways that things can go wrong. For example, what if the user launches your app off a removable drive and then removes the drive? You can’t work out whether that’s a permanent or temporary removal, and thus whether your privileged helper tool should self immolate or not.
I recommend that you offer the user the option of manually uninstalling the privileged helper tool. Users who care will do the manual uninstall. Users who don’t care won’t notice the leftover helper.
For this to be acceptable you have to ensure that any leftover helpers have a minimal impact on the system. If they do all the usual launchd daemon things (launch on demand, exit on pressure), the cost to the user should be negligible.
Obviously the above is less than ideal. It would be nice if macOS had a better mechanism for escalating privileges in a coherent and controlled manner. Please do file an enhancement request describing your requirements in this space, then post the bug number here, just for the record.
Share and Enjoy
—
Quinn “The Eskimo!”
Apple Developer Relations, Developer Technical Support, Core OS/Hardware
let myEmail = "eskimo" + "1" + "@apple.com"