URL: https://github.com/freeipa/freeipa/pull/5378 Author: abbra Title: #5378: [Backport][ipa-4-9] Fix uninstall without dns Action: opened
PR body: """ This PR was opened automatically because PR #5376 was pushed to master and backport to ipa-4-9 is required. """ To pull the PR as Git branch: git remote add ghfreeipa https://github.com/freeipa/freeipa git fetch ghfreeipa pull/5378/head:pr5378 git checkout pr5378
From d1d75e3f96c730c0ed3dfe47ea8c6634669e3ca7 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy <aboko...@redhat.com> Date: Tue, 22 Dec 2020 09:11:51 +0200 Subject: [PATCH 1/3] opendnssecinstance: use late binding for UID/GID resolution Move actual resolution of UID/GID values for 'ods' and 'named' entities to the code that needs them. This prevents failures when uninstalling IPA server set up without DNS feature. In particular, 'named' group is created when 'bind' package is installed and if 'bind' package is not installed, uninstall fails in OpenDNSSEC instance constructor. We use common pattern for all services during uninstall: svc = SVCClass(..) if svc.is_configured() svc.uninstall() This requires that the class constructor should not rely on artifacts that only exist when the service is configured. Fixes: https://pagure.io/freeipa/issue/8630 Signed-off-by: Alexander Bokovoy <aboko...@redhat.com> --- ipaserver/install/opendnssecinstance.py | 30 ++++++++++++++----------- 1 file changed, 17 insertions(+), 13 deletions(-) diff --git a/ipaserver/install/opendnssecinstance.py b/ipaserver/install/opendnssecinstance.py index 415e7710ed1..6d5557f24c7 100644 --- a/ipaserver/install/opendnssecinstance.py +++ b/ipaserver/install/opendnssecinstance.py @@ -67,9 +67,6 @@ def __init__(self, fstore=None): self, "ods-enforcerd", service_desc="OpenDNSSEC enforcer daemon", ) - self.named_gid = constants.NAMED_GROUP.gid - self.ods_uid = constants.ODS_USER.uid - self.ods_gid = constants.ODS_GROUP.gid self.conf_file_dict = { 'SOFTHSM_LIB': paths.LIBSOFTHSM2_SO, 'TOKEN_LABEL': SOFTHSM_DNSSEC_TOKEN_LABEL, @@ -194,8 +191,8 @@ def __setup_conf_files(self): quotes=False, separator='=') def __setup_ownership_file_modes(self): - assert self.ods_uid is not None - assert self.ods_gid is not None + assert constants.ODS_USER.uid is not None + assert constants.ODS_GROUP.gid is not None # workarounds for packaging bugs in opendnssec-1.4.5-2.fc20.x86_64 # https://bugzilla.redhat.com/show_bug.cgi?id=1098188 @@ -204,24 +201,25 @@ def __setup_ownership_file_modes(self): dir_path = os.path.join(root, directory) os.chmod(dir_path, 0o770) # chown to root:ods - os.chown(dir_path, 0, self.ods_gid) + os.chown(dir_path, 0, constants.ODS_GROUP.gid) for filename in files: file_path = os.path.join(root, filename) os.chmod(file_path, 0o660) # chown to root:ods - os.chown(file_path, 0, self.ods_gid) + os.chown(file_path, 0, constants.ODS_GROUP.gid) for (root, dirs, files) in os.walk(paths.VAR_OPENDNSSEC_DIR): for directory in dirs: dir_path = os.path.join(root, directory) os.chmod(dir_path, 0o770) # chown to ods:ods - os.chown(dir_path, self.ods_uid, self.ods_gid) + constants.ODS_USER.chown(dir_path, gid=constants.ODS_GROUP.gid) for filename in files: file_path = os.path.join(root, filename) os.chmod(file_path, 0o660) # chown to ods:ods - os.chown(file_path, self.ods_uid, self.ods_gid) + constants.ODS_USER.chown(file_path, + gid=constants.ODS_GROUP.gid) def __generate_master_key(self): @@ -242,11 +240,15 @@ def __generate_master_key(self): for directory in dirs: dir_path = os.path.join(root, directory) os.chmod(dir_path, 0o770 | stat.S_ISGID) - os.chown(dir_path, self.ods_uid, self.named_gid) # chown to ods:named + # chown to ods:named + constants.ODS_USER.chown(dir_path, + gid=constants.NAMED_GROUP.gid) for filename in files: file_path = os.path.join(root, filename) os.chmod(file_path, 0o660 | stat.S_ISGID) - os.chown(file_path, self.ods_uid, self.named_gid) # chown to ods:named + # chown to ods:named + constants.ODS_USER.chown(file_path, + gid=constants.NAMED_GROUP.gid) finally: p11.finalize() @@ -266,7 +268,8 @@ def __setup_dnssec(self): # copy user specified kasp.db to proper location and set proper # privileges shutil.copy(self.kasp_db_file, paths.OPENDNSSEC_KASP_DB) - os.chown(paths.OPENDNSSEC_KASP_DB, self.ods_uid, self.ods_gid) + constants.ODS_USER.chown(paths.OPENDNSSEC_KASP_DB, + gid=constants.ODS_GROUP.gid) os.chmod(paths.OPENDNSSEC_KASP_DB, 0o660) else: @@ -290,7 +293,8 @@ def __start(self): ) with open(paths.OPENDNSSEC_ZONELIST_FILE, 'w') as f: f.write(result.output) - os.fchown(f.fileno(), self.ods_uid, self.ods_gid) + constants.ODS_USER.chown(f.fileno(), + gid=constants.ODS_GROUP.gid) os.fchmod(f.fileno(), 0o660) def uninstall(self): From d2e3e9750d009bac9fac7a6e051285660827337e Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy <aboko...@redhat.com> Date: Tue, 22 Dec 2020 09:20:52 +0200 Subject: [PATCH 2/3] dnskeysyncinstance: use late binding for UID/GID resolution Move actual resolution of UID/GID values for 'ods' and 'named' entities to the code that needs them. This prevents failures when uninstalling IPA server set up without DNS feature. In particular, 'named' group is created when 'bind' package is installed and if 'bind' package is not installed, uninstall fails in OpenDNSSEC instance constructor. We use common pattern for all services during uninstall: svc = SVCClass(..) if svc.is_configured() svc.uninstall() This requires that the class constructor should not rely on artifacts that only exist when the service is configured. Fixes: https://pagure.io/freeipa/issue/8630 Signed-off-by: Alexander Bokovoy <aboko...@redhat.com> --- ipaserver/install/dnskeysyncinstance.py | 24 ++++++++++++------------ 1 file changed, 12 insertions(+), 12 deletions(-) diff --git a/ipaserver/install/dnskeysyncinstance.py b/ipaserver/install/dnskeysyncinstance.py index 16870b73b5c..b5eca31da79 100644 --- a/ipaserver/install/dnskeysyncinstance.py +++ b/ipaserver/install/dnskeysyncinstance.py @@ -55,10 +55,6 @@ def __init__(self, fstore=None, logger=logger): keytab=paths.IPA_DNSKEYSYNCD_KEYTAB ) self.extra_config = [u'dnssecVersion 1', ] # DNSSEC enabled - self.named_uid = constants.NAMED_USER.uid - self.named_gid = constants.NAMED_GROUP.gid - self.ods_uid = constants.ODS_USER.uid - self.ods_gid = constants.ODS_GROUP.gid suffix = ipautil.dn_attribute_property('_suffix') @@ -78,7 +74,7 @@ def set_dyndb_ldap_workdir_permissions(self): else: os.chmod(directory, 0o770) # dnssec daemons require to have access into the directory - os.chown(directory, self.named_uid, self.named_gid) + constants.NAMED_USER.chown(directory, gid=constants.NAMED_GROUP.gid) def remove_replica_public_keys(self, replica_fqdn): ldap = api.Backend.ldap2 @@ -180,7 +176,7 @@ def setup_named_openssl_conf(self): ) with open(paths.DNSSEC_OPENSSL_CONF, 'w') as f: os.fchmod(f.fileno(), 0o640) - os.fchown(f.fileno(), 0, self.named_gid) + os.fchown(f.fileno(), 0, gid=constants.NAMED_GROUP.gid) f.write(named_openssl_txt) def setup_named_sysconfig(self): @@ -235,7 +231,8 @@ def __setup_softhsm(self): os.mkdir(paths.IPA_DNSSEC_DIR) os.chmod(paths.IPA_DNSSEC_DIR, 0o770) # chown ods:named - os.chown(paths.IPA_DNSSEC_DIR, self.ods_uid, self.named_gid) + constants.ODS_USER.chown(paths.IPA_DNSSEC_DIR, + gid=constants.NAMED_GROUP.gid) # setup softhsm2 config file softhsm_conf_txt = ("# SoftHSM v2 configuration file \n" @@ -272,7 +269,8 @@ def __setup_softhsm(self): os.mkdir(paths.DNSSEC_TOKENS_DIR) os.chmod(paths.DNSSEC_TOKENS_DIR, 0o770 | stat.S_ISGID) # chown to ods:named - os.chown(paths.DNSSEC_TOKENS_DIR, self.ods_uid, self.named_gid) + constants.ODS_USER.chown(paths.DNSSEC_TOKENS_DIR, + gid=constants.NAMED_GROUP.gid) # generate PINs for softhsm pin_length = 30 # Bind allows max 32 bytes including ending '\0' @@ -284,7 +282,7 @@ def __setup_softhsm(self): logger.debug("Saving user PIN to %s", paths.DNSSEC_SOFTHSM_PIN) with open(paths.DNSSEC_SOFTHSM_PIN, 'w') as f: # chown to ods:named - os.fchown(f.fileno(), self.ods_uid, self.named_gid) + constants.ODS_USER.chown(f.fileno(), gid=constants.NAMED_GROUP.gid) os.fchmod(f.fileno(), 0o660) f.write(pin) @@ -419,12 +417,14 @@ def __setup_replica_keys(self): dir_path = os.path.join(root, directory) os.chmod(dir_path, 0o770 | stat.S_ISGID) # chown to ods:named - os.chown(dir_path, self.ods_uid, self.named_gid) + constants.ODS_USER.chown(dir_path, + gid=constants.NAMED_GROUP.gid) for filename in files: file_path = os.path.join(root, filename) os.chmod(file_path, 0o660 | stat.S_ISGID) # chown to ods:named - os.chown(file_path, self.ods_uid, self.named_gid) + constants.ODS_USER.chown(file_path, + gid=constants.NAMED_GROUP.gid) def __enable(self): try: @@ -449,7 +449,7 @@ def __setup_principal(self): dnssynckey_principal_dn = p # Make sure access is strictly reserved to the named user - os.chown(self.keytab, 0, self.ods_gid) + os.chown(self.keytab, 0, constants.ODS_GROUP.gid) os.chmod(self.keytab, 0o440) dns_group = DN(('cn', 'DNS Servers'), ('cn', 'privileges'), From a7c92d60d768ada3ecb021e5b68cc726b1bdbbed Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy <aboko...@redhat.com> Date: Tue, 22 Dec 2020 09:25:01 +0200 Subject: [PATCH 3/3] odsexporterinstance: use late binding for UID/GID resolution Move actual resolution of UID/GID values for 'ods' entities to the code that needs them. This prevents failures when uninstalling IPA server set up without DNS feature. In particular, 'ods' user and group are created when 'opendnssec' package is installed and if 'opendnssec' package is not installed, uninstall fails in OpenDNSSEC Exporter instance constructor. We use common pattern of checking the service during uninstall: svc = SVCClass() if svc.is_configured(): svc.uninstall() Thus, service class constructor must not do UID/GID resolution Fixes: https://pagure.io/freeipa/issue/8630 Signed-off-by: Alexander Bokovoy <aboko...@redhat.com> --- ipaserver/install/odsexporterinstance.py | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/ipaserver/install/odsexporterinstance.py b/ipaserver/install/odsexporterinstance.py index d9fa46d0a36..414705b6ed9 100644 --- a/ipaserver/install/odsexporterinstance.py +++ b/ipaserver/install/odsexporterinstance.py @@ -31,8 +31,6 @@ def __init__(self, fstore=None): keytab=paths.IPA_ODS_EXPORTER_KEYTAB, service_prefix=u'ipa-ods-exporter' ) - self.ods_uid = constants.ODS_USER.uid - self.ods_gid = constants.ODS_GROUP.gid self.enable_if_exists = False suffix = ipautil.dn_attribute_property('_suffix') @@ -71,7 +69,7 @@ def __setup_key_exporter(self): quotes=False, separator='=') def __setup_principal(self): - assert self.ods_uid is not None + assert constants.ODS_GROUP.gid is not None for f in [paths.IPA_ODS_EXPORTER_CCACHE, self.keytab]: try: @@ -95,7 +93,7 @@ def __setup_principal(self): # Make sure access is strictly reserved to the ods user os.chmod(self.keytab, 0o440) - os.chown(self.keytab, 0, self.ods_gid) + os.chown(self.keytab, 0, constants.ODS_GROUP.gid) dns_group = DN(('cn', 'DNS Servers'), ('cn', 'privileges'), ('cn', 'pbac'), self.suffix)
_______________________________________________ FreeIPA-devel mailing list -- freeipa-devel@lists.fedorahosted.org To unsubscribe send an email to freeipa-devel-le...@lists.fedorahosted.org Fedora Code of Conduct: https://docs.fedoraproject.org/en-US/project/code-of-conduct/ List Guidelines: https://fedoraproject.org/wiki/Mailing_list_guidelines List Archives: https://lists.fedorahosted.org/archives/list/freeipa-devel@lists.fedorahosted.org