Anyone can please provide sample code to launch a daemon from cocoa application using AuthorizationRef.
A daemon is generally defined as a long-running system service that has no user interaction. If that is what you mean by daemon then this is the wrong way to solve your problem most likely. Daemons should be started through launchctl and should have a preferences plist in /Library/LaunchDaemons or ~/Library/LaunchDaemons depending on whether they are system-wide or user-specific. Communication between your user application and the daemon can be done any way you please but I've found NotificationCenter (CFNotificationCenterRef) to be useful for such things.
However, if what you really need is to launch a tool to perform a specific task and that tool needs special privileges then check out the sample code here :
http://developer.apple.com/library/mac/#documentation/Security/Conceptual/authorization_concepts/03authtasks/authtasks.html%23//apple_ref/doc/uid/TP30000995-CH206-TPXREF33
Related
How can I protect my macOS system extension endpoint security from:
A. kill by the user (root user)
B. unloading by the root user?
I would say you could subscribe to a ES_EVENT_TYPE_AUTH_SIGNAL event to filter out all kill-alike signals to your process (if you run it inside your daemon. In case you are loading it into system process, user just can't kill it).
Well, I would not recomend to do this. The main question you should ask yourself: how the one will unload your system extension to uninstall a software or to update it, if it could not be unloaded?
The root user is the one that should be able to do any sane operation on the system by design.
You could still do some tricks here, like subscribe to the ES_EVENT_TYPE_AUTH_EXEC event and cancel all launchctl unload attempts, or systemextensionsctl with your system extension parameters in case you are doing this via separate extension.
I'm doing some research about the way launchd load it's services from plist files under /Library/LaunchDaemons/ or via the command launchctl load
So far I've managed to gather some various sources and compose the following vague picture as I understand it:
Upon Service loading (launchctl load) The process launchctl send the launchd an appropriate XPC message, and then the launchd is forked into new process with the context of xpcproxy.
This generic process, is waiting for another XPC call from the launchd to run it's real process context according to the launchDaemon plst.
Is this explanation sounds right ? perhaps anybody can help me make it more accurate ?
thanks
This is actually a bit more complicated. The kernel is composed of two parts, BSD and the mach kernel; the latter being responsible for management of memory and process scheduling.
Each mach process has one or more mach tasks (really task port rights!). When an application is first launched, it has just one right, the bootstrap port, allowing communication with launchd. Note that a task port right is uni-directional, so a launching process that has the right to communicate with launchd must give a right for launchd to communicate back to it.
When an XPC message is received by launchd, it depends upon the Launch Daemon as to what action it takes. It's possible that the message is for a service that runs with a network port that may or may not be running. If running, it forwards any arguments from the calling process to the running service. If not running, it can provide the service on demand by launching the process first.
More specifically you asked about launchctl load. Since the source code for launchd is no longer open source, the next best resource is the reverse engineering work by Jonathan Levin; Author of Mac OS X and iOS Internals and more recently, his newer self-published books on *OS Internals.
You'll find his slides about launchd here, but probably more useful to you is his version of launchctl, jlaunchctl which is open source.
Finally, if you want to view content of XPC messages between processes, disable SIP and use Jonathan's invaluable XPoCe tool.
How can I allow my process to persist after logout and not be killed, preferably without requiring the process to have administrator privileges? I am unable to use a service/scheduled task due to some peculiarities in the program.
The correct way to achieve this is through a Windows service. They are designed to run while the machine is on, independent of any interactive user logins.
You state in an edit that you aren't able to use a service. If that really is true then your task is not viable. My guess is that if you design your service correctly, perhaps interacting with a companion desktop app, then a service is perfectly feasible.
How would you use a LaunchAgent inside the sandbox? I want to distribute a UI-less LaunchAgent app bundle inside my main application that I can launch on demand. The reason I want this instead of an XPC service is for the KeepAlive option, which will prevent launchd from automatically killing my process when its idle. This option doesn't exist on XPC services.
The documentation says that there's a plist that needs to be copied into ~/Library/LaunchAgents, and this is obviously not possible inside the sandbox. Is there some sort of system API that would handle copy the plist for me? I've seen Apple's SMJobBless sample code, but it seems like that's for registering a privileged LaunchDaemon rather than an unprivileged LaunchAgent.
The API you're looking for is SMLoginItemSetEnabled(). You'll have to package your long-running agent as a regular .app bundle and put it into your main app's bundle at Content/Library/LoginItems.
Then at runtime in the main application you can use the SMLoginItemSetEnabled() call with the agent's bundle identifier to enable and disable your agent. If your main application quits, the agent stays alive. If the user logs out and back in or reboots, the OS will relaunch your agent when the user logs back in.
Update: As Dmitry notes, the documentation no longer comes with the sample I originally mentioned, but another Apple sample code project, for App Sandbox, demonstrates the same API (see the file NSXPCConnection+LoginItem.m).
Documentation page now doesn't contain a sample project, so here it is: http://rhult.github.io/articles/sandboxed-launch-on-login/
I've got a Launch Daemon that runs as root outside of the user context. This Daemon is always running and monitoring a server. On occasion, my Daemon will get a command from the server telling it to display something to the user. Obviously I can't do this from a Launch Daemon since it's not running in a "WindowsServer" environment - so the other option is to spawn a separate process for each user that has access to be able to display a GUI.
One option I have is to make a Launch Agent and have the OS start it up for me. The launch agent could then communicate with the Launch Daemon to determine when something needs to be displayed.
The problem is this though: the server will sometimes provide updates of the actual binary files. So the server would send the Launch Daemon a series of files which it is expected to copy out on top of the existing files. If I have a Launch Agent running, how can I shut it down so that the agent itself can be updated? Likewise, how could I start the Agent back up after the update is done?
Off the cuff, I would say that you should arrange a way for your daemon to request the launch agent to exit on demand, the same way you would arrange for it to launch on demand. Once you know the agent has exited, your daemon can proceed with the update.
Note that your agent probably should not live forever, and it should definitely not be polling the daemon for work. Instead, you should rig it up so that, when the daemon tries to connect to the agent, launchd launches the agent. You could do this by having the daemon connect to a Unix domain socket registered on behalf of the agent by launchd, for example.
You might do better to look at how Google's UpdateEngine handles software updates. I believe it too has a launch daemon perform the app updates. Since this is already working on many computers, its solution to software update problems is a proven one. (Sparkle's solution is thoroughly proven, as well, but it relies on user interaction, which you seem to want to avoid.)