[launchd-dev] UserName ignored on per-user LaunchAgents
Kevin Van Vechten
kvv at apple.com
Wed Dec 5 00:48:37 PST 2007
On Dec 4, 2007, at 7:39 PM, Jeremy Reichman wrote:
> This may be something of a "duh" but I'm curious if it is
> intentional and
> immutable that per-user LaunchAgents, such as those a sys admin
> might want
> to stuff into /Library/LaunchAgents, ignore the "UserName" key.
Yes, it's intentional. LaunchAgents are executed by the per-user
launchd. As a non-root process, it does not have the privilege to
setuid(2) to another user, hence the UserName key is ignored.
> In launchd.plist's man page:
>
> "UserName <string>
> This optional key specifies the user to run the job as. The default
> is the
> user who submitted the job to launchd."
This was written before the advent of the per-user launchd. It should
be revised to indicate this key is honored by the root launchd only
(for use by LaunchDaemons).
> Why do I want to specify it? Well, launchd tasks have certain
> advantages
> over LoginHook (and LogoutHook). If I could replace LoginHook
> scripts --
> which, let's face it, are limited in that they have to be called by
> a single
> script parent script (similar to `/usr/sbin/periodic`) -- with launchd
> tasks, I'd much prefer to do so. For one thing, there's no
> modification of
> the loginwindow plist -- and the use of individual launchd jobs
> would make
> it much easier to run multiple tasks.
>
> The most obvious way to accomplish that is with a LaunchAgent, but
> Login|LogoutHook run as root. Hence the problem. If your LoginHook-
> type
> tasks need root access for whatever reason, then the obvious launchd
> way to
> set that up is with the UserName key in your job plist. But it
> doesn't work.
>
> I can see the wisdom of ignoring the key, but if a sys admin has
> placed a
> job in /Library/LaunchAgents, and that directory is installed with the
> system using restrictive permissions, and the job is owned by root,
> there
> would seem to be several adequate safeguards in place to make
> malicious use
> difficult. (Application Launch Restrictions are already depending on
> the
> filesystem location and permissions, at least in managed
> environments, so it
> would seem that launchd could do so as well.) I would be supportive
> of other
> reasonable safeguards besides these, too, including script signing
> and more.
>
> Besides asking whether ignoring the UserName key is meant to be this
> way and
> could be changed in the future if enhancement requests were filed,
> is there
> another way to replace the hooks with launchd?
Let's step back to a time before launchd and consider the case of an
ordinary Cocoa application that needs to perform a privileged
operation. Since there's no "UserName" key available in the
Info.plist, the application must invoke a privileged helper tool
(setuid binary, gated by AuthorizationExecWithPrivilege).
With launchd, it's now possible to get rid of the setuid binary (which
avoids a whole class of potential privilege escalation
vulnerabilities) and replace it with a LaunchDaemon that executes in a
privileged context. The Cocoa application can send an IPC message to
the Daemon, and the daemon can perform the privileged operation
(Authorization API can still be used to create an "external form" that
can be validated across the IPC channel).
A LaunchAgent, like the Cocoa application example, runs as the user --
in fact they're running in the same context. If it needs to perform a
privileged operation, it can send an IPC message to a LaunchDaemon
running in a privileged context to perform said operation.
- Kevin
More information about the launchd-dev
mailing list