11

systemctl --user seems to be working fine for the desktop user:

dev@dev-VirtualBox:~$ systemctl --user > /dev/null
dev@dev-VirtualBox:~$ echo $?
0

But when running the same command under the www-data user I get an unexpected response

dev@dev-VirtualBox:~$ sudo su www-data -s /bin/bash
www-data@dev-VirtualBox:~$ systemctl --user > /dev/null 
Failed to connect to bus: No such file or directory 
www-data@dev-VirtualBox:~$ echo $? 
1

How to enable systemctl --user here?

Running Ubuntu 16.04

4 Answers4

18

The per-user instance of systemd is started by a hook into the login process, a pam_systemd PAM, for both ordinary virtual/real terminal login and remote login via SSH and otherwise.

You are not logging in. You are augmenting the privileges of your existing login session with sudo su www-data. (This is redundant, by the way. sudo -u www-data will go straight to www-data without your running commands as the superuser.) You have not invoked the hook.

Therefore www-data's per-user instance of systemd has not been started, and systemctl --user finds nothing to talk to.

You can start it manually:

% sudo install -d -o www-data /run/user/`id -u www-data`
% sudo systemctl start user@`id -u www-data`

(If you have done these in the wrong order, then stop the service and do them in the right order. Doing them in the wrong order ends up in a state where the runtime directory is empty and lacks the D-Bus and other socket files, but the service is running and will never communicate with clients.)

The one niggle is that your DBUS_SESSION_BUS_ADDRESS variable needs to be changed so that Desktop Bus client programs like systemctl talk to the other account's Desktop Bus broker when you are running them with the privileges of that other account:

% sudo -u www-data DBUS_SESSION_BUS_ADDRESS=unix:path=/run/user/`id -u www-data`/bus systemctl --user

This is the simple way. The more complex way is to adjust the PAM configuration so that sudo invokes the pam_systemd hook. However, this has side-effects, particularly with respect to the XDG_RUNTIME_DIR environment variable, that you probably do not desire. Only try this alternative if you are confident that you are alright with the effects of introducing pam_systemd into sudo.

Further reading

JdeBP
  • 68,745
  • Turns out the user@id -u www-data was already installed and running. Also, the /run/user/x/bus socket doesn't exist for any of the users folders present under /run/user. The error I'm seeing is still the same – Jon Skarpeteig Feb 13 '18 at 09:09
  • likely sudo is already configured to use pam_systemd. But pam_systemd does not allow the user to escape the current logind session. See https://github.com/systemd/systemd/issues/7451 – sourcejedi Feb 13 '18 at 09:41
  • No, pam_systemd is not invoked via the sudo PAM service. That's why I pointed out the complex route of changing that PAM service's configuration so it is, – JdeBP Feb 13 '18 at 12:04
  • 1
    Right :). Correction: sudo is configured to use pam_systemd on Fedora Linux - yet it still does not start a systemd-user instance, by design. (You get a warning about not creating a session because you're already in one, iirc. Debian's approach might be the cleaner one). So I think the "more complex route" is wrong. – sourcejedi Feb 15 '18 at 09:51
  • Yeah I ended up writing a similar response https://serverfault.com/a/1047069 My suggestion is for people to use ssh user@localhost when they need a full-fledged session with systemctl – am70 Dec 21 '20 at 18:27
  • @JdeBP The first link is down… – rugk Sep 15 '21 at 18:20
8

So I was able to figure out the missing piece of the puzzle finally. Thanks to some excellent hints from @JdeBP I was able to determine:

  • systemd --user was running for www-data
  • DBUS_SESSION_BUS_ADRESS seems to be ignored under Ubuntu
  • XDG_RUNTIME_DIR was NOT set

Setting XDG_RUNTIME_DIR to export "/run/user/$UID" solved my issue

Steps I followed to get the intended behavior:

% sudo loginctl enable-linger www-data # Enable systemd --user service to start at boot
% XDG_RUNTIME_DIR="/run/user/$UID" systemctl --user # Access services as www-data without actually logging in
  • 1
    For me, I also needed to apt install libpam-systemd and systemctl restart user@$(id -u www-data). – Dave Dec 20 '18 at 06:02
3

These all are quite ugly workarounds.

As it has been said the issue is:

You are not logging in. You are augmenting the privileges of your existing login session […]

As such, "just" login…

If you are on a server, you need to use the terminal. I had to ask the same question, but finally could find it out. The solution is as easy as running this command to switch to your user (respectively run a proper shell with that user):

$ sudo machinectl shell --uid www-data

Note that sudo loginctl enable-linger www-data is still useful if you intent to start services or so there, in order to have them run at boot. Otherwise, they would only run at "login" of that user.

rugk
  • 3,086
0

As noted in a comment here, you might just be missing the relevant Ubuntu packages that allow running systemctl as user. Just happened to me. To fix:

  1. apt install libpam-systemd

  2. Re-login via SSH as the user that should be able to execute systemctl --user. So, not as root.

Now, echo $XDG_RUNTIME_DIR should work without further steps, showing something like this:

$ echo $XDG_RUNTIME_DIR
/run/user/1012

Ubuntu 18.04 LTS here.

tanius
  • 874