From 7d0e6e6c7b3ae6aab2aaa7b51909101f38bd659c Mon Sep 17 00:00:00 2001 From: shridhargadekar Date: Fri, 22 May 2026 00:23:48 +0530 Subject: [PATCH] Add export_root_ca_certificate() methods for LDAPS Add certificate export functionality to AD and Samba hosts to support LDAPS testing with proper certificate trust chains. AD (Windows): - Export LDAPS certificate from LocalMachine\My store (not Root) - Filter by FQDN subject and Server Authentication EKU (1.3.6.1.5.5.7.3.1) - Certificate has both CA:TRUE and ServerAuth for trust chain validation Samba (Linux): - Export CA certificate from /var/data/certs/ca.crt - Pre-configured LDAPS certificate in container setup These methods enable tests to: 1. Export certificates from providers 2. Trust them on client systems using TLSUtils.trust_ca_certificate() 3. Validate LDAPS connections (port 636) with proper TLS verification Used by adcli LDAPS tests to verify --use-ldaps functionality. Signed-off-by: shridhargadekar --- sssd_test_framework/hosts/ad.py | 42 ++++++++++++++++++++++++++++++ sssd_test_framework/hosts/samba.py | 21 +++++++++++++++ 2 files changed, 63 insertions(+) diff --git a/sssd_test_framework/hosts/ad.py b/sssd_test_framework/hosts/ad.py index d603795c..5722ce2d 100644 --- a/sssd_test_framework/hosts/ad.py +++ b/sssd_test_framework/hosts/ad.py @@ -100,6 +100,48 @@ def naming_context(self) -> str: return self.__naming_context + def export_root_ca_certificate(self) -> str: + """ + Export the AD LDAPS certificate in PEM format. + + This method retrieves the LDAPS server certificate from the AD domain + controller's local machine personal certificate store (My) and exports it + in PEM format. The certificate has both Server Authentication capability + and CA:TRUE flag, making it suitable for both TLS and trust verification. + + :return: PEM-formatted LDAPS certificate content. + :rtype: str + :raises RuntimeError: If certificate cannot be exported. + """ + result = self.conn.run( + """ + $fqdn = [System.Net.Dns]::GetHostEntry($env:COMPUTERNAME).HostName + + # Get the LDAPS certificate from My store (server certificate with ServerAuth EKU) + # Use regex to match CN component within Subject (handles additional RDNs like OU, DC) + $cert = Get-ChildItem Cert:\\LocalMachine\\My | Where-Object { + $_.Subject -match "CN=$([regex]::Escape($fqdn))(,|$)" -and + $_.EnhancedKeyUsageList.ObjectId -contains "1.3.6.1.5.5.7.3.1" + } | Sort-Object NotBefore -Descending | Select-Object -First 1 + + if (-not $cert) { + throw "No LDAPS certificate found in My store" + } + + $pem = "-----BEGIN CERTIFICATE-----`r`n" + + [Convert]::ToBase64String($cert.RawData, "InsertLineBreaks") + + "`r`n-----END CERTIFICATE-----" + + Write-Output $pem + """, + raise_on_error=False, + ) + + if result.rc != 0: + raise RuntimeError(f"Failed to export LDAPS certificate: {result.stderr}") + + return result.stdout.strip() + def disconnect(self) -> None: return diff --git a/sssd_test_framework/hosts/samba.py b/sssd_test_framework/hosts/samba.py index 0e196912..9dc8e641 100644 --- a/sssd_test_framework/hosts/samba.py +++ b/sssd_test_framework/hosts/samba.py @@ -81,6 +81,27 @@ def start(self) -> None: def stop(self) -> None: self.svc.stop("samba.service") + def export_root_ca_certificate(self) -> str: + """ + Export the Samba root CA certificate in PEM format. + + This method retrieves the CA certificate used for LDAPS from the Samba + domain controller and exports it in PEM format. + + :return: PEM-formatted root CA certificate content. + :rtype: str + :raises RuntimeError: If certificate cannot be exported. + """ + result = self.conn.run( + "cat /var/data/certs/ca.crt", + raise_on_error=False, + ) + + if result.rc != 0: + raise RuntimeError(f"Failed to export root CA certificate: {result.stderr}") + + return result.stdout.strip() + def backup(self) -> Any: """ Backup all Samba server data.