Check Password Expiry Safely with expiry

expiry gives a read-only check of the current account's password expiry status, plus a boundary around its one dangerous mode. That mode forces a password change, so this guide draws a clear line around it. It uses expiry from the Ubuntu passwd package, version 1:4.13+dfsg1-4ubuntu3.2, whose man page identifies the underlying shadow-utils release as 4.13.

Allow about ten minutes. You need a shell and the passwd package. The normal check does not require sudo and does not modify account files. The force mode can start an interactive password change, so do not run it casually on a production shell, in a script, or while demonstrating the command to another user.

1. Confirm the installed command

First confirm which executable and package version you are about to use. These are ordinary, read-only commands:

$ command -v expiry
/usr/bin/expiry
$ dpkg-query -W -f='${Package} ${Version}\n' passwd
passwd 1:4.13+dfsg1-4ubuntu3.2

The installed man page documents expiry as a command that checks and enforces password expiration for the current user. It accepts an option, rather than a username. There is no documented operand for checking another account.

Checkpoint: If command -v expiry returns nothing, stop and install or repair the package through your normal system-management process. Do not copy an unrelated executable into a system path.

2. Run the read-only check

Use --check, or its short form -c, to check the current user's password expiration:

$ expiry --check
$ printf 'exit status: %s\n' "$?"
exit status: 0

On this machine the command produced no normal output and returned status 0. That is a useful result: the check completed successfully. Do not build a script that expects a date or a sentence on standard output, because the local interface does not promise one.

Capture the status immediately if you need to branch on it. A later command would replace $?:

expiry --check
status=$?
if [ "$status" -eq 0 ]; then
    printf '%s\n' 'Password expiry check completed'
else
    printf 'expiry failed with status %s\n' "$status" >&2
    exit "$status"
fi

The man page defines the action, but does not publish a table of distinct exit statuses or a guaranteed text format. Treat a non-zero status as a failed check unless you have verified the exact behaviour of your packaged build. Do not infer 'password expired' solely from silence.

3. See the available syntax

Ask the installed binary for its own help when you need to check spelling or script documentation:

$ expiry --help
Usage: expiry [options]

Options:
  -c, --check                   check the user's password expiration
  -f, --force                   force password change if the user's password
                                is expired
  -h, --help                   display this help message and exit

The spacing in the help output can vary with packaging, but the three options are the important contract in this release. -h and --help display help and exit. They do not inspect or change the account.

4. Understand the force option before using it

expiry --force, or expiry -f, forces a password change if the current user's password is expired. This is an interactive, security-sensitive operation. It can change the password and can leave an unattended script waiting for input, so it is not a suitable monitoring probe.

Warning: Do not use the following command as a harmless test:

$ expiry --force

Run it only when the account owner is present, the password-change policy is understood, and you have an approved recovery path. If you start it by mistake, answer according to your site's normal password-change procedure or use the terminal's interrupt key if it is still waiting for input. If the password has already changed, expiry has no undo operation. Recovery belongs to your administrator or identity provider, not to this command.

The option does not mean 'mark this account as expired' and it does not accept a new password on the command line. It only asks for a change when the current user's password is already expired. Use a dedicated account-management tool, with its own documented safeguards, for planned administrative changes.

5. Keep account inspection separate

expiry reads the account information used to make its decision. The man page names /etc/passwd for user account information and /etc/shadow for secure account information. Do not edit either file by hand to make the result change. A malformed shadow entry can prevent logins and complicate recovery.

If you need to inspect policy details rather than run the check, use the account-management commands and procedures already approved for your distribution. Read access to shadow data is restricted, and adding sudo merely to make a check look more informative can expose sensitive account metadata. Start with the unprivileged command:

$ expiry -c
$ printf 'check status: %s\n' "$?"
check status: 0

Use elevated privileges only for a separate administrative investigation that specifically requires them. expiry itself is documented as callable by a normal user, and the check concerns the current user, not an account selected by an administrator.

6. Account for the upstream version boundary

This guide is deliberately tied to shadow-utils 4.13 as installed here. Upstream shadow-utils later deprecated password ageing facilities, including expiry, in the 4.19 release series. The upstream project planned removal in 4.20. A newer distribution may therefore omit the command or document different policy. Always check expiry --help and the local man page instead of copying this command into a portable deployment script without a version check.

That boundary also explains why a working command on this host is not proof that every current Linux system provides it. For fleet automation, make the absence of expiry an explicit compatibility case and choose a supported account-policy interface for the target distribution.

Done means