Safely Reconcile Debian System Accounts with update-passwd
A daemon can stop starting if update-passwd changes its account underneath it without review. The installed command here is from base-passwd version 3.6.3build1, and this is exactly the kind of accident it exists to control rather than cause.
The route
Jump straight to the step you need, or tick off Done means at the end.
You will compare a running system's /etc/passwd, /etc/shadow and /etc/group against the account masters shipped by base-passwd, inspect any proposed changes, and apply them with a recoverable backup. Allow about fifteen minutes for a normal check, longer if changes are proposed.
- A shell and elevated privileges for the real check, since
/etc/shadowis normally unreadable to ordinary users. - An approved maintenance window and an existing root session kept open, because this touches security-sensitive account databases.
1. Confirm the command and its input files
Start with read-only checks that do not need sudo on a normally configured system:
$ command -v update-passwd
/usr/sbin/update-passwd
$ dpkg-query -W -f='${Package} ${Version}\n' base-passwd
base-passwd 3.6.3build1
$ update-passwd --version
update-passwd 3.6.3build1
The installed defaults are two master copies, /usr/share/base-passwd/passwd.master and /usr/share/base-passwd/group.master, compared against /etc/passwd, /etc/shadow and /etc/group. The tool only considers the global system range, UID and GID 0 through 99: it is not a general account synchroniser for ordinary users.
Checkpoint
Confirm the package version and paths are the ones you actually intend. Do not substitute a hand-edited file as a master unless you have a documented reason and have reviewed every entry in it.
2. Run a sanity check as root
--sanity-check checks the inputs without making any change. Run it with sudo so the shadow database can be opened:
$ sudo update-passwd --sanity-check --verbose
# output depends on the state of this host
$ printf 'exit status: %s\n' "$?"
exit status: 0
On this machine, running the same command without elevated privileges fails while opening /etc/shadow: that is an access problem, not evidence the account files are inconsistent. If your run returns non-zero, read the diagnostic before reaching for a different option.
--verbose prints more detail. Use --verbose --verbose when the first report is not enough.
3. Preview proposed changes
Once the sanity check passes, use --dry-run for the operational preview:
$ sudo update-passwd --dry-run --verbose
# proposed changes, if any, are printed here
$ printf 'exit status: %s\n' "$?"
exit status: 0
Dry-run means the program reports what it would do and leaves the account files alone. Review every proposed addition, removal, UID or GID change, home-directory change, shell change and GECOS change: a change to a low-numbered service account can stop a daemon starting or make files appear to belong to a different numeric identity.
An empty report is not a failure. It normally just means the installed master copies require no update in the global system range.
4. Apply the update only after review
Warning
The next command can modify /etc/passwd, /etc/shadow and /etc/group, and may affect logins, file ownership interpretation and services. Confirm the dry-run output and your rollback plan first.
$ sudo update-passwd --verbose
# review any interactive questions and the final report
The program locks the account database while it works; keep that locking behaviour. --no-locking exists for debugging, but the manual explicitly warns against using it unless you are certain it is necessary, so do not add it to a routine repair command.
If DEBIAN_HAS_FRONTEND is set and you skipped --dry-run, update-passwd can use debconf to ask about each proposed change. Read the exact question rather than accepting a long sequence mechanically.
5. Check the result and backups
The command leaves an .org copy of a previous file whenever it modifies that file. Inspect the current files and any backups without printing password hashes:
$ sudo stat -c '%A %U:%G %s %n' /etc/passwd /etc/shadow /etc/group
$ sudo find /etc -maxdepth 1 -type f -name '*.org' -printf '%f\n'
$ getent passwd root
root:x:0:0:root:/root:/bin/bash
$ getent group root
root:x:0:
The exact getent output depends on local account data. Check the key service accounts you expected to remain, and confirm the services relying on them are healthy.
Warning
Do not use cat /etc/shadow as a verification step; it exposes password hashes for no reason. Keep the .org files until the result has been checked: they are recovery material, not a substitute for a tested account-backup procedure.
6. Recover carefully if an account change breaks something
There is no undo flag. If a service or login breaks, stop making further account changes and preserve diagnostics. Compare the affected current file with its matching .org copy:
$ sudo diff -u /etc/passwd.org /etc/passwd
$ sudo diff -u /etc/group.org /etc/group
# inspect /etc/shadow.org only when it exists and access is authorised
$ sudo diff -u /etc/shadow.org /etc/shadow
Recovery
Only restore a file after confirming it is the one you need and that no later legitimate account change would be lost. Restoring replaces the current database and is itself a security-sensitive change:
$ sudo cp --preserve=all /etc/passwd.org /etc/passwd
$ sudo cp --preserve=all /etc/group.org /etc/group
# restore /etc/shadow.org in the same way only after reviewing it
$ sudo pwck -r
$ sudo grpck -r
pwck and grpck are separate local tools; if they are unavailable, stop and use your distribution's normal account-recovery procedure. Restoring only one of the related files can leave the databases mismatched, so involve whoever is responsible for the host before restoring a partial set.
7. Know the boundary of the check
The installed manual records a real limitation: update-passwd does not verify that every passwd entry has a matching shadow entry, or that passwords are absent from both files. A successful run does not prove the shadow database is complete or correctly separated.
It also does not manage ordinary user accounts, rotate passwords, repair arbitrary ownership, or enable a disabled login service. Keep those tasks separate. If it reports a difference you cannot explain, leave the files unchanged, save the verbose dry-run output, and investigate the package master files and local policy before applying anything.
Done means
- Confirmed the installed versions. Both
base-passwdandupdate-passwd. - Ran the sanity check and dry-run with shadow access. Not just as an ordinary user.
- Reviewed proposed changes in the UID and GID range 0-99. Every addition, removal and modification.
- Kept database locking enabled. While applying the update.
- Checked key accounts and services. Without exposing shadow contents.
- Know which
.orgbackups exist. With a reviewed recovery path ready.