I E

Troubleshooting LightDM's test mode

3 August, 2024

Recently I’ve been tweaking the appearance of my desktop environment, which consists of XMonad and Taffybar, with LightDM as the display manager, all tied together using NixOS and home-manager.

Taffybar was very easy to customise because it uses a single CSS file. XMonad was also not too bad, but needs a custom X compositor to get really nice results (I’m using picom). LightDM is the last thing on my list.

If I’m going to be tweaking my greeter’s appearance, I don’t want to repeatedly log in and out to test it. I’d like to preview the changes in a window while I’ve got my editor open in another.

LightDM on ArchWiki says to run lightdm --test-mode, but this didn’t work for me.

Summary

Symptoms

Solution

Run xhost +SI:localuser:lightdm to allow the lightdm user to connect to the X user, then run sudo -u lightdm --test-mode.

Details

When I ran lightdm --test-mode a small black window briefly appeared and then the program exited with status 1. I added the --debug flag, and saw that a subprocess had failed:

$ lightdm --test-mode --debug
...
[+0.07s] DEBUG: Session pid=29039: Started with service 'lightdm-greeter', username '{my username}'
[+0.08s] DEBUG: Session pid=29039: Authentication complete with return value 0: Success
[+0.08s] DEBUG: Seat seat0: Session authenticated, running command
[+0.08s] DEBUG: Session pid=29039: Not setting XDG_VTNR
[+0.08s] DEBUG: Session pid=29039: Running command /nix/store/ikwkdnyzd8xflr3j7cabmy6vr3srvp3j-lightdm-gtk-greeter-2.0.8/bin/lightdm-gtk-greeter
[+0.08s] DEBUG: Creating shared data directory /var/lib/lightdm-data/{my username}
[+0.08s] WARNING: Could not create user data directory /var/lib/lightdm-data/{my username}: Error creating directory /var/lib/lightdm-data/{my username}: Permission denied
[+0.08s] DEBUG: Session pid=29039: Logging to /home/{my username}/.cache/lightdm/log/seat0-greeter.log
[+0.08s] DEBUG: Greeter closed communication channel
[+0.08s] DEBUG: Session pid=29039: Exited with return value 1
...

The output also told me where the subprocess stored its logs, so I checked there:

$ cat /home/{my username}/.cache/lightdm/log/seat0-greeter.log
Failed to open PAM session: Authentication failure

A PAM error.

man pam says that PAM errors are often logged to syslog, so I checked the systemd journal:

$ journalctl --user -b -r -g pam -n 10
Aug 03 11:22:44 {my hostname} lightdm[29039]: pam_systemd(lightdm-greeter:session): Failed to create session: Access denied
Aug 03 11:22:44 {my hostname} lightdm[29039]: pam_succeed_if(lightdm-greeter:session): requirement "user = lightdm" not met by user "{my username}"
...

It seems that LightDM doesn’t like being run as a normal user, and would rather be run as the lightdm user. I found that the LightDM README actually has a note about using sudo -u lightdm for --test-mode, so I tried it:

$ sudo -u lightdm lightdm --test-mode --debug
[+0.00s] DEBUG: Logging to /var/lib/lightdm/.cache/lightdm/log/lightdm.log
[+0.00s] DEBUG: Starting Light Display Manager 1.32.0, UID=78 PID=30100
...
[+0.00s] DEBUG: Loading configuration from /etc/lightdm/lightdm.conf
[+0.00s] DEBUG: Running in user mode
[+0.00s] DEBUG: Using Xephyr for X servers
...
[+0.00s] DEBUG: Using D-Bus name org.freedesktop.DisplayManager
...
[+0.00s] DEBUG: Seat seat0: Starting
[+0.00s] DEBUG: Seat seat0: Creating greeter session
[+0.00s] DEBUG: Loading users from org.freedesktop.Accounts
[+0.00s] DEBUG: Seat seat0: Creating display server of type x
[+0.00s] DEBUG: Seat seat0: Starting local X display
[+0.01s] DEBUG: XServer 1: Logging to /var/lib/lightdm/.cache/lightdm/log/x-1.log
[+0.01s] DEBUG: XServer 1: Writing X server authority to /var/lib/lightdm/.cache/lightdm/run/root/:1
[+0.01s] DEBUG: XServer 1: Launching X Server
[+0.01s] DEBUG: Launching process 30107: /run/current-system/sw/bin/Xephyr :1 -seat seat0 -auth /var/lib/lightdm/.cache/lightdm/run/root/:1 -nolisten tcp
[+0.01s] DEBUG: XServer 1: Waiting for ready signal from X server :1
Failed to get D-Bus connection

That didn’t work either. I checked the X server logs that were generated:

$ sudo cat /var/lib/lightdm/.cache/lightdm/log/x-1.log
Authorization required, but no authorization protocol specified


Xephyr cannot open host display. Is DISPLAY set?

I didn’t undertand what this meant. Is DISPLAY set?

$ sudo -u lightdm env | rg DISPLAY
DISPLAY=:0

It is. I was stumped.

After lots of searching and browsing, a Kagi search for lightdm --test-mode turned up Problems with lightdm test mode - Raspberry Pi Forums, which lead to Capture Your LightDM Login Screen in Ubuntu Unity | UbuntuHandbook, which uses a variation of sudo -u lightdm lightdm --test-mode after calling xhost +SI:localuser:lightdm.

man xhost says:

The xhost program is used to add and delete host names or user names to the list allowed to make connections to the X server. In the case of hosts, this provides a rudimentary form of privacy control and security. It is only sufficient for a workstation (single user) environment, although it does limit the worst abuses. Environments which require more sophisticated measures should implement the user-based mechanism or use the hooks in the protocol for passing other authentication data to the server.

That seemed promising.

$ xhost +SI:localuser:lightdm
localuser:lightdm being added to access control list

Running LightDM again worked!

$ sudo -u lightdm lightdm --test-mode --debug
...
[+0.09s] DEBUG: Session pid=40112: Started with service 'lightdm-greeter', username 'lightdm'
[+0.09s] DEBUG: Session pid=40112: Authentication complete with return value 0: Success
[+0.09s] DEBUG: Seat seat0: Session authenticated, running command
[+0.09s] DEBUG: Session pid=40112: Not setting XDG_VTNR
[+0.09s] DEBUG: Session pid=40112: Running command /nix/store/ikwkdnyzd8xflr3j7cabmy6vr3srvp3j-lightdm-gtk-greeter-2.0.8/bin/lightdm-gtk-greeter
[+0.09s] DEBUG: Creating shared data directory /var/lib/lightdm-data/lightdm
[+0.09s] DEBUG: Session pid=40112: Logging to /var/lib/lightdm/.cache/lightdm/log/seat0-greeter.log
[+0.16s] DEBUG: Greeter connected version=1.32.0 api=1 resettable=false
[+0.35s] DEBUG: Greeter start authentication
[+0.35s] DEBUG: Session: Not setting XDG_VTNR
[+0.35s] DEBUG: Session pid=40144: Started with service 'lightdm', username '(null)'
[+0.35s] DEBUG: Session pid=40144: Got 1 message(s) from PAM
[+0.35s] DEBUG: Prompt greeter with 1 message(s)

My greeter appeared in a small window. I don’t know what the fundamental problem was; I know basically nothing about this area of Linux. I’ll probably learn more about it one day. For now I’m content with having fixed my issue.