From 6049b791567dad33be050b05bb08ef2040f473ee Mon Sep 17 00:00:00 2001 From: Rob Crittenden Date: Tue, 24 Oct 2017 15:43:08 -0400 Subject: [PATCH] Fix cert-find for CA-less installations Change 49f9d799c171c7ae2ac546a33a353c2c40b4719c 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 Reviewed-By: Stanislav Laznicka --- 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 bb11713317abad55577b1c280253ab5d6d68c508..c1d389217265f44e646ac27d9adc8d5524c74ce7 100644 --- a/ipaserver/plugins/cert.py +++ b/ipaserver/plugins/cert.py @@ -1453,6 +1453,7 @@ class cert_find(Search, CertMethod): 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, []): @@ -1466,7 +1467,12 @@ class cert_find(Search, CertMethod): obj = result[issuer, serial_number] except KeyError: obj = {'serial_number': 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).decode('ascii')) result[issuer, serial_number] = obj @@ -1480,6 +1486,11 @@ class cert_find(Search, CertMethod): 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]) @@ -1534,7 +1545,8 @@ class cert_find(Search, CertMethod): 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: @@ -1561,6 +1573,12 @@ class cert_find(Search, CertMethod): 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)) -- 2.13.6