elogind status

From:

Andy Wingo

Subject:

elogind status

Date:

Fri, 21 Aug 2015 12:33:46 +0200

User-agent:

Gnus/5.13 (Gnus v5.13) Emacs/24.5 (gnu/linux)

Hi :)
To pick up a thread from May, I was poking at elogind recently. A bit
of recap as to how things got here, then the status.
To recall: by default on a Unix system, the user has full control over
their space, but can't do very much about the system itself. When D-Bus
came along, more and more system services were exposing interfaces
allowing users to take actions on the system, but that bent the policy
too far towards the user -- the admin had no control. So things started
going the other way again, with PolicyKit brokering privileged actions,
and the admin could specify rules saying under what conditions a user
would be able to take a privileged action, such as rebooting the system,
inhibiting suspend, etc.
One of the conditions that PolicyKit can use to determine whether an
action is authorized or not is knowing whether the user is physically
sitting in front of the computer or not. This information used to be
maintained by ConsoleKit, which implemented login tracking by running a
wrapper around sessions -- like ck-launch-session. It exposed a D-Bus
interface that programs could query.
But ConsoleKit is unmaintained now. The CK developers joined the
systemd team, and shifted to work on logind, which is a part of systemd.
Logind tracks sessions by integrating with PAM -- every time a user logs
in, logind can know it, add some metadata to their PAM session, and
likewise for logout. This also lets logind know how they log in --
graphically, at the console, remotely, etc. Logind exposes a C API, in
practice these days part of libsystemd, but it's more common for
programs to use logind's D-Bus API.
I want GNOME on Guix :) GNOME used to support ConsoleKit but doesn't
any more. There is a ConsoleKit2 project that started recently but
without buy-in from GNOME I don't see a future for it. GNOME really
needs the org.freedesktop.login1 D-Bus interface -- really wants it. So
I thought, OK, let's pull logind out of systemd, and see where that gets
us.
The result is https://github.com/andywingo/elogind. It provides:
* a logind-compatible API with a different library name, libelogind
* a pkg-config file, libelogind.pc
* a daemon, elogind
* a PAM module, pam_elogind.so
* a query/control utility, loginctl
It might be worth it to install more compatibility interfaces for
systemd, e.g. libsystemd.so, or a symlink for <systemd/sd-login.h> to go
to <elogind/sd-login.h>. Or perhaps we should just provide the systemd
header files with the systemd names. In practice this means that
building packages that use the C interfaces need a bit more munging in
Guix to replace names.
In the patches I sent to this list, we have also a service which runs
elogind, and the facilities to integrate pam_elogind.so with the rest of
the system. The PAM integration is really horrible and I'd be
interested in other options; see footnote for my os-config.scm.
Upstream logind integrates with systemd to ensure that user sessions are
run in cgroups, which is a pretty neat feature. They manage cgroups
with a hierarchical "slice" abstraction. Perhaps DMD should do this at
some point. Using cgroups also lets logind know when a process was
started by a user but the user has logged out, and optionally lets the
administrator kill user processes when they log out. So, elogind will
expose information about users, sessions, and seats, but for now not
slices. Most logind users don't care so this is OK.
Andy
[*] Configuring elogind
First of all you need some extra file systems. These paths provide a
documented interface to logind information:
(file-system
(device "systemd")
(mount-point "/run/systemd")
(type "tmpfs")
(check? #f)
(flags '(no-suid no-dev no-exec))
(options "mode=0755")
(create-mount-point? #t))
(file-system
(device "systemd")
(mount-point "/run/user")
(type "tmpfs")
(check? #f)
(flags '(no-suid no-dev no-exec))
(options "mode=0755")
(create-mount-point? #t))
Since elogind wants to manage the content of these directories, it has a
little internal rm-rf helper to clean them when elogind starts up. But
that helper is really conservative and doesn't want to remove files on a
filesystem that's not tmpfs or ramfs, hence these mounts.
Secondly you need to configure a pam-elogind module.
(define pam-elogind
(pam-entry
(control "required")
(module #~(string-append #$elogind "/lib/security/pam_elogind.so"))))
We add the pam module to the base pam services:
(pam-services
(base-pam-services #:additional-session-modules (list pam-elogind)))
Now we have to add that module to *all* services that can log in that
elogind should know about :( In my case:
(services
(let ((motd (text-file "motd" "
This is the GNU operating system, welcome!\n\n")))
(list (console-font-service "tty1")
(console-font-service "tty2")
(console-font-service "tty3")
(console-font-service "tty4")
(console-font-service "tty5")
(console-font-service "tty6")
(mingetty-service "tty1" #:motd motd #:additional-session-modules
(list pam-elogind))
(mingetty-service "tty2" #:motd motd #:additional-session-modules
(list pam-elogind))
(mingetty-service "tty3" #:motd motd #:additional-session-modules
(list pam-elogind))
(mingetty-service "tty4" #:motd motd #:additional-session-modules
(list pam-elogind))
(mingetty-service "tty5" #:motd motd #:additional-session-modules
(list pam-elogind))
(mingetty-service "tty6" #:motd motd #:additional-session-modules
(list pam-elogind))
(static-networking-service "lo" "127.0.0.1"
#:provision '(loopback))
(syslog-service)
(guix-service)
(nscd-service #:name-services (list nss-mdns))
(lsh-service #:additional-session-modules (list pam-elogind))
(slim-service #:additional-session-modules (list pam-elogind))
(avahi-service)
(wicd-service)
(upower-service)
(colord-service)
(geoclue-service)
(polkit-service)
(elogind-service)
(dbus-service (list avahi wicd upower colord geoclue polkit elogind))
(udev-service #:rules (list lvm2 fuse alsa-utils upower colord
elogind)))))
It's a bit of a cross-cutting concern and I don't know what to do about
it exactly. But, with all of this, and the patches I have sent,
pam_elogind.so does tell logind about users. I rewired polkit to use
elogind for console information but I haven't tried going back up the
stack to get a GNOME session. Future work, I guess, and help is very
much welcome :) If you are interested in hacking on elogind I am sure
you will find things to do. Let me know and I'll add you to the
maintainers.
Cheers,
Andy