Skip to content

pam: offer local Smartcard authentication to GDM switchable authentication - #9368

Merged
alexey-tikhonov merged 3 commits into
SSSD:masterfrom
divinehawk:pam-json-local-smartcard
Oct 29, 2026
Merged

alexey-tikhonov merged 3 commits into
SSSD:masterfrom
divinehawk:pam-json-local-smartcard

Conversation

@divinehawk

@divinehawk divinehawk commented Sep 29, 2026 •

Copy link
Copy Markdown
Contributor

Resolves: #9367

With pam_json_services = gdm-switchable-auth, local Smartcard authentication (e.g. the proxy provider with certificate mapping and local_auth_policy = enable:smartcard) is never offered to GDM, even though p11_child found a matching certificate and the local auth policy allows Smartcard authentication.

Changes

  • pam: add pam_add_response_no_send(): adds a response which is only used inside of the PAM responder and not sent to the client.
  • pam: offer local Smartcard authentication in the JSON message: evalute_sending_cert_info() now runs for every request. If local Smartcard authentication is allowed and certificates were found without SSS_CERT_AUTH_PROMPTING, it adds SSS_CERT_AUTH_PROMPTING with pam_add_response_no_send(), so the JSON message offers Smartcard and pam_sss gets the same reply as before. If it is not allowed, the certificate info is hidden as before.
  • tests: check local Smartcard authentication in the JSON message: new test_pam_preauth_cert_match_json in test_pam_srv.

The authentication step needed no change: the proxy backend returns PAM_BAD_ITEM for the PIN, and pam_reply() falls back to local Smartcard authentication. Password-only users are not affected: they still get no JSON message and GDM falls back to its legacy services.

Testing

  • test_pam_srv: all 92 tests pass; the new test fails without the fix. With plain pam_add_response() instead of the no-send helper, 16 existing Smartcard tests fail.
  • make check passes.
  • Manual: GDM/gnome-shell 51 with enable-switchable-authentication on Ubuntu 26.10, proxy provider for local users, certificate mapping, PIV smartcard: Smartcard is offered and the PIN logs the user in; allow_missing_name works; password users still log in through gdm-password.

@alexey-tikhonov

