[OpenAFS] Linux: systemctl --user vs. AFS

Gaja Sophie Peters gaja.peters@math.uni-hamburg.de
Sat, 17 Mar 2018 16:09:25 +0100


Am 08.03.2018 um 20:08 schrieb Jonathan Billings:
> There's a google doc in the Debian bug that I wrote 
> (https://docs.google.com/document/d/1P27fP1uj-C8QdxDKMKtI-Qh00c5_9zJa4YHjnpB6ODM/pub), 
> which was to create an /etc/systemd/user/aklog.service that is 
> automatically started as part of the login, 

I did some testing on Ubuntu 18.04 alpha (or beta?), and ran into the
same problem, which I solved with a variant of the above, which seems to
work for the time being.
The systemd-file itself goes to
	/etc/systemd/user/aklog.service

The link to start it goes to
	/etc/systemd/user/default.target.wants

Main advantage of course, that you don't have to make your
AFS-Homedirectory world-readable...

> what it does is runs an    
> aklog so that the processes started by systemd --user have tokens.  This 
> assumes that it's got its own keyring.

This seems to work. "xterm" and "gnome-terminal" are still in separate
PAGs, but since both can read the Kerberos-Ticket, both can get the
AFS-Token. I added an "unlog" to ExecStop, so that the Token will be
destroyed on logout. Without that, the once-obtained token will remain,
even after logout and immidiate re-login. (Tested with manual,
non-scripted aklog...)

> This works, to a certain extent.  I also have a startup script that I 
> wrote that runs dbus-monitor to watch org.gnome.ScreenSaver, and restart 
> the aklog.service user service every time you unlock the screensaver, so 
> those tokens get renewed with the updated krb5 credentials.

I tried to combine both parts into a single "aklog.service" file (see
below). I don't know much about systemd and even less about dbus, so
there might be things that are backwards... An added complication for me
was that at the point where I wanted the aklog.service to be executed,
the environment-variable KRB5CCNAME wasn't yet set, so I used a somewhat
hackish fragment to construct the variable from the file that existed
already in /tmp.

File /etc/systemd/user/aklog.service
>>>>>>>>>>>>>>>>>>>>>
[Unit]
Description=aklog for session --user
Before=gnome-keyring-ssh.service

[Service]
Type=simple
ExecStartPre=/bin/sh -c ' \
	KRB5CCNAME=FILE:$(ls -t /tmp/krb5cc_${XDG_RUNTIME_DIR#/run/user/}*|head
-1) aklog -d'
ExecStart=/bin/sh -c ' \
	dbus-monitor --profile path=/org/freedesktop/secrets/collection/login | \
		while read TYPE LINE; \
		do \
			[ "$TYPE" = "mc" ] && systemctl --user reload aklog; \
		done'
ExecReload=/usr/bin/aklog
ExecStop=/usr/bin/unlog

[Install]
WantedBy=default.target
>>>>>>>>>>>>>>>>>>>>>

Explanation: the dbus-monitor needs to run all the time for new logins,
so I made it the main-process of the service. Before that, aklog needs
to be started with a (re-)constructed KRB5CCNAME which is at that time
missing from the environment, so I look for the newest krb5cc-file with
the current user-ID in /tmp. The user-ID itself doesn't exist in the
environment at that point, only the username (in $LOGNAME and $USER),
however the userid is found as part of the $XDG_RUNTIME_DIR, so I used that.

The dbus-monitor watches "something" that seems to be called exactly
once on each login - no idea if there are better things to watch for
(disadvantage of screensaver seemed to be that there are two lines, one
for locking, one for unlocking). The first few returned lines start with
"sig" or "#" and aren't interesting, the interesting lines have "mc" as
their first word and will reload the aklog.service (KRB5CCNAME doesn't
need to be set again).

When the service ends, unlog will destroy the AFS-Token. For the
"Before=" line, I simply looked for something that was run fairly early
in the boot-process and told systemd, I want to run even before that.

Greetings,
Gaja Peters

P.S. I have tested this ONLY in Ubuntu 18.04, it might be completely
different in another system! D-Bus might have to be monitored for
something else, and the variable XDG_RUNTIME_DIR might point to
something different.