Move login state, authentication, discovery, input, rendering, and tests into focused TUI modules. Add detailed CLI error reports with recovery commands, align the build and host-check documentation, and keep the legacy Go tree outside normal builds. Checks: make check; make integration-test; go test ./... (legacy/go).
209 lines
8.7 KiB
Markdown
209 lines
8.7 KiB
Markdown
# Latchd guide
|
|
|
|
Latchd is a terminal login manager for Linux. It starts on a virtual terminal, gives you a keyboard-first screen, and starts the shell or desktop you select.
|
|
|
|
The service is small on purpose: systemd gives it the terminal, the login stack checks the account, and latchd handles the screen plus the process handoff. The [configuration reference](configuration.md) lists every field, while the [architecture notes](architecture.md) explain the Rust workspace.
|
|
|
|
## What starts when
|
|
|
|
The service unit starts `/usr/bin/latchd` as root on `/dev/tty2`. The default configuration file is `/etc/latchd/config.toml`.
|
|
|
|
The screen contains these parts:
|
|
|
|
- A list of desktop and shell sessions.
|
|
- An account field.
|
|
- A password field.
|
|
- A status line.
|
|
|
|
Use the screen in this order:
|
|
|
|
- Select an account.
|
|
- Select a desktop or shell.
|
|
- Enter the password.
|
|
- Press Enter.
|
|
- Enter a new password if the login stack requests one.
|
|
|
|
After login, latchd performs these actions:
|
|
|
|
- Build an environment for the selected account and session.
|
|
- Open the session.
|
|
- Start the selected child with the account credentials.
|
|
- Wait for the child to exit.
|
|
- Close the session.
|
|
|
|
Session-specific setup works as follows:
|
|
|
|
- X11 uses a temporary authority file.
|
|
- Wayland receives the session values that it needs.
|
|
- A TTY session starts the account shell.
|
|
|
|
```text
|
|
Start latchd
|
|
|
|
|
v
|
|
Show accounts and sessions
|
|
|
|
|
v
|
|
Select account, session, and password
|
|
|
|
|
v
|
|
Press Enter
|
|
|
|
|
v
|
|
Check the password and account state
|
|
|
|
|
+------------------------------+
|
|
| |
|
|
v v
|
|
Login accepted New password required
|
|
| |
|
|
| v
|
|
| Show new password field
|
|
| |
|
|
| v
|
|
| Submit the password change
|
|
| |
|
|
+--------------+---------------+
|
|
|
|
|
v
|
|
Build the session environment
|
|
|
|
|
v
|
|
Open the session
|
|
|
|
|
v
|
|
Start the child
|
|
|
|
|
v
|
|
Wait for exit
|
|
|
|
|
v
|
|
Close the session
|
|
```
|
|
|
|
## Service mode and preview mode
|
|
|
|
Service mode needs root, a controlling terminal, and a system configuration file with safe ownership. It can authenticate users and start sessions.
|
|
|
|
Preview mode is for local work; it draws the screen, discovers the configured entries, and reads the user configuration, but it does not authenticate or start a child process.
|
|
|
|
```sh
|
|
make build
|
|
./build/latchd --preview --no-log
|
|
```
|
|
|
|
Use the non-interactive checks when you only need a result:
|
|
|
|
```sh
|
|
./build/latchd --preview --show-config --no-log
|
|
./build/latchd --preview --no-tui --no-log
|
|
```
|
|
|
|
`--show-config` prints the build information plus the selected terminal, service name, and shell. `--no-tui` validates the configuration and runs session preflight without opening the screen.
|
|
|
|
## Build from source
|
|
|
|
Install Rust 1.88 and the PAM development files. On Debian or Ubuntu, use:
|
|
|
|
```sh
|
|
sudo apt-get install build-essential pkg-config libpam0g-dev libpam-modules
|
|
```
|
|
|
|
The toolchain file selects Rust 1.88 and the required `rustfmt` and `clippy` components. Build the optimized binary with:
|
|
|
|
```sh
|
|
make build --release
|
|
```
|
|
|
|
The output is at `build/latchd`, `make build` also embeds the version, commit, and build time.
|
|
|
|
Run `make check` for verification and `make package` to create a tarball with the binary, the system configuration, and the systemd unit. The `make install` target writes the files to the system.
|
|
|
|
The commands and the container workflow are in [Development and release](development.md).
|
|
|
|
## Install and start the service
|
|
|
|
Use a disposable machine first and keep another way to log in while you change the display manager:
|
|
|
|
```sh
|
|
sudo make install
|
|
sudo systemctl enable latchd.service
|
|
sudo systemctl start latchd.service
|
|
```
|
|
|
|
The install target writes the binary, the system TOML file, the login policy, the session-script directories, and the systemd unit. It does not disable another display manager, so stop the service that already owns the target VT before you start latchd there.
|
|
|
|
The supplied unit owns `tty2`. If you move it, change `tty` in the TOML file and `TTYPath` in the unit together; otherwise the values passed to the login stack and the terminal will disagree.
|
|
|
|
Use `sudo systemctl status latchd.service` and `sudo journalctl -u latchd.service -b --no-pager` when the unit fails before the screen appears.
|
|
|
|
## Configuration files
|
|
|
|
The service default is `/etc/latchd/config.toml`. Preview mode first checks `$XDG_CONFIG_HOME/latchd/config.toml`, then `~/.config/latchd/config.toml`, and finally the system file; `--config PATH` overrides all of them.
|
|
|
|
Create the user file with:
|
|
|
|
```sh
|
|
make install-user
|
|
```
|
|
|
|
The target creates the directory with mode `700` and the file with mode `600`, and it leaves an existing file unchanged. Read [Configuration reference](configuration.md) before you add a variable file or change a path used by the service.
|
|
|
|
The main sections are:
|
|
|
|
| Section | What it controls |
|
|
| --- | --- |
|
|
| `[accounts]` | NSS account list, shadow status, and faillock display |
|
|
| `[x11]` | X server, authority tool, desktop entries, and scripts |
|
|
| `[wayland]` | Wayland desktop entries and scripts |
|
|
| `[environment_switcher]` | TTY entry and last-session file |
|
|
| `[visual]` | Wallpaper, animation, notices, and motion setting |
|
|
| `[power_controls]` | Confirmed programs bound to F1 through F12 |
|
|
|
|
## Accounts and sessions
|
|
|
|
Account discovery starts with NSS and then removes entries below `minimum_uid`, entries in `excluded_users`, accounts with a no-login shell, and homes with unsafe ownership or write permission. Set `enumerate = false` when you want a blank list and manual username entry.
|
|
|
|
The screen can show password expiry, account expiry, lock state, and inactivity from the configured shadow file. It can also call `faillock` for the selected name; the query has a 750 millisecond limit and a failed query only removes the extra status text.
|
|
|
|
Session discovery reads `.desktop` files from the X11 and Wayland directories, then reads executable files from the matching script directories. Files must belong to root and must not be writable by group or other users. A desktop entry with `Hidden=true`, `NoDisplay=true`, an invalid `Exec`, or an unavailable `TryExec` is skipped.
|
|
|
|
Latchd stores desktop commands as argument lists, so shell operators and desktop field codes do not run. A script entry uses the file path as its command. The TTY shell appears when `include_tty_shell = true`, and it also appears when no other session exists.
|
|
|
|
## The session environment
|
|
|
|
The child starts with an empty environment, then receives terminal locale values, account paths, XDG directories, session type, seat, VT number, and the selected desktop values. The account UID, primary GID, and supplementary groups are set before the child runs.
|
|
|
|
X11 starts the configured server on the selected VT, waits for its readiness signal, creates a private authority file, and removes that file after the client exits. Wayland starts the selected program but does not start a compositor. TTY mode attaches the shell to the controlling terminal.
|
|
|
|
The session records a UTMPX user process when the platform supports it. A last-session file can remember the successful choice for each account; the file is bounded and replaced atomically.
|
|
|
|
## Logs and useful paths
|
|
|
|
The example file uses these paths:
|
|
|
|
| Path | Use |
|
|
| --- | --- |
|
|
| `/var/log/latchd.log` | Main service and audit output |
|
|
| `/var/log/latchd.client.log` | Graphical session output |
|
|
| `/var/log/latchd.xorg.log` | X server output |
|
|
| `/var/lib/latchd/last-session.toml` | Last session per account |
|
|
| `/etc/latchd/wms/` | X11 script entries |
|
|
| `/etc/latchd/wayland/` | Wayland script entries |
|
|
|
|
The service creates log files with mode `600` and rejects a main log larger than 64 MiB. Audit lines include the action, result, account, and a short reason; passwords and command arguments stay out of the log.
|
|
|
|
## When a session does not start
|
|
|
|
Check the config and the paths first:
|
|
|
|
```sh
|
|
./build/latchd --preview --show-config --no-log
|
|
./build/latchd --preview --no-tui --no-log
|
|
make system-e2e
|
|
```
|
|
|
|
Then check the desktop file, the executable named by `Exec` or `TryExec`, the account home permissions, and the service log. For X11, check the X server and `xauth` paths; for Wayland, check the compositor and its user service outside latchd.
|
|
|
|
Use [End-to-end testing](e2e-testing.md) when the host is a container or when you need a disposable VM for the terminal and display stack.
|