Copy link
Copy Markdown
Member
  • Two gnome-shell 51 changes were also needed on the GDM side (a race between the legacy and switchable services, and the default mechanism ignoring sssd's priority). Those are separate from this change.

Are there PRs/MRs you could link for the sake of posterity?

@sumit-bose

Copy link
Copy Markdown
Contributor

Hi,

thank you very much for the fix. So far I only tested it by checking the reply of the PAM responder in different configurations but it is working as expected.

I'm just wondering if pamsrv_json.c is the right place for the check. I think a better place might be during pam_eval_local_auth_policy() or even in evalute_sending_cert_info() since your has_local_cert_info() works on the result of evalute_sending_cert_info().

My suggestion would be to call something like pam_add_response(pd, SSS_CERT_AUTH_PROMPTING, 0, NULL) in pam_eval_local_auth_policy() or evalute_sending_cert_info() under a suitable condition. But it is a bit tricky because some unit tests for Smartcard authentication will fail because with the call above the SSS_CERT_AUTH_PROMPTING will be added to the reply of the PAM responder and the current tests are not aware of it. Since pam_sss.so ignores SSS_CERT_AUTH_PROMPTING there is no need send it to the client. So a new helper function pam_add_response_no_send() which sets do_not_send_to_client to true might be useful.

bye,
Sumit

@divinehawk

Copy link
Copy Markdown
Contributor Author

@divinehawk
divinehawk force-pushed the pam-json-local-smartcard branch from 911ec3d to 8ac2766 Compare October 2, 2026 18:14
@divinehawk

Copy link
Copy Markdown
Contributor Author

Thanks for the review. I implemented your suggestions but I am going to do some more testing alongside the gdm patches.

@sumit-bose

Copy link
Copy Markdown
Contributor

Thanks for the review. I implemented your suggestions but I am going to do some more testing alongside the gdm patches.

Hi,

thank you for the updates, please let me know when you are done with your testing.

bye,
Sumit

@divinehawk

divinehawk commented Oct 8, 2026 •

Copy link
Copy Markdown
Contributor Author

Added a commit so password is still offered next to local Smartcard auth (it was dropped because SSS_CERT_AUTH_PROMPTING disabled the password fallback), except with local_auth_policy = only. Tested with GNOME 51 + gdm!405 + gnome-shell!4459 and a PIV.

@joantolo

Copy link
Copy Markdown
Contributor

Tested with GDM. I confirm that when authenticating a local user, it lists smartcard authentication and password authentication via JSON messages.

Smartcard authentication works fine. However, password authentication doesn't work. Probably due to sssd not having enough permissions to read /etc/shadow for this local user.

@alexey-tikhonov

Copy link
Copy Markdown
Member

Password auth of local users should be handled by pam_unix.so, not by pam_sss.so

@sumit-bose

Copy link
Copy Markdown
Contributor

Added a commit so password is still offered next to local Smartcard auth (it was dropped because SSS_CERT_AUTH_PROMPTING disabled the password fallback), except with local_auth_policy = only. Tested with GNOME 51 + gdm!405 + gnome-shell!4459 and a PIV.

Hi,

I think it would be better let the backends return this information. The password fallback was really meant as a falback if nothing else is available. Since we do not know if password authentication will really work, e.g. auth_provider = none, it would not be good to add it somewhat unconditionally.

bye,
Sumit

@divinehawk
divinehawk force-pushed the pam-json-local-smartcard branch from 11ec33a to 8ac2766 Compare October 12, 2026 18:20
@divinehawk

Copy link
Copy Markdown
Contributor Author

Removed the additional commit. The others are good to go from testing with the current gnome patches.

Comment thread src/responder/pam/pamsrv_cmd.c Resolved
@divinehawk
divinehawk force-pushed the pam-json-local-smartcard branch from 8ac2766 to f1978b9 Compare October 16, 2026 17:49
@spoore1

spoore1 commented Oct 27, 2026

Copy link
Copy Markdown
Contributor

Hi @divinehawk,

I'm trying to test your fix here on a Fedora 45 system but, I'm running into some issues. By any chance did you create a custom pam (gdm-switchable-auth) config to use? Could you post what your /etc/pam.d/gdm-switchable-auth file contains?

Thanks,
Scott

@divinehawk

Copy link
Copy Markdown
Contributor Author

I lost my Fedora VM but here's the one from Ubuntu I'm using:

auth    [success=1 ignore=ignore user_unknown=ignore authinfo_unavail=ignore default=die] pam_sss.so allow_missing_name
auth    substack        common-auth
auth    required        pam_succeed_if.so user != root quiet_success
auth    optional        pam_gnome_keyring.so

account required        pam_nologin.so
@include common-account

session [success=ok ignore=ignore module_unknown=ignore default=bad]        pam_selinux.so close
session required        pam_loginuid.so
session [success=ok ignore=ignore module_unknown=ignore default=bad]        pam_selinux.so open
session optional        pam_keyinit.so force revoke
session required        pam_limits.so
session required        pam_env.so readenv=1
session required        pam_env.so readenv=1 user_readenv=1 envfile=/etc/default/locale
@include common-session
session optional        pam_gnome_keyring.so auto_start

@include common-password

Note the pam_sss.so with allow_missing_name runs first in the auth stack.

And my sssd.conf, with a proxy domain for the local users:

[pam]
pam_cert_auth = True
pam_json_services = gdm-switchable-auth

[domain/local]
id_provider = proxy
proxy_lib_name = files
auth_provider = proxy
proxy_pam_target = sssd-shadowutils
local_auth_policy = enable:smartcard

[certmap/local/<user>]
matchrule = <SAN:ntPrincipalName>^<upn>$

@spoore1 spoore1 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Thanks for the testing into.

Testing looks good.

When the smart card is inserted, I do see the expected generated JSON message:

(2026-10-28  8:31:05): [pam] [pam_get_auth_types] (0x4000): [CID#11] Authentication types for user [localuser1@local] and service [gdm-switchable-auth]: smartcard
(2026-10-28  8:31:05): [pam] [generate_json_auth_message] (0x0400): [CID#11] Generated JSON message: {"authSelection": {"mechanisms": {"smartcard": {"name": "Smartcard", "role": "smartcard", "certificates": [{"tokenName": "localuser1", "certInstruction": "CAC ID Certificate\nCN=localuser1", "pinPrompt": "PIN", "moduleName": "/usr/lib64/pkcs11/opensc-pkcs11.so", "keyId": "0001", "label": "CAC ID Certificate"}]}}, "priority": ["smartcard"]}}.

When I remove the card, I see GDM switch to Password prompt and this message:
"""
(2026-10-28 8:31:16): [pam] [pam_get_auth_types] (0x4000): [CID#12] Authentication types for user [localuser1@local] and service [gdm-switchable-auth]: password
(2026-10-28 8:31:16): [pam] [generate_json_auth_message] (0x0020): [CID#12] Failed to initialize authentication data.
(2026-10-28 8:31:16): [pam] [pam_reply] (0x0020): [CID#12] failed to generate JSON message.
"""

At this point in GDM, I am able to see the option to change authentication type. If I select Smartcard, I see the message to "insert card" in the prompt. And I see this message:
"""
(2026-10-28 8:31:36): [pam] [get_client_cred] (0x4000): Client [0x561cd3529e00][18] creds: euid[0] egid[0] pid[27102] cmd_line['gdm-session-worker [pam/gdm-smartcard]'].
(2026-10-28 8:31:36): [pam] [accept_fd_handler] (0x0400): [CID#13] Client [cmd gdm-session-worker [pam/gdm-smartcard]][uid 0][0x561cd3529e00][18] connected!
(2026-10-28 8:31:36): [pam] [pam_print_data] (0x0100): [CID#13] service: gdm-smartcard
(2026-10-28 8:31:36): [pam] [pam_reply] (0x0400): [CID#13] Local auth policy allowed: smartcard [True], passkey [False]
"""

@sumit-bose sumit-bose left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hi,

thank you for the fix, ACK.

bye,
Sumit

Responses added with pam_add_response_no_send() are only used inside of
the PAM responder, e.g. to evaluate the available authentication types,
and are not sent to the client.

Reviewed-by: Scott Poore <spoore@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
The smartcard mechanism of the JSON message is only enabled if the
response list contains SSS_CERT_AUTH_PROMPTING, which is only added by
krb5_child when the KDC offers PKINIT. Local Smartcard authentication,
e.g. with the proxy provider and certificate mapping, was never offered
to GDM's switchable authentication, even if local_auth_policy allows it
and p11_child found a matching certificate.

If local Smartcard authentication is allowed and certificates were
found, add SSS_CERT_AUTH_PROMPTING in evalute_sending_cert_info() with
pam_add_response_no_send(), pam_sss does not need it.

Resolves: SSSD#9367
Reviewed-by: Scott Poore <spoore@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
Reviewed-by: Scott Poore <spoore@redhat.com>
Reviewed-by: Sumit Bose <sbose@redhat.com>
@sssd-bot

Copy link
Copy Markdown
Contributor

The pull request was accepted by @sumit-bose with the following PR CI status:


🟢 CodeQL (success)
🟢 osh-diff-scan:fedora-rawhide-x86_64:upstream (success)
🟢 rpm-build:centos-stream-10-x86_64:upstream (success)
🟢 rpm-build:fedora-43-x86_64:upstream (success)
🟢 rpm-build:fedora-44-x86_64:upstream (success)
🟢 rpm-build:fedora-45-x86_64:upstream (success)
🟢 rpm-build:fedora-rawhide-x86_64:upstream (success)
🟢 testing-farm:centos-stream-10-x86_64:upstream (success)
🟢 testing-farm:fedora-43-x86_64:upstream (success)
🟢 testing-farm:fedora-44-x86_64:upstream (success)
🟢 testing-farm:fedora-45-x86_64:upstream (success)
🟢 testing-farm:fedora-rawhide-x86_64:upstream (success)
🟢 Build / freebsd (success)
🟢 Build / make-distcheck (success)
🟢 ci / prepare (success)
🟢 ci / system (centos-10) (success)
🟢 ci / system (fedora-43) (success)
🟢 ci / system (fedora-44) (success)
🟢 ci / system (fedora-45) (success)
🟢 ci / system (fedora-46) (success)
➖ Coverity scan / coverity (skipped)
🟢 Static code analysis / codeql (success)
🟢 Static code analysis / files-changed (success)
🟢 Static code analysis / pre-commit (success)
➖ Static code analysis / python-system-tests (skipped)


There are unsuccessful or unfinished checks. Make sure that the failures are not related to this pull request before merging.

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: GDM switchable authentication never offers local Smartcard authentication

6 participants