** Description changed:

+ [ Impact ]
+ 
+ Ubuntu machines managed with Active Directory Group Policy through ADSys can
+ silently lose certificate auto-enrollment. Windows treats registry paths as
+ case-insensitive, so depending on the tool used to create it, a GPO may store
+ the auto-enrollment settings under SOFTWARE\Policies\Microsoft\Cryptography
+ instead of Software\Policies\Microsoft\Cryptography. Windows clients apply
+ such a GPO normally, but ADSys compares the key literally and does not
+ recognize the setting.
+ 
+ ADSys reports no error when this happens. It treats auto-enrollment as not
+ configured and runs the enrollment helper in "unenroll" mode, so a machine 
that
+ was previously enrolled loses its enrollment on the next policy refresh.
+ Services relying on machine certificates can then stop working with no clear
+ indication of the cause.
+ 
+ The fix makes ADSys match the certificate auto-enrollment key and the
+ PolicyServers keys case-insensitively when parsing GPOs, and normalizes the
+ policy server ID so that entries from different GPOs that differ only in case
+ are merged with the usual GPO precedence. Other policy types are not changed.
+ The fix is upstream in adsys 0.17.0, which is already in tenacious and 
stonking,
+ and needs to be backported to resolute, noble and jammy.
+ 
+ [ Test Plan ]
+ 
+ This test requires an Active Directory domain with AD Certificate Services and
+ an AD-joined Ubuntu machine running ADSys. The test can be performed in VMs
+ using libvirt/KVM.
+ 
+ ** Setup VMs (one-time) **
+ 
+ 1. Create VMs on the host machine:
+     $ virt-install --name winserver --virt-type kvm --memory 4096 --vcpus 2 \
+         --disk size=60 --cdrom /path/to/WindowsServer_eval.iso \
+         --network network:default --osinfo detect=on,require=off \
+         --noautoconsole --graphics spice
+     $ virt-install --name ubuntu-client --virt-type kvm --memory 2048 \
+         --vcpus 2 --disk size=20 --cdrom 
/path/to/ubuntu-live-server-amd64.iso \
+         --network network:default --osinfo detect=on,require=off \
+         --noautoconsole --graphics spice
+     Complete both installations from virt-manager. The Windows VM shuts
+     down during setup; restart it with:
+     $ virsh start winserver
+ 
+ 2. Configure the domain controller (on winserver, PowerShell as
+    Administrator):
+     PS> Install-WindowsFeature AD-Domain-Services -IncludeManagementTools
+     PS> Install-ADDSForest -DomainName "test.local" -InstallDns `
+           -DomainMode WinThreshold -ForestMode WinThreshold `
+           -SafeModeAdministratorPassword `
+           (Read-Host -AsSecureString "DSRM password") -Force
+ 
+ 3. Configure AD Certificate Services (on winserver):
+     Install the Enterprise Root CA and Web Enrollment:
+     PS> Install-WindowsFeature AD-Certificate, ADCS-Web-Enrollment `
+           -IncludeManagementTools
+     PS> Install-AdcsCertificationAuthority -CAType EnterpriseRootCA -Force
+     PS> Install-AdcsWebEnrollment -Force
+ 
+     Find a certificate with the Server Authentication EKU and the DNS name
+     winserver.test.local (normally the auto-enrolled Kerberos Authentication
+     or DomainController certificate, not the CA certificate):
+     PS> Get-ChildItem Cert:\LocalMachine\My | ForEach-Object {
+           [pscustomobject]@{ Thumbprint = $_.Thumbprint;
+             EKU = ($_.EnhancedKeyUsageList.FriendlyName -join ', ');
+             DnsNames = ($_.DnsNameList.Unicode -join ', ') } } | Format-List
+ 
+     Install the Enrollment Policy (CEP) and Enrollment Web Service (CES):
+     PS> $thumb = '<thumbprint from above>'
+     PS> $caConfig = 'winserver.test.local\test-WINSERVER-CA'
+     PS> Install-WindowsFeature ADCS-Enroll-Web-Pol, ADCS-Enroll-Web-Svc `
+           -IncludeManagementTools
+     PS> Install-AdcsEnrollmentPolicyWebService -AuthenticationType Kerberos `
+           -SSLCertThumbprint $thumb -Force
+     PS> Install-AdcsEnrollmentWebService -CAConfig $caConfig `
+           -AuthenticationType Kerberos -SSLCertThumbprint $thumb `
+           -ApplicationPoolIdentity -Force
+     PS> Enable-NetFirewallRule `
+           -DisplayName 'World Wide Web Services (HTTPS Traffic-In)'
+     PS> Get-WebApplication | Select-Object Path
+     Expected: /CertSrv, /test-WINSERVER-CA_CES_Kerberos and 
+     /ADPolicyProvider_CEP_Kerberos are all listed.
+ 
+ 4. Allow Domain Computers to autoenroll the Machine template (on
+    winserver):
+     PS> Import-Module ActiveDirectory
+     PS> $tmpl = "CN=Machine,CN=Certificate Templates,CN=Public Key " + `
+           "Services,CN=Services,CN=Configuration,DC=test,DC=local"
+     PS> $acl = Get-Acl "AD:$tmpl"
+     PS> $sid = (Get-ADGroup 'Domain Computers').SID
+     PS> $guid = [Guid]'a05b8cc2-17bc-4802-a710-e7c15ab866a2'
+     PS> $acl.AddAccessRule((New-Object `
+           System.DirectoryServices.ActiveDirectoryAccessRule `
+           $sid, 'ExtendedRight', 'Allow', $guid))
+     PS> Set-Acl "AD:$tmpl" $acl
+     PS> Restart-Service certsvc
+ 
+ 5. Create and link the certificate auto-enrollment GPO (on winserver):
+     PS> New-GPO -Name "Ubuntu-CertAutoEnrollment"
+     PS> New-GPLink -Name "Ubuntu-CertAutoEnrollment" -Target 
"DC=test,DC=local"
+     PS> Set-GPRegistryValue -Name "Ubuntu-CertAutoEnrollment" `
+           -Key "HKLM\Software\Policies\Microsoft\Cryptography\AutoEnrollment" 
`
+           -ValueName "AEPolicy" -Type DWord -Value 7
+     Do not edit the GPO after the Ubuntu client has downloaded it, as a
+     version change makes ADSys re-download it and overwrite the modified
+     cached copy.
+ 
+ ** Setup Ubuntu Client (one-time) **
+ 
+ 6. Configure networking (on ubuntu-client, replace <DC_IP> with the Windows
+    server IP and <IFACE> with the interface name from "ip -br link"):
+     $ sudo tee /etc/netplan/99-ad-dns.yaml <<EOF
+     network:
+       version: 2
+       ethernets:
+         <IFACE>:
+           dhcp4: true
+           dhcp4-overrides:
+             use-dns: false
+           nameservers:
+             addresses: [<DC_IP>]
+             search: [test.local]
+     EOF
+     $ sudo chmod 600 /etc/netplan/99-ad-dns.yaml
+     $ sudo netplan apply
+     $ sudo hostnamectl set-hostname ubuntu-client.test.local
+     $ resolvectl status <IFACE>
+     Expected: "DNS Servers: <DC_IP>" and "DNS Domain: test.local"
+     $ host -t SRV _ldap._tcp.test.local
+     Expected: "_ldap._tcp.test.local has SRV record 0 100 389
+     winserver.test.local."
+ 
+ 7. Install packages and join the domain:
+     $ sudo apt update
+     $ sudo apt install -y sssd-ad sssd-tools realmd adcli krb5-user \
+         openssh-server adsys certmonger python3-cepces python3-samba
+     $ sudo realm join -U Administrator test.local -v
+     $ sudo pam-auth-update --enable mkhomedir
+     $ sudo reboot
+ 
+ 8. Attach Ubuntu Pro (certificate policy requires it):
+     $ sudo pro attach <token>
+ 
+ ** Reproduce the Issue **
+ 
+ 9. Refresh the policies and locate the cached policy file (on
+    ubuntu-client, as root):
+     $ sudo -i
+     # adsysctl policy update -m -vvvv 2>&1 | tee /root/refresh-before.log
+     # GUID=$(adsysctl policy applied -m | \
+         grep -o 'Ubuntu-CertAutoEnrollment ({[^}]*})' | grep -o '{.*}')
+     # POL="/var/cache/adsys/sysvol/Policies/$GUID/Machine/Registry.pol"
+ 
+ 10. Confirm the baseline:
+     # adsysctl policy applied -m --details --all
+     # grep -o 'Certificate policy value: [0-9]*' /root/refresh-before.log
+     # grep "cert autoenroll script with arguments" /root/refresh-before.log
+ 
+     Observed results:
+     - applied output shows "certificate: autoenroll: 7" under the GPO
+     - refresh log shows "Certificate policy value: 7"
+     - refresh log shows the cert autoenroll script ran with "enroll"
+ 
+ 11. Change the registry key case in the cached policy file:
+     # cp "$POL" "$POL.bak"
+     # python3 -c 'import sys, pathlib; p = pathlib.Path(sys.argv[1]); enc = 
lambda s: s.encode("utf-16le"); 
p.write_bytes(p.read_bytes().replace(enc("Software\\Policies\\Microsoft\\Cryptography\\"),
 enc("SOFTWARE\\Policies\\Microsoft\\Cryptography\\")))' "$POL"
+     # iconv -f utf-16le -t utf-8 "$POL" | grep -a -o \
+         'SOFTWARE\\Policies\\Microsoft\\Cryptography'
+     Expected: "SOFTWARE\Policies\Microsoft\Cryptography" is printed
+ 
+ 12. Refresh and check the policies:
+     # adsysctl policy update -m -vvvv 2>&1 | tee /root/refresh-after.log
+     # adsysctl policy applied -m --details --all
+     # grep 'not configured, unenrolling machine' /root/refresh-after.log
+     # grep "cert autoenroll script with arguments" /root/refresh-after.log
+ 
+     Observed results:
+     - applied output shows no certificate settings under the GPO
+     - refresh log shows "Certificate autoenrollment is not configured,
+       unenrolling machine"
+     - refresh log shows the cert autoenroll script ran with "unenroll"
+ 
+ ** Verify the Fix **
+ 
+ 13. Install patched adsys and repeat the refresh with the modified 
Registry.pol
+     still in place:
+     # systemctl restart adsysd
+     # iconv -f utf-16le -t utf-8 "$POL" | grep -a -o \
+         'SOFTWARE\\Policies\\Microsoft\\Cryptography'
+     Expected: the cached file still contains the uppercase key
+     # adsysctl policy update -m -vvvv 2>&1 | tee /root/refresh-fixed.log
+     # adsysctl policy applied -m --details --all
+     # grep -o 'Certificate policy value: [0-9]*' /root/refresh-fixed.log
+     # grep "cert autoenroll script with arguments" /root/refresh-fixed.log
+ 
+     Observed results:
+     - applied output shows "certificate: autoenroll: 7" under the GPO
+     - refresh log shows "Certificate policy value: 7"
+     - refresh log shows the cert autoenroll script ran with "enroll"
+ 
+ [ Where problems could occur ]
+ 
+ The change is limited to how ADSys parses certificate auto-enrollment keys 
from
+ GPOs in internal/ad/ad.go. Other policy types are not affected. Possible
+ problems include:
+ 
+ - Behaviour change on upgrade: GPOs that store the keys with a different case
+   were silently ignored before. After upgrading, ADSys will apply them on the
+   next refresh, so affected machines will start enrolling and install the CA
+   certificate into the system trust store. This is the intended result and
+   matches Windows clients, but administrators who relied on the old behaviour
+   may see machines enroll unexpectedly.
+ 
+ - Key parsing: the prefix match now slices the key after a length check. A
+   mistake here would show up as certificate settings missing from "adsysctl
+   policy applied" or as errors during policy refresh. Upstream unit tests 
cover
+   uppercase, fully uppercase, and lowercase paths.
+ 
+ [ Other Info ]
+ 
+ - Certificate auto-enrollment in ADSys requires an Ubuntu Pro subscription, so
+   theclient must be attached for the test.
+ 
+ - Full enrollment (a certificate tracked by certmonger) is not required to
+   verify this fix. The bug occurs before ADSys contacts the CA, when it 
decides
+   whether auto-enrollment is configured, so the "adsysctl policy applied" 
output
+   and the enroll/unenroll calls in the refresh log are sufficient.
+ 
+ - Upstream commit 0574804 ("ad: match certificate auto-enrollment keys
+   case-insensitively") [1] fixes this bug, and is already included in the 
adsys
+   0.17.0 package [2] in tenacious and stonking. It cherry-picks cleanly to
+   resolute, noble, and jammy.
+ 
+ - Test packages were built for each affected release and are available in the
+   following PPA: https://launchpad.net/~munirsid/+archive/ubuntu/lp2169074/
+ 
+ [1] - 
https://github.com/ubuntu/adsys/commit/0574804c613c840003355053c54609f979b86749
+ [2] - https://bugs.launchpad.net/ubuntu/+source/adsys/+bug/2169827
+ 
+ Original Description: Find the original description of the bug below:
+ 
  **Title:** Certificate auto-enrollment settings silently ignored when
  registry paths use uppercase `SOFTWARE`
  
  **Description**
  
  ADSys appears to match certificate enrollment registry paths case-
  sensitively. Our GPO contains paths beginning with `SOFTWARE`, while the
  matching code expects `Software`. Windows registry key names are case-
  insensitive.
  
  As a result, ADSys retrieves and parses the GPO and lists it in applied
  policies, but omits its certificate settings and does not initiate
  enrollment. The policy refresh completes without an obvious error
  identifying the skipped settings.
  
  **Affected environment**
  
  - Ubuntu 22.04, host `lt001237w`
  - Stock ADSys client and daemon: `0.16.3~22.04.2ubuntu0.22.04.1`
  - Ubuntu Pro enabled
  - GPO: `Linux Certificate Auto-Enrollment`
  - GPO ID: `{9B8F0CA0-96EF-4672-8733-095719DDDD52}`
  - Local and remote GPO version: `65545`
  
  The issue was also investigated on Ubuntu 24.04 using ADSys
  `0.16.3~24.04.2ubuntu0.24.04.1`, where a local casing patch enabled
  certificate-policy processing.
  
  **Reproduction**
  
  1. Configure a computer certificate auto-enrollment GPO whose 
`Machine/Registry.pol` contains:
-    ```
-    SOFTWARE\Policies\Microsoft\Cryptography\AutoEnrollment
-        AEPolicy
- 
-    SOFTWARE\Policies\Microsoft\Cryptography\PolicyServers
-    ```
+    ```
+    SOFTWARE\Policies\Microsoft\Cryptography\AutoEnrollment
+        AEPolicy
+ 
+    SOFTWARE\Policies\Microsoft\Cryptography\PolicyServers
+    ```
  2. Apply the GPO to an Ubuntu computer running stock ADSys.
  3. Run:
-    ```bash
-    sudo adsysctl policy update -m -vvv
-    sudo adsysctl policy applied -m --details --all
-    sudo getcert list
-    ```
+    ```bash
+    sudo adsysctl policy update -m -vvv
+    sudo adsysctl policy applied -m --details --all
+    sudo getcert list
+    ```
  
  **Actual result**
  
  The debug log confirms that ADSys finds and parses the certificate GPO’s
  `Machine/Registry.pol`. However:
  
  - No certificate settings appear under that GPO in detailed applied-policy 
output.
  - No certificate enrollment helper invocation appears in the captured refresh 
log.
  - Certmonger reports zero tracked requests.
  
  The downloaded policy file’s SHA-256 is:
  
  ```text
  8165f411b061c84027a811ae8727db0304f37796f6c34c4d76ec58836a80a1a4
  ```
  
  **Expected result**
  
  ADSys should recognize equivalent registry paths regardless of
  capitalization and process the configured certificate enrollment
  settings.
  
  **Suspected cause and proposed fix**
  
  In `internal/ad/ad.go`, certificate settings are identified using case-
  sensitive comparisons:
  
  ```go
  pol.Key == certAutoEnrollKey
  strings.HasPrefix(pol.Key, policyServersPrefix)
  ```
  
  Our local patch uses case-insensitive comparisons and canonicalizes the
  matched policy-server prefix while preserving the remaining identifier,
  value name, and data.
  
  **Validation performed**
  
  On Ubuntu 24.04, the patched package recognized `autoenroll=7` and the
  policy-server settings. After resolving separate CEP/CES server
  configuration and TLS issues, enrollment successfully issued
  certificates.
  
  On Ubuntu 22.04, we have reproduced the omission using the stock package
  and verified uppercase `SOFTWARE` in the downloaded policy. A patched
  before/after comparison on that host remains pending.
  
  The patch also includes a regression test covering canonical,
  uppercase-`SOFTWARE`, fully uppercase, and lowercase path variants.
  
  **Impact**
  
  Affected clients can report a successful GPO refresh while silently
  omitting certificate enrollment settings, making the problem difficult
  to distinguish from CA, template, or enrollment-service configuration
  issues.
  
  ProblemType: Bug
  DistroRelease: Ubuntu 22.04
  Package: adsys 0.16.3~22.04.2ubuntu0.22.04.1
  ProcVersionSignature: Ubuntu 6.8.0-138.138~22.04.1-generic 6.8.12
  Uname: Linux 6.8.0-138-generic x86_64
  NonfreeKernelModules: lkp_Ubuntu_6_8_0_138_138_generic_121
  ApportVersion: 2.20.11-0ubuntu82.10
  Architecture: amd64
  CasperMD5CheckResult: pass
  Date: Wed Sep 30 14:17:45 2026
  InstallationDate: Installed on 2026-09-30 (0 days ago)
  InstallationMedia: Ubuntu 22.04.5 LTS "Jammy Jellyfish" - Release amd64 
(20240911)
  ProcEnviron:
-  SHELL=/bin/bash
-  LANG=en_US.UTF-8
-  TERM=xterm-256color
-  PATH=(custom, no user)
+  SHELL=/bin/bash
+  LANG=en_US.UTF-8
+  TERM=xterm-256color
+  PATH=(custom, no user)
  RelatedPackageVersions:
-  sssd          2.6.3-1ubuntu3.9
-  python3-samba 2:4.15.13+dfsg-0ubuntu1.13
+  sssd          2.6.3-1ubuntu3.9
+  python3-samba 2:4.15.13+dfsg-0ubuntu1.13
  SourcePackage: adsys
  UpgradeStatus: No upgrade log present (probably fresh install)
  
modified.conffile..etc.polkit-1.localauthority.conf.d.99-adsys-privilege-enforcement.conf:
 [deleted]
  modified.conffile..etc.sudoers.d.99-adsys-privilege-enforcement: [deleted]

-- 
You received this bug notification because you are a member of Ubuntu
Bugs, which is subscribed to Ubuntu.
https://bugs.launchpad.net/bugs/2169074

Title:
  Adsys is case sensitive when querying registery
  \SOFTWARE\Policies\Microsoft\Cryptography\

To manage notifications about this bug go to:
https://bugs.launchpad.net/ubuntu/+source/adsys/+bug/2169074/+subscriptions


-- 
ubuntu-bugs mailing list
[email protected]
https://lists.ubuntu.com/mailman/listinfo/ubuntu-bugs

Reply via email to