upgrade: fix ipakra people entry 'description' attribute

Add an upgrade script to detect when ipakra people entry has
incorrect 'description' attribute and fix it.

Part of: https://pagure.io/freeipa/issue/8084

Reviewed-By: Florence Blanc-Renaud <flo@redhat.com>
This commit is contained in:
Fraser Tweedale 2019-10-11 15:56:10 +11:00 committed by Florence Blanc-Renaud
parent 326d417d98
commit 7ea50ff76d
3 changed files with 85 additions and 7 deletions

View File

@ -23,6 +23,7 @@ plugin: update_upload_cacrt
# update_ra_cert_store has to be executed after update_ca_renewal_master
plugin: update_ra_cert_store
plugin: update_mapping_Guests_to_nobody
plugin: fix_kra_people_entry
# last
# DNS version 1

View File

@ -50,6 +50,9 @@ ADMIN_GROUPS = [
'Security Domain Administrators'
]
KRA_BASEDN = DN(('o', 'kra'), ('o', 'ipaca'))
KRA_AGENT_DN = DN(('uid', 'ipakra'), ('ou', 'people'), KRA_BASEDN)
class KRAInstance(DogtagInstance):
"""
@ -77,8 +80,6 @@ class KRAInstance(DogtagInstance):
config=paths.KRA_CS_CFG_PATH,
)
self.basedn = DN(('o', 'kra'), ('o', 'ipaca'))
def configure_instance(self, realm_name, host_name, dm_password,
admin_password, pkcs12_info=None, master_host=None,
subject_base=None, ca_subject=None,
@ -247,9 +248,8 @@ class KRAInstance(DogtagInstance):
conn.connect(autobind=True)
# create ipakra user with RA agent certificate
user_dn = DN(('uid', "ipakra"), ('ou', 'people'), self.basedn)
entry = conn.make_entry(
user_dn,
KRA_AGENT_DN,
objectClass=['top', 'person', 'organizationalPerson',
'inetOrgPerson', 'cmsuser'],
uid=["ipakra"],
@ -264,9 +264,10 @@ class KRAInstance(DogtagInstance):
conn.add_entry(entry)
# add ipakra user to Data Recovery Manager Agents group
group_dn = DN(('cn', 'Data Recovery Manager Agents'), ('ou', 'groups'),
self.basedn)
conn.add_entry_to_group(user_dn, group_dn, 'uniqueMember')
group_dn = DN(
('cn', 'Data Recovery Manager Agents'), ('ou', 'groups'),
KRA_BASEDN)
conn.add_entry_to_group(KRA_AGENT_DN, group_dn, 'uniqueMember')
conn.disconnect()

View File

@ -0,0 +1,76 @@
#
# Copyright (C) 2019 FreeIPA Contributors see COPYING for license
#
import logging
from ipalib import Registry, Updater, x509
from ipapython.dn import DN
from ipaplatform.paths import paths
from ipaserver.install import krainstance
logger = logging.getLogger(__name__)
register = Registry()
@register()
class fix_kra_people_entry(Updater):
"""
Update the KRA uid=ipakra agent user entry.
There was a bug where this was created with an incorrect
'description' attribute, breaking authentication:
https://pagure.io/freeipa/issue/8084.
"""
def execute(self, **options):
kra = krainstance.KRAInstance(self.api.env.realm)
if not kra.is_installed():
return False, []
cert = x509.load_certificate_from_file(paths.RA_AGENT_PEM)
entry = self.api.Backend.ldap2.get_entry(krainstance.KRA_AGENT_DN)
# check description attribute
description_values = entry.get('description', [])
if len(description_values) < 1:
# missing 'description' attribute is unexpected, but we can
# add it
do_fix = True
else:
# There should only be one value, so we will take the first value.
# But ignore the serial number when comparing, just in case.
description = description_values[0]
parts = description.split(';', 2) # see below for syntax
if len(parts) < 3:
do_fix = True # syntax error (not expected)
elif parts[2] != '{};{}'.format(DN(cert.issuer), DN(cert.subject)):
# issuer/subject does not match cert. THIS is the condition
# caused by issue 8084, which we want to fix.
do_fix = True
else:
do_fix = False # everything is fine
if do_fix:
# If other replicas have a different iteration of the IPA RA
# cert (e.g. renewal was triggered prematurely on some master
# and not on others) then authentication on those replicas will
# fail. But the 'description' attribute needed fixing because
# the issuer value was wrong, meaning authentication was broken
# on ALL replicas. So even for the corner case where different
# replicas have different IPA RA certs, updating the attribute
# will at least mean THIS replica can authenticate to the KRA.
logger.debug("Fixing KRA user entry 'description' attribute")
entry['description'] = [
'2;{};{};{}'.format(
cert.serial_number,
DN(cert.issuer),
DN(cert.subject)
)
]
self.api.Backend.ldap2.update_entry(entry)
return False, [] # don't restart DS; no LDAP updates to perform