From edaea8865f42f8b6e786f6648ac4cb5c4ddd4f35 Mon Sep 17 00:00:00 2001 From: Christian Heimes Date: Thu, 18 Apr 2019 08:02:38 +0200 Subject: [PATCH] Add ODS manager abstraction to ipaplatform OpenDNSSEC 1.4 and 2.x use different commands to initialize kasp.db and manage zones. ipaplatform.tasks abstracts the commands. Note: I added the logic to the base task instead of having different implementations for Red Hat and Debian platforms. Eventually Fedora is going to move to OpenDNSSEC 2.x, too. The design will make it easier to support OpenDNSSEC 2.x on Fedora. Signed-off-by: Christian Heimes Reviewed-By: Alexander Bokovoy Reviewed-By: Rob Crittenden --- ipaplatform/base/paths.py | 2 +- ipaplatform/base/tasks.py | 34 +++++++++++++++++++++++++ ipaplatform/debian/paths.py | 2 +- ipaserver/dnssec/odsmgr.py | 9 ++----- ipaserver/install/opendnssecinstance.py | 24 ++++++----------- 5 files changed, 46 insertions(+), 25 deletions(-) diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py index a5ed14066..8b21733b9 100644 --- a/ipaplatform/base/paths.py +++ b/ipaplatform/base/paths.py @@ -186,7 +186,7 @@ class BasePathNamespace: ODS_KSMUTIL = "/usr/bin/ods-ksmutil" ODS_SIGNER = "/usr/sbin/ods-signer" ODS_ENFORCER = None - ODS_ENFORCER_SETUP = None + ODS_ENFORCER_DB_SETUP = None OPENSSL = "/usr/bin/openssl" PK12UTIL = "/usr/bin/pk12util" SOFTHSM2_UTIL = "/usr/bin/softhsm2-util" diff --git a/ipaplatform/base/tasks.py b/ipaplatform/base/tasks.py index 2f96acaf6..a7587a58d 100644 --- a/ipaplatform/base/tasks.py +++ b/ipaplatform/base/tasks.py @@ -24,10 +24,12 @@ This module contains default platform-specific implementations of system tasks. from __future__ import absolute_import +import os import logging from pkg_resources import parse_version +from ipaplatform.constants import constants from ipaplatform.paths import paths from ipapython import ipautil @@ -272,5 +274,37 @@ class BaseTaskNamespace: if fstore is not None and fstore.has_file(paths.RESOLV_CONF): fstore.restore_file(paths.RESOLV_CONF) + def run_ods_setup(self): + """Initialize a new kasp.db + """ + if paths.ODS_KSMUTIL is not None: + cmd = [paths.ODS_KSMUTIL, 'setup'] + else: + cmd = [paths.ODS_ENFORCER_DB_SETUP] + return ipautil.run(cmd, stdin="y", runas=constants.ODS_USER) + + def run_ods_manager(self, params, **kwargs): + """Run OpenDNSSEC manager command (ksmutil, enforcer) + + :param params: parameter for ODS command + :param kwargs: additional arguments for ipautil.run() + :return: result from ipautil.run() + """ + assert params[0] != 'setup' + + if paths.ODS_KSMUTIL is not None: + # OpenDNSSEC 1.4 + cmd = [paths.ODS_KSMUTIL] + else: + # OpenDNSSEC 2.x + cmd = [paths.ODS_ENFORCER] + cmd.extend(params) + + # run commands as ODS user + if os.geteuid() == 0: + kwargs['runas'] = constants.ODS_USER + + return ipautil.run(cmd, **kwargs) + tasks = BaseTaskNamespace() diff --git a/ipaplatform/debian/paths.py b/ipaplatform/debian/paths.py index 4bd631be8..d698e2a30 100644 --- a/ipaplatform/debian/paths.py +++ b/ipaplatform/debian/paths.py @@ -67,7 +67,7 @@ class DebianPathNamespace(BasePathNamespace): CERTMONGER_COMMAND_TEMPLATE = "/usr/lib/ipa/certmonger/%s" ODS_KSMUTIL = None ODS_ENFORCER = "/usr/sbin/ods-enforcer" - ODS_ENFORCER_SETUP = "/usr/sbin/ods-enforcer-db-setup" + ODS_ENFORCER_DB_SETUP = "/usr/sbin/ods-enforcer-db-setup" UPDATE_CA_TRUST = "/usr/sbin/update-ca-certificates" BIND_LDAP_DNS_IPA_WORKDIR = "/var/cache/bind/dyndb-ldap/ipa/" BIND_LDAP_DNS_ZONE_WORKDIR = "/var/cache/bind/dyndb-ldap/ipa/master/" diff --git a/ipaserver/dnssec/odsmgr.py b/ipaserver/dnssec/odsmgr.py index 44ba1cf6f..67138008b 100644 --- a/ipaserver/dnssec/odsmgr.py +++ b/ipaserver/dnssec/odsmgr.py @@ -11,7 +11,7 @@ except ImportError: from xml.etree import ElementTree as etree from ipapython import ipa_log_manager, ipautil -from ipaplatform.paths import paths +from ipaplatform.tasks import tasks logger = logging.getLogger(__name__) @@ -135,12 +135,7 @@ class ODSMgr: Raises CalledProcessError if returncode != 0. """ - if paths.ODS_ENFORCER is not None: - cmd = [paths.ODS_ENFORCER] - else: - cmd = [paths.ODS_KSMUTIL] - cmd.extend(params) - result = ipautil.run(cmd, capture_output=True) + result = tasks.run_ods_manager(params, capture_output=True) return result.output def get_ods_zonelist(self): diff --git a/ipaserver/install/opendnssecinstance.py b/ipaserver/install/opendnssecinstance.py index f6d50b9c8..df39705a4 100644 --- a/ipaserver/install/opendnssecinstance.py +++ b/ipaserver/install/opendnssecinstance.py @@ -21,6 +21,7 @@ from ipapython import ipautil from ipaplatform import services from ipaplatform.constants import constants from ipaplatform.paths import paths +from ipaplatform.tasks import tasks from ipalib import errors, api from ipaserver import p11helper from ipalib.constants import SOFTHSM_DNSSEC_TOKEN_LABEL @@ -279,11 +280,6 @@ class OpenDNSSECInstance(service.Service): if not self.fstore.has_file(paths.OPENDNSSEC_KASP_DB): self.fstore.backup_file(paths.OPENDNSSEC_KASP_DB) - if paths.ODS_ENFORCER is not None: - ods_cmd = paths.ODS_ENFORCER - else: - ods_cmd = paths.ODS_KSMUTIL - if self.kasp_db_file: # copy user specified kasp.db to proper location and set proper # privileges @@ -292,20 +288,16 @@ class OpenDNSSECInstance(service.Service): os.chmod(paths.OPENDNSSEC_KASP_DB, 0o660) # regenerate zonelist.xml - cmd = [ods_cmd, 'zonelist', 'export'] - result = ipautil.run( - cmd, runas=constants.ODS_USER, capture_output=True + result = tasks.run_ods_manager( + ['zonelist', 'export'], capture_output=True ) - if paths.ODS_ENFORCER is not None: - with open(paths.OPENDNSSEC_ZONELIST_FILE, 'w') as f: - f.write(result.output) - os.fchown(f.fileno(), self.ods_uid, self.ods_gid) - os.fchmod(f.fileno(), 0o660) - + with open(paths.OPENDNSSEC_ZONELIST_FILE, 'w') as f: + f.write(result.output) + os.fchown(f.fileno(), self.ods_uid, self.ods_gid) + os.fchmod(f.fileno(), 0o660) else: # initialize new kasp.db - cmd = [ods_cmd, 'setup'] - ipautil.run(cmd, stdin="y", runas=constants.ODS_USER) + tasks.run_ods_setup() def __setup_dnskeysyncd(self): # set up dnskeysyncd this is DNSSEC master