Repository navigation
Password-less Script Improvements – Release Notes
Date: 2026‑01‑13
Overview
This release significantly improves the safety, observability, and verification tooling around passwordless behavior in the Password-less project:
- Hardened PAM
nullokdetection to avoid lockouts and false positives. - Removed dangerous automatic password deletion.
- Added unified PAM + SSH empty-password audits.
- Upgraded the standalone
pam-nullok-check.shhelper with richer diagnostics. - Improved documentation to match the new behavior.
1. PAM nullok Detection and Safety
1.1 Smarter can_system_accept_empty_passwords
The main script’s can_system_accept_empty_passwords() now:
- Scans
/etc/pam.donce forauth ... pam_unix(.so)lines. - Ignores commented lines.
- Treats the system as accepting empty passwords only if it finds at least one
auth pam_unix(.so)line that:- Contains bare
nullok, - Does not contain
nullok_secureon the same line, - Is not commented out.
- Contains bare
It does not fail just because nullok_secure exists somewhere else (e.g. /etc/pam.d/login for TTY logins). This avoids false negatives on systems that use nullok_secure for console but nullok for other stacks (such as system-auth, password-auth, or sssd-shadowutils).
1.2 Logging and Summary
verify_empty_password_status (and the helper scripts) now:
- Print each relevant
pam_unixline tagged as either:nullok(empty passwords accepted for that auth stack), ornullok_secure(TTY-only empty passwords).
- Summarize per file where bare
nullokandnullok_secureoccur. - Clearly state whether PAM as a whole appears willing to accept empty passwords.
This makes it much easier to understand which PAM stacks are truly passwordless-capable.
2. Removal of Automatic passwd -d Behavior
2.1 Deprecated --delete-passwd-on-polkit-fail
The previously dangerous option --delete-passwd-on-polkit-fail has been removed from the script’s behavior and from README usage:
- The script no longer calls
passwd -dautomatically under any circumstances. - All flows that used to offer automatic password deletion are now replaced by warnings only.
2.2 New Guidance in maybe_delete_password_for_target_user
The maybe_delete_password_for_target_user() function is now a no-op + explanation:
- It informs the user when polkit JS rules might be unsupported (e.g. polkit ≥ 124 with no JS rules present).
- It explicitly states that the script will:
- Not run
passwd -d. - Not change any Unix password automatically.
- Not run
- It tells users to:
- Use
--verify-pam-nullokand/orpam-nullok-check.shto inspect PAM first. - If they still want an empty Unix password, run
passwd -d <USER>manually, fully understanding the risk.
- Use
3. Unified PAM + SSH Empty-Password Audit
3.1 --verify-pam-nullok → Full Auth Audit
The CLI option --verify-pam-nullok now runs a combined PAM + SSH empty-password audit:
- Internally wired to the new
verify_empty_password_status()function. - No configuration changes are made; this is a read-only audit.
3.2 PAM Side: can_system_accept_empty_passwords
As described above, this function:
- Detects bare
nullok(withoutnullok_secureon the same line). - Interprets the presence of such lines as indication that at least one local login path can accept an empty Unix password.
3.3 SSH Side: check_sshd_config_allows_empty
New helper function:
- Prefers
sshd -Twhere available (and only when run as root) to inspect the effective SSH configuration, includingInclude/Matchhandling. - If
sshd -Tis available:- Returns true if
permitemptypasswords yesappears in the test output. - Returns false if
sshd -Tsucceeds and does not reportpermitemptypasswords yes.
- Returns true if
- Fallback:
- Recursively scans
/etc/ssh/sshd_configand/etc/ssh/sshd_config.d/*.conffor:PermitEmptyPasswords yeson non-comment lines.
- Recursively scans
This ensures the audit sees whether SSH would even consider allowing empty passwords.
3.4 Audit Summary Output
verify_empty_password_status now prints:
-
PAM Status: SAFEorRISK (nullok present). -
SSH Status: SAFEorRISK (PermitEmptyPasswords yes). -
A final interpretation:
- CRITICAL – both PAM and SSH allow empty passwords.
- WARNING – PAM local path allows empty passwords, but SSH blocks them.
- WARNING – SSH allows empty passwords, but PAM appears to reject them.
- RESULT – both look safe (no empty-password path found).
This clarifies the local vs remote exposure in one shot.
4. Standalone Helper: pam-nullok-check.sh
The helper script has been heavily improved:
4.1 PAM Logic
- Single-pass scan of
/etc/pam.dforauth ... pam_unix(.so)lines. - Ignores commented lines.
- Tracks:
nullokwithoutnullok_secure→ local paths that accept empty passwords.nullok_secureanywhere → TTY-only empty passwords.
4.2 SSH Logic
- Checks for SSH server presence and:
- Uses
sshd -Tif available to locatepermitemptypasswords yes. - Falls back to
PermitEmptyPasswords yesgrep insshd_configandsshd_config.d.
- Uses
4.3 Exit-Code Semantics
- Exit code 0 (SAFE) – no bare
nullokin PAM, and noPermitEmptyPasswords yesin SSH. - Exit code 1 (RISK) – at least one of PAM/SSH is capable of operating with empty passwords.
This makes the helper friendlier for CI and security pipelines (0 = clean, 1 = risk).
4.4 Clear User-Facing Messages
The script now explicitly spells out risk:
-
For PAM:
- “PAM RISK: Your system’s PAM configuration includes at least one auth pam_unix(.so) stack that will accept an EMPTY PASSWORD…”
- “This means at least one local login path is technically capable of working with no Unix password set for the account.”
-
For SSH:
- “SSHD RISK: sshd_config is explicitly configured with
PermitEmptyPasswords yes. Remote SSH logins could succeed with an EMPTY PASSWORD if PAM also allows it.”
- “SSHD RISK: sshd_config is explicitly configured with
-
Overall:
- If risk is found:
RISK: Your system is currently CAPABLE of operating with EMPTY PASSWORDS for at least one path (PAM and/or SSH). - If safe:
SAFE: Based on current PAM and SSH configuration, empty Unix passwords should NOT be accepted for logins by default.
- If risk is found:
The helper also prints an extra SUCCESS/FAIL style line with emojis for at-a-glance understanding:
✅ SUCCESS: This system CAN operate password-less for at least one login path...❌ FAIL: This system CANNOT be used without a Unix password by default (which is safer).
5. Internal Flag Cleanup and Naming
Internally:
-
The legacy flag
verify_pam_nullok_onlyhas been renamed to:verify_empty_pw_only=0
-
The
--verify-pam-nullokoption now maps to:--verify-pam-nullok) # Historical name; now runs the combined PAM + SSH empty-password audit. verify_empty_pw_only=1 shift ;;
-
The early-exit block now checks the new internal flag:
if [[ "verify_empty_pw_only" -eq 1 ]] then verify_empty_password_status exit 0 fi
This matches the new semantics while preserving CLI compatibility.
6. README Documentation Updates
The README has been updated to match the new behavior:
-
--verify-pam-nullokis documented as:Historical option name, now wired to a combined PAM + SSH empty-password audit…
-
The “PAM
nullokvsnullok_secureand empty passwords” section now explains:nullokvsnullok_secure.- The heuristic used by
can_system_accept_empty_passwords. - That
--verify-pam-nullok:- Prints all relevant
pam_unixlines. - Summarizes where
nullok/nullok_secureare present. - Inspects SSH for
PermitEmptyPasswords yes. - Produces a final PAM/SSH risk summary.
- Prints all relevant
-
Emphasizes that the script never deletes Unix passwords automatically anymore and that any
passwd -daction must be taken manually after reviewing the audit output.
7. Summary
This release focuses on:
- Safety: No automatic password deletion; better nullok detection; explicit risk messaging.
- Visibility: Clear per-file summaries plus unified PAM + SSH audits.
- Correctness: Single-pass scanning, robust regex, and
sshd -Tintegration for accurate SSH interpretation. - Documentation: README and comments now accurately describe the improved behavior.
These changes make it much harder to accidentally lock yourself out or misinterpret the system’s ability to operate without passwords, while giving you powerful tools to audit and understand your auth stack.