I have been reading documentation and the SMJobBless example and various discussions on the Internet. My app now installs a privileged helper using SMJobBless()
, but the helper doesn't run at all.
The whole purpose of the helper is to load a kext, an important component of my app, whenever the application starts. I have seen examples showing that trying to connect to the helper through XPC will launch the helper, but I would like to keep my helper simple and dumb.
The API doc shows that there is a SMJobSubmit()
function. What exactly does it do? Can I use it to launch the privileged helper installed previously by SMJobBless()
?
I'm confused by all the terms around launchd
and the Service Management Framework
- for example, the "RunAtLoad" plist option controls "whether your job is launched once at the time the job is loaded". What exactly is "load" and "launch", and how are they related to "bless/install" and "submit"?
SMJobBless will add your job to launchd's system. See the SMJobBless sample code for doing this.
http://developer.apple.com/library/mac/#samplecode/SMJobBless/Introduction/Intro.html
However, the whole purpose of launchd is to control how and when the jobs are launched, and by default (in the sample code), there is no specification of actually when the job should be launched, so the job will in fact never be launched.
Nathan de Vries wrote a very good article and sample code for using SBJobBless and communicating with the privileged job using XPC. One import side affect is, of course, that the act of trying to communicate with the launchd service will cause launchd to actually start your service, so this would solve your problem.
http://atnan.com/blog/2012/02/29/modern-privileged-helper-tools-using-smjobbless-plus-xpc/
And to specifically answer your question, SMJobSubmit can execute a privileged helper. It took me a long time to figure out, but the difference between the two is that SMJobSubmit will let you run an executable with privileges using launchd, while SMJobBless will add a LaunchDaemon permanently. SMJobBless's installed executable will remain blessed, whereas SMJobSubmit will require you to re-authenticate each time.
Note that in both cases you must SMJobRemove the previous one to ensure that a new version is used.
So, I would think you need to either:
- SMJobRemove, SMJobSubmit each time you launch your application, prompting the user for authentication each time. Use the RunAtLoad property in the dictionary you built to have the helper execute immediately.
OR
- Use Nathan's code, XPC connect, ask it its version number, if its not update, have it quit, then SMJobRemove, SMJobBless a new version, then XPC connect and ask it to install your kext. That way the user only has to authenticate for any new version.