[launchd-dev] Mysterious problem with [NSURL getResourceValue:forKey:error:]

James Bucanek subscriber at gloaming.com
Fri Aug 19 10:30:46 PDT 2016


> Quinn "The Eskimo!" <mailto:eskimo1 at apple.com>
> August 19, 2016 at 1:42 AM
> On 18 Aug 2016, at 17:58, James Bucanek<subscriber at gloaming.com>  wrote:
>
>> Question: I now [have] a second system daemon (which I created to support XPC communications). This one is a bit special because its launchd properties include the<key>UserName</key>  so the process is executes as the user that installed it.
>
> OK, that statement is either incorrect or illustrates that we're not using the same terminology.  A *launchd daemon* is system wide.  If you include the `UserName` property it's started as that user; the only legitimate use case here is to supply a role account.  If you don't include the `UserName` property, the daemon runs as root.
>
> A *launch agent* is per user.  It runs as the user in whose context the agent was loaded.  If you include the `UserName` property, it's ignored.
>
> Does that make sense?  If so, is this "second system daemon" actually an agent?

It makes prefect sense. If you have an interest in understanding what 
I'm doing, I'll summarize it here. But you can skip this explanation as 
I think I've already found a solution.

I've created a service, aptly named the "switchboard," that I use to 
allow my various processes (agents, daemons, client apps, helpers, etc.) 
to form ad hoc XPC connections with each other. They do that by 
exchanging their NSXPCListenerEndpoint objects via the switchboard daemon.

The switchboard has to be in a Mach namespace that all processes (both 
user and root) from all sessions (system, user, and gui) can connect 
with via [NSXPCConnection initWithMachServiceName:...]. However, each 
switchboard service only serves a single user, so I really don't want it 
running as root or be accessible from just any process.

My solution is to install the switchboard as a system daemon 
(/Library/LaunchDaemons), so it's globally reachable. To tighten 
security, the daemon uses the <key>UserName</key> property so the daemon 
runs as that particular user, and the service rejects any XPC 
connections from a process with an effective UID of an unknown user.

So far, this seems to be working just great.
>
> This is important because, in order to guarantee that you can act like the user, your code /must/ be running as an agent.  So a lot of the time you need two launchd jobs, one daemon providing system-wide functionality and one agent, loaded into each user's context, that performs actions that can only be done in that context.

That is clear to me now. I've found that I can successfully run my 
metadata gathering process from any process created in the "user" domain 
(Background session) or "gui" domain (Aqua session). But everything that 
was launched/exec'd/spawned from the system domain doesn't work, no 
matter what its UID or EUID is.

My solution is to leverage a user agent that runs in either the user's 
"user" or "gui" domain, and use the switchboard to let my root process 
form a connection with it.
> [1] There's two problems with doing this:
>
> * The set of context information is not documented to be exhaustive, so new stuff could be added in the future.
>
> * The security context is now (since 10.7) tied to the audit session ID, and there's no public API for switching that.

I have noticed the lack of a public API. ;) I did spend quit a bit of 
time looking for a way of either specifying the session ID for a new 
process, or switching sessions, but with a clearer understanding of the 
problem I think I now have a cleaner solution.

Cheers,

James
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://lists.macosforge.org/pipermail/launchd-dev/attachments/20160819/f095c6fe/attachment.html>


More information about the launchd-dev mailing list