Skip to content

pam_oo7 fails to unlock keyring under greetd due to hardcoded paths and missing environment variables in execv #516

Description

@jexjws

Describe the bug

When using pam_oo7.so on my Arch Linux with greetd, the keyring auto-unlock fails during login. Checking the system log shows:

greetd[17421]: Connecting to daemon socket at: /run/user/1000/oo7-pam.sock
greetd[17421]: Socket not found, attempting to start daemon
greetd[17421]: Attempting to start oo7-daemon directly
greetd[17421]: Started oo7-daemon with PID 17434
...
greetd[17421]: Failed to send message in child process: Failed to connect to daemon socket: No such file or directory (os error 2)
greetd[17333]: Failed to send secret to oo7 daemon: Failed to connect to daemon socket: Child process failed with exit code 1

There are two causes for this:

1. Hardcoded daemon/helper paths

In the codebase (e.g., pam/src/socket.rs v0.6.0 ), the daemon path is hardcoded as:

   let daemon_path = c"/usr/bin/oo7-daemon".as_ptr();

However, on distributions like Arch Linux, the packaging script compiles the server using Meson with --libexecdir=lib , which installs the daemon at /usr/lib/oo7-daemon .
Bypassing Meson's directory variables by hardcoding path strings inside the Rust code makes the PAM module unable to find the executable, resulting in instant startup failure.

My Workaround: On Arch Linux, creating a symbolic link from the hardcoded path to the actual installation path resolves the "file not found" crash:

ln -s /usr/lib/oo7-daemon /usr/bin/oo7-daemon

(Note: In the current master branch, the helper path is still hardcoded as c"/usr/libexec/oo7-daemon-login" , which will still fail on Arch for the same reason.)

2. Environment inheritance with execv

When pam_oo7.so forks and executes the daemon/helper, it uses libc::execv , inheriting the parent process's (the display manager, e.g., greetd ) environment. During the PAM session opening
phase, the environment variables HOME and XDG_RUNTIME_DIR for the target user are missing or set to the display manager's paths (e.g., /var/lib/greetd or /root ).
When the daemon starts up as the target user (UID 1000) but inherits HOME=/root , it attempts to read/write directories it does not have permission to, causing it to crash with exit code 1.

My Workaround: Replacing /usr/bin/oo7-daemon with a thin wrapper script that explicitly resolves and injects the correct user environment before executing the real daemon fixes the crash:

#!/bin/bash
USER_UID=$(id -u)
if [ "$USER_UID" -ge 1000 ]; then
    USER_NAME=$(id -un)
    export USER="$USER_NAME"
    export LOGNAME="$USER_NAME"
    export HOME=$(getent passwd "$USER_NAME" | cut -d: -f6)
    export XDG_RUNTIME_DIR="/run/user/$USER_UID"
fi
exec /usr/lib/oo7-daemon "$@"

After replacing /usr/bin/oo7-daemon with this script, the system log confirms a successful unlock on login:

greetd[17333]: Successfully sent secret to oo7 daemon for user: voyage200

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't workingserver

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions