URL: https://github.com/freeipa/freeipa/pull/1269
Author: stlaz
 Title: #1269: [Backport][ipa-4-6] Don't fail on cert_find in the UI on a 
CA-less installation
Action: opened

PR body:
"""
This PR was opened automatically because PR #1196 was pushed to master and 
backport to ipa-4-6 is required.
"""

To pull the PR as Git branch:
git remote add ghfreeipa https://github.com/freeipa/freeipa
git fetch ghfreeipa pull/1269/head:pr1269
git checkout pr1269
From b08f3c5373c3f92d4ab88a16d75b4c1004ba8098 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcrit...@redhat.com>
Date: Tue, 24 Oct 2017 15:43:08 -0400
Subject: [PATCH] Fix cert-find for CA-less installations

Change eb6d4c3037d0cc269a7924745f1cbd8f647e6e1a deferred the
detailed lookup until all certs were collected but introduced
a bug where the ra backend was always retrieved. This generated a
backtrace in a CA-less install because there is no ra backend in
the CA-less case.

The deferral also removes the certificate value from the LDAP
search output resulting in only the serial number being displayed
unless --all is provided. Add a new class variable,
self.ca_enabled, to add an exception for the CA-less case.

Fixes https://pagure.io/freeipa/issue/7202

Signed-off-by: Rob Crittenden <rcrit...@redhat.com>
---
 ipaserver/plugins/cert.py | 22 ++++++++++++++++++++--
 1 file changed, 20 insertions(+), 2 deletions(-)

diff --git a/ipaserver/plugins/cert.py b/ipaserver/plugins/cert.py
index 38314cd0c0..f40d0f9439 100644
--- a/ipaserver/plugins/cert.py
+++ b/ipaserver/plugins/cert.py
@@ -1555,6 +1555,7 @@ def _ldap_search(self, all, pkey_only, no_members, **options):
 
             truncated = bool(truncated)
 
+        ca_enabled = getattr(context, 'ca_enabled')
         for entry in entries:
             for attr in ('usercertificate', 'usercertificate;binary'):
                 for cert in entry.get(attr, []):
@@ -1563,7 +1564,12 @@ def _ldap_search(self, all, pkey_only, no_members, **options):
                         obj = result[cert_key]
                     except KeyError:
                         obj = {'serial_number': cert.serial_number}
-                        if not pkey_only and all:
+                        if not pkey_only and (all or not ca_enabled):
+                            # Retrieving certificate details is now deferred
+                            # until after all certificates are collected.
+                            # For the case of CA-less we need to keep
+                            # the certificate because getting it again later
+                            # would require unnecessary LDAP searches.
                             obj['certificate'] = (
                                 base64.b64encode(
                                     cert.public_bytes(x509.Encoding.DER))
@@ -1580,6 +1586,11 @@ def _ldap_search(self, all, pkey_only, no_members, **options):
 
     def execute(self, criteria=None, all=False, raw=False, pkey_only=False,
                 no_members=True, timelimit=None, sizelimit=None, **options):
+        # Store ca_enabled status in the context to save making the API
+        # call multiple times.
+        ca_enabled = self.api.Command.ca_is_enabled()['result']
+        setattr(context, 'ca_enabled', ca_enabled)
+
         if 'cacn' in options:
             ca_obj = api.Command.ca_show(options['cacn'])['result']
             ca_sdn = unicode(ca_obj['ipacasubjectdn'][0])
@@ -1634,7 +1645,8 @@ def execute(self, criteria=None, all=False, raw=False, pkey_only=False,
 
         if not pkey_only:
             ca_objs = {}
-            ra = self.api.Backend.ra
+            if ca_enabled:
+                ra = self.api.Backend.ra
 
             for key, obj in six.iteritems(result):
                 if all and 'cacn' in obj:
@@ -1659,6 +1671,12 @@ def execute(self, criteria=None, all=False, raw=False, pkey_only=False,
 
                 if not raw:
                     self.obj._parse(obj, all)
+                    if not ca_enabled and not all:
+                        # For the case of CA-less don't display the full
+                        # certificate unless requested. It is kept in the
+                        # entry from _ldap_search() so its attributes can
+                        # be retrieved.
+                        obj.pop('certificate', None)
                     self.obj._fill_owners(obj)
 
         result = list(six.itervalues(result))
_______________________________________________
FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org
To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org

Reply via email to