Skip to content

pam_succeed_if: prevent logging unknown user names in plaintext#985

Open
lzwind wants to merge 1 commit into
linux-pam:masterfrom
lzwind:fix/pam_succeed_if_password_leak
Open

pam_succeed_if: prevent logging unknown user names in plaintext#985
lzwind wants to merge 1 commit into
linux-pam:masterfrom
lzwind:fix/pam_succeed_if_password_leak

Conversation

@lzwind

@lzwind lzwind commented Jun 2, 2026

Copy link
Copy Markdown

Summary

  • When a user accidentally types their password at the username prompt, pam_succeed_if logs the password in plaintext via pam_syslog. This happens because evaluate_ingroup, evaluate_notingroup, evaluate_innetgr, and evaluate_notinnetgr return PAM_AUTH_ERR or PAM_SUCCESS for non-existent users instead of PAM_USER_UNKNOWN, bypassing the existing log guard (ret != PAM_USER_UNKNOWN).
  • Instead of changing the return values of the evaluate_* functions (which would break the expected semantics, e.g., evaluate_notingroup should return PAM_SUCCESS when the user is not in the group), this fix modifies the logging part: check whether the user exists using pam_modutil_getpwnam(). If the user does not exist and audit is not enabled, print "unknown user" instead of the potentially sensitive user input.

Changes

File Change
modules/pam_succeed_if/pam_succeed_if.c After evaluate(), check if user exists via pam_modutil_getpwnam(). Use "unknown user" in log messages when user does not exist and audit is disabled.

Test plan

  • Verify that when a non-existent username (e.g., a mistyped password) is passed to pam_succeed_if.so user ingroup <group>, logs show "unknown user" instead of the password
  • Verify that existing valid user checks still work correctly (user name appears in logs as before)
  • Verify that ingroup, notingroup, innetgr, notinnetgr qualifiers all behave correctly with both existing and non-existing users
  • Verify that when audit flag is set, the actual user input is still logged for debugging purposes

Fixes: #559

@ldv-alt ldv-alt left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks like the chosen approach is not correct. Instead, I suggest changing the logging part where the user name is printed: if audit is enabled or the user exists, print the user name as it is printed now, otherwise print an unknown user.

Comment thread modules/pam_succeed_if/pam_succeed_if.c Outdated
Comment thread modules/pam_succeed_if/pam_succeed_if.c Outdated
When a user accidentally types their password at the username prompt,
pam_succeed_if logs the password in plaintext via pam_syslog.  This
happens because evaluate_ingroup, evaluate_notingroup, evaluate_innetgr,
and evaluate_notinnetgr return PAM_AUTH_ERR or PAM_SUCCESS for
non-existent users instead of PAM_USER_UNKNOWN, bypassing the existing
log guard (ret != PAM_USER_UNKNOWN).

Instead of changing the return values of the evaluate_* functions
(which would break the expected semantics of e.g. evaluate_notingroup
that should return PAM_SUCCESS when the user is not in the group),
fix the logging part: check whether the user exists using
pam_modutil_getpwnam().  If the user does not exist and audit is not
enabled, print "unknown user" instead of the potentially sensitive
user input.

Fixes: linux-pam#559
Signed-off-by: Liu Zheng <liuzheng@uniontech.com>
@lzwind lzwind force-pushed the fix/pam_succeed_if_password_leak branch from 4f943f8 to f2689ca Compare June 11, 2026 02:30
@ldv-alt

ldv-alt commented Jun 11, 2026

Copy link
Copy Markdown
Member

I don't see any changes in the new edition of this commit.

@lzwind lzwind force-pushed the fix/pam_succeed_if_password_leak branch from f2689ca to 12ac9e0 Compare June 12, 2026 10:00
@lzwind lzwind requested a review from ldv-alt June 12, 2026 10:00
@lzwind lzwind force-pushed the fix/pam_succeed_if_password_leak branch from 12ac9e0 to 48ed3c9 Compare June 12, 2026 10:05
@lzwind

lzwind commented Jun 12, 2026

Copy link
Copy Markdown
Author

Thank you for the suggestion. I've updated the patch to follow your approach: instead of modifying the evaluate_* functions' return values, the fix now only changes the logging part in pam_succeed_if(). After evaluate() returns, if pwd is still NULL, we call pam_modutil_getpwnam() to check whether the user exists. When the user doesn't exist and audit is not enabled, the log message prints 'unknown user' instead of the potentially sensitive user input.

The evaluate_ingroup, evaluate_notingroup, evaluate_innetgr, and evaluate_notinnetgr functions remain unchanged, so their original return value semantics (e.g. evaluate_notingroup returning PAM_SUCCESS when the user is not in the group) are preserved.

@lzwind lzwind left a comment

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated per review feedback: moved the user existence check from evaluate_* functions to the logging section. The evaluate functions' return value semantics are preserved.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

pam_succeed_if logs invalid user names

2 participants