Hi,
Success! Mostly :) A table of contents:
1. What is now possible
2. How elogind maps PIDs to sessions
3. GuixSD caveats
1. What is now possible
-----------------------
The attached patches update to the latest elogind, for which I just cut
a new release. The big change is that elogind can now map PIDs to
sessions. Elogind already keeps an idea of what sessions are "active".
On the other hand, polkit can implicitly grant some permissions to
"active" users. This set of permissions is initially empty but it can
be augmented by other services, like gnome-settings-daemon. In the
specific case of gnome-settings-daemon, gnome-settings-daemon ships an
.action file that allows the active user to invoke a helper that can
change the backlight of your screen. For example:
$ tail /etc/polkit-1/actions/org.gnome.settings-daemon.plugins.power.policy
修改筆記型電腦亮度需要核對
no
no
yes
/gnu/store/rssyvyd0dj0j5jqkmir0najq1rcd72il-gnome-settings-daemon-3.18.2/libexec/gsd-backlight-helper
$ /gnu/store/rssyvyd0dj0j5jqkmir0najq1rcd72il-gnome-settings-daemon-3.18.2/libexec/gsd-backlight-helper --set-brightness 500
This program can only be used by the root user
$ pkexec /gnu/store/rssyvyd0dj0j5jqkmir0najq1rcd72il-gnome-settings-daemon-3.18.2/libexec/gsd-backlight-helper --set-brightness 500
$
That last pkexec call checked remotely if polkit allowed this
invocation, and whee, it did, so pkexec did a setuid() to root and
invoked the binary:
$ tail /var/log/secure
[...]
Mar 6 19:12:34 localhost pkexec: pam_unix(polkit-1:session): session opened for user root by (uid=1000)
Mar 6 19:12:34 localhost pkexec[1885]: wingo: Executing command [USER=root] [TTY=/dev/pts/0] [CWD=/home/wingo/src/elogind] [COMMAND=/gnu/store/rssyvyd0dj0j5jqkmir0najq1rcd72il-gnome-settings-daemon-3.18.2/libexec/gsd-backlight-helper --set-brightness 500]
This is the exact mechanism that gnome-settings-daemon uses to set the
backlight, so we are doing great!
This isn't just theoretical; gnome-settings-
./plugins/power/gpm-common.c:514: command = g_strdup_printf ("pkexec " LIBEXECDIR "/gsd-backlight-helper --%s %i",
2. How elogind maps PIDs to sessions
------------------------------------
Systemd uses cgroups in two ways: one, to organize the tree of processes
into users, slices, machines, sessions, and scopes; and two, to allow
the user to balance resource usage between users, slices, etc.
In contrast, elogind only uses cgroups to organize processes, and since
it doesn't try to control resource usage, it can just organize them into
sessions. It turns out that you can make cgroups that are just for
organization, not for controlling any particular resource. (See
http://0pointer.de/blog/projects/cgroups-vs-cgroups.html, for more.)
So that's what elogind does. When pam_elogind tells the logind about a
new session, elogind will create a new cgroup for that session and
migrate the session leader into the new cgroup, assuming that the only
process in the session is the session leader. From then on, all
children of that PID, even if they double-fork, are marked as being in
the e.g. /sys/fs/cgroups/elogind/c1 cgroup.
And yes, the interface to cgroups really is the file system. Pretty
weird. The other cgroups that correspond to resource controllers like
"cpuset" and "memory" have their own mounts, eg /sys/fs/cgroups/memory.
So one of these patches adds a mount for the elogind cgroup hierarchy.
From then on out, to know what cgroup a process is in, you just cat a
special file in /proc. For example:
$ cat /proc/$(pgrep gnome-terminal)/cgroup
10:name=elogind:/c1
9:cpuset:/
8:cpu:/
7:cpuacct:/
6:memory:/
5:devices:/
4:freezer:/
3:blkio:/
2:perf_event:/
1:hugetlb:/
So my gnome-terminal is running in cgroup /c1, which because elogind
controls that cgroup tree, we interpret to mean that it is running in
the "c1" session. Voilà.
Conversely to know what PIDs are in a session:
$ cat /sys/fs/cgroup/elogind/c1/cgroup.procs
346
411
420
[...]
3. Caveats
----------
Polkit 0.113 broke "pkexec" in the case where your desktop environment
didn't already install a polkit authentication agent.
The background is, it's usually graphical applications that want to do
things on your behalf as root or some other user, and you might need to
authenticate yourself or even authenticate as root to do the action.
However it would be ~~~~~clownshoes pants-on-fire zaniness~~~~~~~ if
apps popped up dialog boxes asking you to put in the root password.
Probably those apps have security vulnerabilities, and it can be hard to
know if you should trust the app with those credentials, or trust the
app as root, or trust that the permissions it appears to be asking you
for correspond with what it's actually going to do. So desktop
environments ship graphical authentication agents that are carefully
coded to be able to use credentials in a very limited way: only to
*answer* the polkit daemon's query that a user is authenticated.
But in the absence of such an auth agent, it could be that pkexec has to
install one on its own, to allow you to enter your password on the
console. It's setuid IPC madness but I have followed most of the code
paths and I am OK with it.
But, this fallback console agent is broken in 0.113:
https://bugs.freedesktop.org/show_bug.cgi?id=90837. So should polkit
need to ask you for a password, it will take your password but then fail
to authenticate. I have a patch to fix it:
http://thread.gmane.org/gmane.comp.gnu.guix.devel/16906 but probably
something else will go upstream (check that bug).
For the specific permissions about the backlight helper, you need
http://thread.gmane.org/gmane.comp.gnu.guix.devel/16937. Need to push
that one along.
Finally to actually have your backlight keys work, there is something
still missing -- gnome-settings-daemon has to run and I don't have that
fully working yet. Perhaps some other brave soul will get on this :)
Happy hacking,
Andy