mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2024-12-25 00:20:04 -06:00
4c4f16fc9c
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 <abokovoy@redhat.com> Reviewed-By: Christian Heimes <cheimes@redhat.com> Reviewed-By: Stanislav Levin <slev@altlinux.org>
174 lines
5.8 KiB
Python
174 lines
5.8 KiB
Python
#
|
|
# Copyright (C) 2014 FreeIPA Contributors see COPYING for license
|
|
#
|
|
|
|
from __future__ import absolute_import
|
|
|
|
import logging
|
|
import os
|
|
|
|
import ldap
|
|
|
|
from ipaserver.install import service
|
|
from ipaserver.install import installutils
|
|
from ipapython.dn import DN
|
|
from ipapython import directivesetter
|
|
from ipapython import ipautil
|
|
from ipaplatform.constants import constants
|
|
from ipaplatform.paths import paths
|
|
from ipaplatform import services
|
|
from ipalib import errors, api
|
|
|
|
logger = logging.getLogger(__name__)
|
|
|
|
|
|
class ODSExporterInstance(service.Service):
|
|
def __init__(self, fstore=None):
|
|
super(ODSExporterInstance, self).__init__(
|
|
"ipa-ods-exporter",
|
|
service_desc="IPA OpenDNSSEC exporter daemon",
|
|
fstore=fstore,
|
|
keytab=paths.IPA_ODS_EXPORTER_KEYTAB,
|
|
service_prefix=u'ipa-ods-exporter'
|
|
)
|
|
self.enable_if_exists = False
|
|
|
|
suffix = ipautil.dn_attribute_property('_suffix')
|
|
|
|
def create_instance(self, fqdn, realm_name):
|
|
self.backup_state("enabled", self.is_enabled())
|
|
self.backup_state("running", self.is_running())
|
|
self.fqdn = fqdn
|
|
self.realm = realm_name
|
|
self.suffix = ipautil.realm_to_suffix(self.realm)
|
|
|
|
try:
|
|
self.stop()
|
|
except Exception:
|
|
pass
|
|
|
|
self.step("setting up DNS Key Exporter", self.__setup_key_exporter)
|
|
self.step("setting up kerberos principal", self.__setup_principal)
|
|
self.step("disabling default signer daemon", self.__disable_signerd)
|
|
self.step("starting DNS Key Exporter", self.__start)
|
|
self.step("configuring DNS Key Exporter to start on boot", self.__enable)
|
|
self.start_creation()
|
|
|
|
def __enable(self):
|
|
|
|
try:
|
|
self.ldap_configure('DNSKeyExporter', self.fqdn, None,
|
|
self.suffix)
|
|
except errors.DuplicateEntry:
|
|
logger.error("DNSKeyExporter service already exists")
|
|
|
|
def __setup_key_exporter(self):
|
|
directivesetter.set_directive(paths.SYSCONFIG_IPA_ODS_EXPORTER,
|
|
'SOFTHSM2_CONF',
|
|
paths.DNSSEC_SOFTHSM2_CONF,
|
|
quotes=False, separator='=')
|
|
|
|
def __setup_principal(self):
|
|
assert constants.ODS_GROUP.gid is not None
|
|
|
|
for f in [paths.IPA_ODS_EXPORTER_CCACHE, self.keytab]:
|
|
try:
|
|
os.remove(f)
|
|
except OSError:
|
|
pass
|
|
|
|
installutils.kadmin_addprinc(self.principal)
|
|
|
|
# Store the keytab on disk
|
|
installutils.create_keytab(paths.IPA_ODS_EXPORTER_KEYTAB,
|
|
self.principal)
|
|
p = self.move_service(self.principal)
|
|
if p is None:
|
|
# the service has already been moved, perhaps we're doing a DNS reinstall
|
|
dns_exporter_principal_dn = DN(
|
|
('krbprincipalname', self.principal),
|
|
('cn', 'services'), ('cn', 'accounts'), self.suffix)
|
|
else:
|
|
dns_exporter_principal_dn = p
|
|
|
|
# Make sure access is strictly reserved to the ods user
|
|
os.chmod(self.keytab, 0o440)
|
|
os.chown(self.keytab, 0, constants.ODS_GROUP.gid)
|
|
|
|
dns_group = DN(('cn', 'DNS Servers'), ('cn', 'privileges'),
|
|
('cn', 'pbac'), self.suffix)
|
|
mod = [(ldap.MOD_ADD, 'member', dns_exporter_principal_dn)]
|
|
|
|
try:
|
|
api.Backend.ldap2.modify_s(dns_group, mod)
|
|
except ldap.TYPE_OR_VALUE_EXISTS:
|
|
pass
|
|
except Exception as e:
|
|
logger.critical("Could not modify principal's %s entry: %s",
|
|
dns_exporter_principal_dn, str(e))
|
|
raise
|
|
|
|
# limit-free connection
|
|
|
|
mod = [(ldap.MOD_REPLACE, 'nsTimeLimit', '-1'),
|
|
(ldap.MOD_REPLACE, 'nsSizeLimit', '-1'),
|
|
(ldap.MOD_REPLACE, 'nsIdleTimeout', '-1'),
|
|
(ldap.MOD_REPLACE, 'nsLookThroughLimit', '-1')]
|
|
try:
|
|
api.Backend.ldap2.modify_s(dns_exporter_principal_dn, mod)
|
|
except Exception as e:
|
|
logger.critical("Could not set principal's %s LDAP limits: %s",
|
|
dns_exporter_principal_dn, str(e))
|
|
raise
|
|
|
|
def __disable_signerd(self):
|
|
signerd_service = services.knownservices.ods_signerd
|
|
if self.get_state("singerd_running") is None:
|
|
self.backup_state("singerd_running", signerd_service.is_running())
|
|
if self.get_state("singerd_enabled") is None:
|
|
self.backup_state("singerd_enabled", signerd_service.is_enabled())
|
|
|
|
# disable default opendnssec signer daemon
|
|
signerd_service.stop()
|
|
signerd_service.mask()
|
|
|
|
def __start(self):
|
|
self.start()
|
|
|
|
def remove_service(self):
|
|
try:
|
|
api.Command.service_del(self.principal)
|
|
except errors.NotFound:
|
|
pass
|
|
|
|
def uninstall(self):
|
|
if not self.is_configured():
|
|
return
|
|
|
|
self.print_msg("Unconfiguring %s" % self.service_name)
|
|
|
|
# just eat states
|
|
self.restore_state("running")
|
|
self.restore_state("enabled")
|
|
|
|
# stop and disable service (IPA service, we do not need it anymore)
|
|
self.disable()
|
|
self.stop()
|
|
|
|
# restore state of dnssec default signer daemon
|
|
signerd_enabled = self.restore_state("singerd_enabled")
|
|
signerd_running = self.restore_state("singerd_running")
|
|
signerd_service = services.knownservices.ods_signerd
|
|
|
|
signerd_service.unmask()
|
|
|
|
# service was stopped and disabled by setup
|
|
if signerd_enabled:
|
|
signerd_service.enable()
|
|
|
|
if signerd_running:
|
|
signerd_service.start()
|
|
|
|
ipautil.remove_keytab(self.keytab)
|
|
ipautil.remove_ccache(ccache_path=paths.IPA_ODS_EXPORTER_CCACHE)
|