From caafc9dff7391655325b9dec143967b01b1fefd1 Mon Sep 17 00:00:00 2001 From: krishnavema Date: Thu, 1 Oct 2026 20:47:46 +0530 Subject: [PATCH] tests: add AD smart card certificate authentication test (cherry picked from commit ebc26647024e8440b64b3f1b1a175550f3168c63) Reviewed-by: Scott Poore Reviewed-by: Sumit Bose --- src/tests/system/tests/test_ad.py | 68 +++++++++++++++++++++++++++++++ 1 file changed, 68 insertions(+) diff --git a/src/tests/system/tests/test_ad.py b/src/tests/system/tests/test_ad.py index 7576fb8b046..14c150a4f70 100644 --- a/src/tests/system/tests/test_ad.py +++ b/src/tests/system/tests/test_ad.py @@ -226,3 +226,71 @@ def test_ad__force_ldaps_over_636(client: Client, ad: AD): log = client.fs.read(client.sssd.logs.domain()) assert f"ldaps://{ad.server}" in log, f"Logs should show LDAPS connection to {ad.server}" + + +SMARTCARD_PIN = "123456" + + +def enroll_ad_smartcard(client: Client, ad: AD, username: str) -> None: + """ + Request a certificate from the AD CA for *username* and enroll it onto the + client's virtual smart card. + + :meth:`AD.ca.request` maps the certificate to the user in AD and returns the + certificate together with its private key, regardless of whether the + enrollment agent or the basic path is used. + + :param client: Client role object. + :type client: Client + :param ad: AD role object whose CA issues the certificate. + :type ad: AD + :param username: AD user the certificate is issued for. + :type username: str + """ + cert_path, key_path, _ = ad.ca.request("User", f"CN={username}") + + client.fs.write("/etc/sssd/pki/sssd_auth_ca_db.pem", ad.ca.get_ca_cert()) + + client.smartcard.add_cert_key_by_path(cert_path, key_path, source=ad, name=username) + + +@pytest.mark.importance("high") +@pytest.mark.topology(KnownTopology.AD) +@pytest.mark.builtwith(client="virtualsmartcard") +def test_ad__user_authenticates_with_smartcard_certificate(client: Client, ad: AD): + """ + :title: AD user authenticates using a certificate on a virtual smart card + :setup: + 1. Add AD user + 2. Request a certificate from the AD CA and enroll it on the virtual smart card + 3. Configure SSSD for smart card authentication with a certmap rule and start SSSD + :steps: + 1. Authenticate as the AD user using the smart card PIN + :expectedresults: + 1. Authentication is successful + :customerscenario: True + """ + if not ad.ca.is_available: + pytest.skip("AD Certificate Services is not available") + + username = "certuser1" + ad.user(username).add() + + enroll_ad_smartcard(client, ad, username) + + base_dn = ",".join(f"DC={part}" for part in ad.domain.split(".")) + domain_name = client.sssd.default_domain + + client.authselect.select("sssd", ["with-smartcard"]) + client.sssd.domain["ldap_user_certificate"] = "userCertificate;binary" + client.sssd.domain["local_auth_policy"] = "only" + client.sssd.pam["pam_cert_auth"] = "True" + + certmap = client.sssd.section(f"certmap/{domain_name}/{username}") + certmap["matchrule"] = f".*{base_dn}.*" + certmap["maprule"] = f"(sAMAccountName={username})" + + client.svc.restart("virt_cacard.service") + client.sssd.start() + + assert client.auth.su.smartcard(username, SMARTCARD_PIN), "Smart card authentication failed!"