exec login replaces your current shell outright, so getting it wrong on a remote box can lock you out for good. This guide gets you starting a local login session correctly, understanding the environment values it sets, and maintaining the message shown after authentication.
The examples match shadow-utils 4.13, installed here as package login version 1:4.13+dfsg1-4ubuntu3.2. Allow about fifteen minutes. You need a shell account, and elevated privileges only for the configuration checks or changes marked as such.
Checkpoint: This guide is about the installed login program, not SSH authentication or a display manager. Do not test it on a production terminal by guessing at options. A login replaces the current shell and can make a mistake inconvenient to undo.
Check which executable is selected. This is read-only and does not need elevated privileges:
$ command -v login
/usr/bin/login
$ dpkg-query -W -f='${Package} ${Version}\n' login
login 1:4.13+dfsg1-4ubuntu3.2
The normal caller is getty, which displays a login: prompt on a terminal. From a shell, the documented form is exec login. The exec matters: it replaces the current shell, so the old user cannot return to that shell once the new session ends.
Security warning: Do not run this on a remote maintenance shell unless you have another confirmed way back in. If you are deliberately changing user in a controlled terminal, replace ACCOUNT_NAME with the account you intend to use:
$ exec login ACCOUNT_NAME
Expect a password prompt, followed by the account's login shell. A password is not printed while it is read. If the account is subject to password ageing, login may require the old and new passwords before starting the shell.
After signing in, inspect the values that matter to scripts and interactive tools:
$ id
$ printf 'user=%s\nhome=%s\nshell=%s\npath=%s\nlogname=%s\nmail=%s\n' \
"$USER" "$HOME" "$SHELL" "$PATH" "$LOGNAME" "$MAIL"
$ pwd
$ printf 'umask=%s\n' "$(umask)"
HOME, SHELL, PATH, LOGNAME and MAIL come from the account data and login configuration.Checkpoint: pwd should normally equal $HOME. If it does not, check the home directory and the account entry before changing shell startup files. By default, DEFAULT_HOME is no: if the home directory cannot be entered, login refuses the session. Setting it to yes permits a session in / instead, which can hide a broken home directory and is rarely the right first fix.
Inspect the active values as root because the file is system configuration. This command only reads it:
$ sudo grep -E '^(ENV_PATH|ENV_SUPATH|DEFAULT_HOME|LOGIN_RETRIES|LOGIN_TIMEOUT|HUSHLOGIN_FILE|TTYGROUP|TTYPERM|LOG_OK_LOGINS|LOG_UNKFAIL_ENAB)[[:space:]]' /etc/login.defs
In this installation, ENV_PATH supplies the regular-user path and ENV_SUPATH supplies the superuser path. The file uses whitespace-separated names and values; blank lines and lines whose first non-whitespace character is # are ignored. Boolean values are yes or no, and numbers can be decimal, octal with a leading 0, or hexadecimal with 0x.
Do not assume every authentication setting lives here. The manpage says PAM commonly overrides retry handling, and much of the old shadow functionality is now handled by PAM. Check the relevant files under /etc/pam.d/ when diagnosing authentication, retry limits or password prompts. This read-only check shows the login PAM stack:
$ sudo sed -n '1,160p' /etc/pam.d/login
Warning: Options -h, -r and -f are restricted to root. The -f option skips authentication for a preauthenticated user, so treat it as a privileged integration interface, not as a quicker login. Never place it in a general-purpose wrapper or accept its username from an untrusted input.
After a successful login, PAM's pam_motd displays /etc/motd before the login shell runs. Debian also permits dynamic content configured through /etc/pam.d/login, including content supplied by pam_exec. This is why the text you see need not all come from one file.
Read the static file without changing it:
$ sudo sed -n '1,160p' /etc/motd
$ sudo grep -nE 'motd|pam_exec' /etc/pam.d/login
If the file is absent, the static part may simply be empty. If output still appears, inspect the PAM configuration and any referenced dynamic command. Treat dynamic login output as executable configuration: review ownership, permissions and the command's inputs before adding it.
Only do this when you intend to change what every successful local login sees. It requires elevated privileges and changes a system-wide file. Save a dated copy first, write a temporary file in the same directory, then install it with a root-owned mode:
$ sudo cp -p /etc/motd /etc/motd.backup-2026-09-24
$ cat > /tmp/motd.new <<'EOF'
Maintenance window: check the change record before restarting services.
EOF
$ sudo install -o root -g root -m 0644 /tmp/motd.new /etc/motd
$ sudo sed -n '1,20p' /etc/motd
Replace the backup date with the current date on your system. Remove the temporary file after checking the result:
$ rm -- /tmp/motd.new
Recovery: to undo this exact example, restore the backup as root. Verify the backup path before running the command; do not use a wildcard:
$ sudo install -o root -g root -m 0644 /etc/motd.backup-2026-09-24 /etc/motd
$ sudo sed -n '1,20p' /etc/motd
Do not put passwords, private keys, tokens or sensitive host details in the message. Login output is visible to every account that can authenticate, and may be captured in terminal recordings or support logs.
getty, SSH server or display manager rather than trying to grant the binary extra permissions./etc/passwd entry. Do not enable DEFAULT_HOME yes merely to conceal the fault.ENV_PATH and the shell's startup files. A shell may deliberately replace the value after login sets it./etc/motd with the pam_motd and pam_exec entries in /etc/pam.d/login. The message may be dynamic.login version and its executable path.exec login replaces the current shell.