installing a SMAppService based LaunchDaemon from the command line

our app has a helper to perform privileged operations.

previously that helper was installed via SMJobBless() into the /Library/LaunchDaemons/ and /Library/PrivilegedHelperTools/

we also had a script that would install the helper from the command-line, which was essential for enterprise users that could not manually install the helper on all their employee's Macs. the script would copy the files to their install location and would use launchctl bootstrap system as the CLI alternative to SMJobBless(). the full script is here: https://pastebin.com/FkzuAWwV

due to various issues with the old SMJobBless() approach we have ported to helper to the new SMAppService API where the helpers do not need to be installed but remain within the app bundle ( [[SMAppService daemonServiceWithPlistName:HELPER_PLIST_NAME] registerAndReturnError:&err] )

however, we are having trouble writing a (remote-capable) CLI script to bootstrap the new helper for those users that need to install the helper on many Macs at once. running the trivial

sudo launchctl bootstrap system /Applications/MacUpdater.app/Contents/Library/LaunchDaemons/com.corecode.MacUpdaterPrivilegedInstallHelperTool2.plist

would just result in a non-informative:

Bootstrap failed: 5: Input/output error

various other tries with launchctl bootstrap/kickstart/enable yielded nothing promising.

so, whats the command-line way to install a SMAppService based helper daemon? obviously 'installing' means both 'registering' (which we do with registerAndReturnError in the GUI app) and 'approving' (which a GUI user needs to manually do by clicking on the notification or by going into System Settings).

thanks in advance!

p.s. we wanted to submit this as a DTS TSI, but those are no longer available without spending another day on a reduced sample projects. words fail me.

p.p.s. bonus points for a CLI way to give FDA permissions to the app!

Answered by DTS Engineer in 820500022

[quote='820405022, absinth, /thread/771162?answerId=820405022#820405022, /profile/absinth'] there must be a way to fully install apps … in a non-interactive way, especially for businesses. [/quote]

Agreed.

In my experience folks who run managed sites really like installer packages, because MDM systems are good at running those. So, one option here is to repackage your app as an installer package, and have the installer package install the daemon like it would any other launchd daemon, that is, copy the launchd property list file to /Library/LaunchDaemons.

You don’t need a separate build of your app here; your launchd property list can reference the tool within your app via BundleProgram [This is wrong. See the follow-up below.].

However, it might make sense for your app to be able to detect that it’s installed that way and disable its ability to update and uninstall the daemon. In a managed environment those operations tend to be the purview of the site manager.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

SMAppService is really intended to be used by apps; the clue is in the name (-:

I’m not 100% sure why you’re having this problem. Is that script you posted an example of what you were previously doing with your SMJobBless code? Or what you’re trying to do with your SMAppService code?

p.p.s. bonus points for a CLI way to give FDA permissions to the app!

No. The purpose of such privileges is to allow the user to control their Mac. Adding a way around that would defeat that purpose entirely.

Having said that, in a managed environment the site manager can configure some of these privileges via the com.apple.TCC.configuration-profile-policy payload, deployed via MDM.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

thanks for your reply here

SMAppService is really intended to be used by apps; the clue is in the name (-:

yes but there must be a way to fully install apps (even if they use SMAppService) in a non-interactive way, especially for businesses.

I’m not 100% sure why you’re having this problem. Is that script you posted an example of what you were previously doing with your SMJobBless code?

yes, as mentioned this script is what we were previously doing when the app was still based on SMJobBless.

now that the app('s helper) is based on SMAppService, how to install&approve the helper instead?

as written launchctl bootstrap system just errors out...

Having said that, in a managed environment the site manager can configure some of these privileges via the com.apple.TCC.configuration-profile-policy payload, deployed via MDM.

thanks, exactly what we need.

[quote='820405022, absinth, /thread/771162?answerId=820405022#820405022, /profile/absinth'] there must be a way to fully install apps … in a non-interactive way, especially for businesses. [/quote]

Agreed.

In my experience folks who run managed sites really like installer packages, because MDM systems are good at running those. So, one option here is to repackage your app as an installer package, and have the installer package install the daemon like it would any other launchd daemon, that is, copy the launchd property list file to /Library/LaunchDaemons.

You don’t need a separate build of your app here; your launchd property list can reference the tool within your app via BundleProgram [This is wrong. See the follow-up below.].

However, it might make sense for your app to be able to detect that it’s installed that way and disable its ability to update and uninstall the daemon. In a managed environment those operations tend to be the purview of the site manager.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

In my experience folks who run managed sites really like installer packages, because MDM systems are good at running those. So, one option here is to repackage your app as an installer package,

no problem there. but it really doesn't matter technically if the solution is triggered by a script run during PKG installation or if the script is embedded in the app and the MDM admin calls it in some other way

and have the installer package install the daemon like it would any other launchd daemon

should not matter if the daemon is installed via a PKG or by a script run as root, right?

that is, copy the launchd property list file to /Library/LaunchDaemons.

this finally sounds like a solution, great and THANKS.

i was not aware that SMAppService actually supports daemons installed outside the app, as the documentation always mention they stay embedded in the app.

however and in any case, i tried your solution, but it did not work. the plist can be copied to LaunchDaemons but cannot be loaded into launchd

steps to reproduce:

• i made a copy of the PLIST file that points to the app via an absolute instead of a relative path (attached as com.corecode.MacUpdaterPrivilegedInstallHelperTool2_MDM.plist )

• i modified the installation script (attached as priviledgedHelperTool_install.sh ) to install the plist file to /Library/LaunchDaemons but it cannot be activated either via launchctl or just by rebooting or via the LaunchControl guy. launchctl gives the same uninformative "Bootstrap failed: 5: Input/output error" error that i mentioned in my initial report.

• since the daemon cannot be bootstrapped, the app cannot communicate with the helper

so, we are still at the beginning. how to install the SMAppService based helper daemon non-interactively?

thanks!

note: this content was sent private to DTS on 12. February as part of a TSI. since i have still not received a reply there i'll repost here instead.

attachment 'priviledgedHelperTool_install.sh': https://pastebin.com/QurSFjUT

attachment: 'com.corecode.MacUpdaterPrivilegedInstallHelperTool2_MDM.plist': https://pastebin.com/cZCPWZhf

Hmmm, I’m pretty sure that launchd property lists can be successfully installed by an installer package. Lots of products do that (-:

Looking at the com.corecode.MacUpdaterPrivilegedInstallHelperTool2_MDM.plist file you referenced, it has BundleProgram set to an absolute path. That’s not going to work )-:

Earlier I wrote:

your launchd property list can reference the tool within your app via BundleProgram.

which was incorrect. Sorry about that. BundleProgram is only supported if the job was installed via SMAppService. That’s what allows the system to track down the app which installed the job [1]. In your case you’ll need to use ProgramArguments, or the more limited Program.

Share and Enjoy

Quinn “The Eskimo!” @ Developer Technical Support @ Apple
let myEmail = "eskimo" + "1" + "@" + "apple.com"

[1] You could imagine it doing that via AssociatedBundleIdentifiers but that’s not what the man page says. However, you should set AssociatedBundleIdentifiers anyway.

installing a SMAppService based LaunchDaemon from the command line
 
 
Q