Writing a privileged helper tool with SMJobBless()

In fact @KurtRevis's comment is right, you can use XPC APIs without using XPC services, and it is ideally suited to the job since.

Nathan de Vries has an excellent writeup of using XPC APIs with SMJobBless and has even modified the SMJobBless sample app to use mach XPC to both activate the job and for bidirectional communications:

http://atnan.com/blog/2012/02/29/modern-privileged-helper-tools-using-smjobbless-plus-xpc/

https://github.com/atnan/SMJobBlessXPC

Somewhat related to all this is avoiding unnecessary admin password prompts. See the following email list thread for ideas on how to check if the bundle version and code signature of an already installed helper match (which also allows you to remove a higher versioned helper in the case of a user downgrading):

http://www.cocoabuilder.com/archive/cocoa/309298-question-about-smjobbless.html

If you don't want to wade through the thread, here is a link to the modified SMJobBless sample project provided by Eric Gorr:

http://ericgorr.net/cocoadev/SMJobBless.zip

Also note that the ssd example mentioned in other answers here is still available online from Apple as part of the WWDC 2010 download bundle:

http://connect.apple.com/cgi-bin/WebObjects/MemberSite.woa/wa/getSoftware?code=y&source=x&bundleID=20645


XPC isn't an option if you're trying to elevate privileges (from https://developer.apple.com/library/archive/documentation/MacOSX/Conceptual/BPSystemStartup/Chapters/CreatingXPCServices.html):

By default, XPC services are run in the most restricted environment possible—sandboxed with minimal filesystem access, network access, and so on. Elevating a service’s privileges to root is not supported.

SMJobBless will install a helper tool and register it with Launchd, as in the SMJobBless example provided by Apple. The trick to getting your helper tool to actually launch is to simply attempt to connect to your helper tool's advertised services.

There was a WWDC2010 example called ssd that demonstrated a simple launchd client/server model via sockets. It's not available from Apple any longer, but I've found a link here: https://lists.apple.com/archives/macnetworkprog/2011/Jul/msg00005.html

I've incorporated the dispatch queue handling in the server code from the ssd example into the helper tool in the SMJobBless example and can confirm that my helper tool is indeed running (as root) when my main app attempts a connection on the appropriate port. See the WWDC2010 video on Launchd to understand the other mechanisms with which you can communicate with your helper tool (other than sockets).

I'm not sure I can legally redistribute the modified sources I have, but it should be fairly straightforward to merge the two projects and get your helper tool running.

Edit: Here is an example project I wrote that uses a distributed object for communication between the app and helper: https://www.dropbox.com/s/5kjl8koyqzvszrl/Elevator.zip