Imported Debian patch 4.8.10-2
This commit is contained in:
committed by
Mario Fetka
parent
8bc559c5a1
commit
358acdd85f
@@ -5,30 +5,25 @@
|
||||
"""
|
||||
Server installer module
|
||||
"""
|
||||
|
||||
from __future__ import print_function
|
||||
|
||||
import collections
|
||||
import os.path
|
||||
import random
|
||||
|
||||
from ipaclient.install import client
|
||||
from ipalib import constants
|
||||
from ipalib.util import validate_domain_name
|
||||
from ipalib.install import service
|
||||
from ipalib.install.service import (enroll_only,
|
||||
installs_master,
|
||||
installs_replica,
|
||||
master_install_only,
|
||||
prepares,
|
||||
prepare_only,
|
||||
replica_install_only)
|
||||
from ipapython import ipautil
|
||||
from ipapython.dnsutil import check_zone_overlap
|
||||
from ipapython.install import typing
|
||||
from ipapython.install.core import group, knob, extend_knob
|
||||
from ipapython.install.common import step
|
||||
|
||||
from .install import validate_admin_password, validate_dm_password
|
||||
from .install import get_min_idstart
|
||||
from .install import init as master_init
|
||||
from .install import install as master_install
|
||||
from .install import install_check as master_install_check
|
||||
@@ -237,6 +232,13 @@ class ServerInstallInterface(ServerCertificateInstallInterface,
|
||||
)
|
||||
master_password = master_install_only(master_password)
|
||||
|
||||
hidden_replica = knob(
|
||||
None,
|
||||
cli_names='--hidden-replica',
|
||||
description="Install a hidden replica",
|
||||
)
|
||||
hidden_replica = replica_install_only(hidden_replica)
|
||||
|
||||
domain_level = knob(
|
||||
int, constants.MAX_DOMAIN_LEVEL,
|
||||
description="IPA domain level",
|
||||
@@ -278,6 +280,11 @@ class ServerInstallInterface(ServerCertificateInstallInterface,
|
||||
)
|
||||
setup_dns = enroll_only(setup_dns)
|
||||
|
||||
@setup_dns.validator
|
||||
def setup_dns(self, value):
|
||||
if value:
|
||||
dns.package_check(ValueError)
|
||||
|
||||
idstart = knob(
|
||||
int, random.randint(1, 10000) * 200000,
|
||||
description="The starting value for the IDs range (default random)",
|
||||
@@ -323,6 +330,12 @@ class ServerInstallInterface(ServerCertificateInstallInterface,
|
||||
)
|
||||
dirsrv_config_file = enroll_only(dirsrv_config_file)
|
||||
|
||||
skip_mem_check = knob(
|
||||
None,
|
||||
description="Skip checking for minimum required memory",
|
||||
)
|
||||
skip_mem_check = enroll_only(skip_mem_check)
|
||||
|
||||
@dirsrv_config_file.validator
|
||||
def dirsrv_config_file(self, value):
|
||||
if not os.path.exists(value):
|
||||
@@ -445,7 +458,7 @@ class ServerInstallInterface(ServerCertificateInstallInterface,
|
||||
"You cannot specify --external-ca-profile without "
|
||||
"--external-ca")
|
||||
|
||||
if self.uninstalling:
|
||||
if self.uninstalling: # pylint: disable=using-constant-test
|
||||
if (self.realm_name or self.admin_password or
|
||||
self.master_password):
|
||||
raise RuntimeError(
|
||||
@@ -472,6 +485,15 @@ class ServerInstallInterface(ServerCertificateInstallInterface,
|
||||
"'--ignore-topology-disconnect/--ignore-last-of-role' "
|
||||
"options can be used only during uninstallation")
|
||||
|
||||
min_idstart = get_min_idstart()
|
||||
if self.idstart < min_idstart:
|
||||
raise RuntimeError(
|
||||
"idstart (%i) must be larger than UID_MAX/GID_MAX (%i) "
|
||||
"setting in /etc/login.defs." % (
|
||||
self.idstart, min_idstart
|
||||
)
|
||||
)
|
||||
|
||||
if self.idmax < self.idstart:
|
||||
raise RuntimeError(
|
||||
"idmax (%s) cannot be smaller than idstart (%s)" %
|
||||
@@ -513,10 +535,13 @@ class ServerMasterInstall(ServerMasterInstallInterface):
|
||||
|
||||
@domain_name.validator
|
||||
def domain_name(self, value):
|
||||
if (self.setup_dns and
|
||||
not self.allow_zone_overlap):
|
||||
print("Checking DNS domain %s, please wait ..." % value)
|
||||
check_zone_overlap(value, False)
|
||||
# There might be an overlap but at this point we don't have
|
||||
# complete installer object to verify that DNS is hosted
|
||||
# by the same machine (i.e. we are already installed).
|
||||
# Later, DNS.install_check will do its zone overlap check
|
||||
# and will make sure to fail if overlap does really exist.
|
||||
# At this point we only verify that value is a valid DNS syntax.
|
||||
validate_domain_name(value)
|
||||
|
||||
dm_password = extend_knob(
|
||||
ServerMasterInstallInterface.dm_password,
|
||||
|
||||
@@ -8,6 +8,7 @@ import errno
|
||||
import logging
|
||||
import os
|
||||
import pickle
|
||||
import re
|
||||
import shutil
|
||||
import sys
|
||||
import time
|
||||
@@ -16,42 +17,40 @@ import textwrap
|
||||
|
||||
import six
|
||||
|
||||
from ipaclient.install.client import check_ldap_conf
|
||||
from ipaclient.install.ipachangeconf import IPAChangeConf
|
||||
from ipaclient.install import timeconf
|
||||
from ipaclient.install.client import (
|
||||
check_ldap_conf, sync_time, restore_time_sync)
|
||||
from ipapython.ipachangeconf import IPAChangeConf
|
||||
from ipalib.install import certmonger, sysrestore
|
||||
from ipapython import ipautil, version
|
||||
from ipapython.ipautil import (
|
||||
ipa_generate_password, run, user_input)
|
||||
from ipapython import ipaldap
|
||||
from ipapython.admintool import ScriptError
|
||||
from ipaplatform import services
|
||||
from ipaplatform.paths import paths
|
||||
from ipaplatform.tasks import tasks
|
||||
from ipalib import api, errors, x509
|
||||
from ipalib.constants import DOMAIN_LEVEL_0
|
||||
from ipalib.facts import is_ipa_configured, is_ipa_client_configured
|
||||
from ipalib.util import (
|
||||
validate_domain_name,
|
||||
no_matching_interface_for_ip_address_warning,
|
||||
)
|
||||
import ipaclient.install.timeconf
|
||||
from ipalib.facts import IPA_MODULES
|
||||
from ipaserver.install import (
|
||||
adtrust, bindinstance, ca, dns, dsinstance,
|
||||
adtrust, adtrustinstance, bindinstance, ca, dns, dsinstance,
|
||||
httpinstance, installutils, kra, krbinstance,
|
||||
otpdinstance, custodiainstance, replication, service,
|
||||
sysupgrade)
|
||||
from ipaserver.install.installutils import (
|
||||
IPA_MODULES, BadHostError, get_fqdn, get_server_ip_address,
|
||||
is_ipa_configured, load_pkcs12, read_password, verify_fqdn,
|
||||
update_hosts_file)
|
||||
BadHostError, get_fqdn, get_server_ip_address,
|
||||
load_pkcs12, read_password, verify_fqdn, update_hosts_file,
|
||||
validate_mask)
|
||||
|
||||
if six.PY3:
|
||||
unicode = str
|
||||
|
||||
try:
|
||||
from ipaserver.install import adtrustinstance
|
||||
_server_trust_ad_installed = True
|
||||
except ImportError:
|
||||
_server_trust_ad_installed = False
|
||||
|
||||
NoneType = type(None)
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
@@ -99,6 +98,26 @@ def validate_admin_password(password):
|
||||
', '.join('"%s"' % c for c in bad_characters))
|
||||
|
||||
|
||||
def get_min_idstart(default_idstart=60000):
|
||||
"""Get mininum idstart value from /etc/login.defs
|
||||
"""
|
||||
config = {}
|
||||
# match decimal numbers
|
||||
decimal_re = re.compile(r"^([A-Z][A-Z_]+)\s*([1-9]\d*)")
|
||||
try:
|
||||
with open('/etc/login.defs', 'r') as f:
|
||||
for line in f:
|
||||
mo = decimal_re.match(line)
|
||||
if mo is not None:
|
||||
config[mo.group(1)] = int(mo.group(2))
|
||||
except OSError:
|
||||
return default_idstart
|
||||
idstart = max(config.get("UID_MAX", 0), config.get("GID_MAX", 0))
|
||||
if idstart == 0:
|
||||
idstart = default_idstart
|
||||
return idstart
|
||||
|
||||
|
||||
def read_cache(dm_password):
|
||||
"""
|
||||
Returns a dict of cached answers or empty dict if no cache file exists.
|
||||
@@ -311,10 +330,22 @@ def install_check(installer):
|
||||
dirsrv_ca_cert = None
|
||||
pkinit_ca_cert = None
|
||||
|
||||
if not options.skip_mem_check:
|
||||
installutils.check_available_memory(ca=options.setup_ca)
|
||||
tasks.check_ipv6_stack_enabled()
|
||||
tasks.check_selinux_status()
|
||||
check_ldap_conf()
|
||||
|
||||
mask_str = validate_mask()
|
||||
if mask_str:
|
||||
print("Unexpected system mask: %s, expected 0022" % mask_str)
|
||||
if installer.interactive:
|
||||
if not user_input("Do you want to continue anyway?", True):
|
||||
raise ScriptError(
|
||||
"Unexpected system mask: %s" % mask_str)
|
||||
else:
|
||||
raise ScriptError("Unexpected system mask: %s" % mask_str)
|
||||
|
||||
if options.master_password:
|
||||
msg = ("WARNING:\noption '-P/--master-password' is deprecated. "
|
||||
"KDC master password of sufficient strength is autogenerated "
|
||||
@@ -334,8 +365,7 @@ def install_check(installer):
|
||||
"If you want to reinstall the IPA server, please uninstall "
|
||||
"it first using 'ipa-server-install --uninstall'.")
|
||||
|
||||
client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
||||
if client_fstore.has_files():
|
||||
if is_ipa_client_configured(on_master=True):
|
||||
installer._installation_cleanup = False
|
||||
raise ScriptError(
|
||||
"IPA client is already configured on this system.\n"
|
||||
@@ -416,18 +446,21 @@ def install_check(installer):
|
||||
|
||||
if not options.no_ntp:
|
||||
try:
|
||||
ipaclient.install.timeconf.check_timedate_services()
|
||||
except ipaclient.install.timeconf.NTPConflictingService as e:
|
||||
print("WARNING: conflicting time&date synchronization service '{}'"
|
||||
" will be disabled".format(e.conflicting_service))
|
||||
print("in favor of chronyd")
|
||||
print("")
|
||||
except ipaclient.install.timeconf.NTPConfigurationError:
|
||||
timeconf.check_timedate_services()
|
||||
except timeconf.NTPConflictingService as e:
|
||||
print(
|
||||
"WARNING: conflicting time&date synchronization service "
|
||||
"'{}' will be disabled in favor of chronyd\n".format(
|
||||
e.conflicting_service
|
||||
)
|
||||
)
|
||||
except timeconf.NTPConfigurationError:
|
||||
pass
|
||||
|
||||
if not options.setup_dns and installer.interactive:
|
||||
if ipautil.user_input("Do you want to configure integrated DNS "
|
||||
"(BIND)?", False):
|
||||
dns.package_check(ScriptError)
|
||||
options.setup_dns = True
|
||||
print("")
|
||||
|
||||
@@ -591,8 +624,7 @@ def install_check(installer):
|
||||
|
||||
xmlrpc_uri = 'https://{0}/ipa/xml'.format(
|
||||
ipautil.format_netloc(host_name))
|
||||
ldapi_uri = 'ldapi://%2fvar%2frun%2fslapd-{0}.socket\n'.format(
|
||||
installutils.realm_to_serverid(realm_name))
|
||||
ldapi_uri = ipaldap.realm_to_ldapi_uri(realm_name)
|
||||
|
||||
# [global] section
|
||||
gopts = [
|
||||
@@ -662,6 +694,10 @@ def install_check(installer):
|
||||
if options.ip_addresses or options.setup_dns:
|
||||
installer._update_hosts_file = True
|
||||
|
||||
if not options.no_ntp and not options.unattended and not (
|
||||
options.ntp_servers or options.ntp_pool):
|
||||
options.ntp_servers, options.ntp_pool = timeconf.get_time_source()
|
||||
|
||||
print()
|
||||
print("The IPA Master Server will be configured with:")
|
||||
print("Hostname: %s" % host_name)
|
||||
@@ -699,6 +735,14 @@ def install_check(installer):
|
||||
"Directory unless\nthe realm name of the IPA server matches "
|
||||
"its domain name.\n\n")
|
||||
|
||||
if options.ntp_servers or options.ntp_pool:
|
||||
if options.ntp_servers:
|
||||
for server in options.ntp_servers:
|
||||
print("NTP server:\t{}".format(server))
|
||||
|
||||
if options.ntp_pool:
|
||||
print("NTP pool:\t{}".format(options.ntp_pool))
|
||||
|
||||
if installer.interactive and not user_input(
|
||||
"Continue to configure the system with these values?", False):
|
||||
raise ScriptError("Installation aborted")
|
||||
@@ -748,6 +792,9 @@ def install(installer):
|
||||
# failure to enable root cause investigation
|
||||
installer._installation_cleanup = False
|
||||
|
||||
# Be clear that the installation process is beginning but not done
|
||||
sstore.backup_state('installation', 'complete', False)
|
||||
|
||||
if installer.interactive:
|
||||
print("")
|
||||
print("The following operations may take some minutes to complete.")
|
||||
@@ -762,17 +809,20 @@ def install(installer):
|
||||
if installer._update_hosts_file:
|
||||
update_hosts_file(ip_addresses, host_name, fstore)
|
||||
|
||||
if tasks.configure_pkcs11_modules(fstore):
|
||||
print("Disabled p11-kit-proxy")
|
||||
|
||||
# Create a directory server instance
|
||||
if not options.external_cert_files:
|
||||
# We have to sync time before certificate handling on master.
|
||||
# As chrony configuration is moved from client here, unconfiguration of
|
||||
# chrony will be handled here in uninstall() method as well by invoking
|
||||
# the ipa-server-install --uninstall
|
||||
if not options.no_ntp:
|
||||
if not ipaclient.install.client.sync_time(options, fstore, sstore):
|
||||
print("Warning: IPA was unable to sync time with chrony!")
|
||||
print(" Time synchronization is required for IPA "
|
||||
"to work correctly")
|
||||
if not options.no_ntp and not sync_time(
|
||||
options.ntp_servers, options.ntp_pool, fstore, sstore):
|
||||
print("Warning: IPA was unable to sync time with chrony!")
|
||||
print(" Time synchronization is required for IPA "
|
||||
"to work correctly")
|
||||
|
||||
if options.dirsrv_cert_files:
|
||||
ds = dsinstance.DsInstance(fstore=fstore,
|
||||
@@ -841,9 +891,8 @@ def install(installer):
|
||||
|
||||
ca.install_step_0(False, None, options, custodia=custodia)
|
||||
else:
|
||||
# Put the CA cert where other instances expect it
|
||||
x509.write_certificate(http_ca_cert, paths.IPA_CA_CRT)
|
||||
os.chmod(paths.IPA_CA_CRT, 0o444)
|
||||
# /etc/ipa/ca.crt is created as a side-effect of
|
||||
# dsinstance::enable_ssl() via export_ca_cert()
|
||||
|
||||
if not options.no_pkinit:
|
||||
x509.write_certificate(http_ca_cert, paths.KDC_CA_BUNDLE_PEM)
|
||||
@@ -879,7 +928,6 @@ def install(installer):
|
||||
subject_base=options.subject_base,
|
||||
auto_redirect=not options.no_ui_redirect,
|
||||
ca_is_configured=setup_ca)
|
||||
tasks.restore_context(paths.CACHE_IPA_SESSIONS)
|
||||
|
||||
ca.set_subject_base_in_config(options.subject_base)
|
||||
|
||||
@@ -936,6 +984,12 @@ def install(installer):
|
||||
service.enable_services(host_name)
|
||||
api.Command.dns_update_system_records()
|
||||
|
||||
if options.setup_adtrust:
|
||||
dns_help = adtrust.generate_dns_service_records_help(api)
|
||||
if dns_help:
|
||||
for line in dns_help:
|
||||
service.print_msg(line, sys.stdout)
|
||||
|
||||
if not options.setup_dns:
|
||||
# After DNS and AD trust are configured and services are
|
||||
# enabled, create a dummy instance to dump DNS configuration.
|
||||
@@ -943,6 +997,8 @@ def install(installer):
|
||||
bind.create_file_with_system_records()
|
||||
|
||||
# Everything installed properly, activate ipa service.
|
||||
sstore.delete_state('installation', 'complete')
|
||||
sstore.backup_state('installation', 'complete', True)
|
||||
services.knownservices.ipa.enable()
|
||||
|
||||
print("======================================="
|
||||
@@ -1046,6 +1102,8 @@ def uninstall_check(installer):
|
||||
else:
|
||||
dns.uninstall_check(options)
|
||||
|
||||
ca.uninstall_check(options)
|
||||
|
||||
if domain_level == DOMAIN_LEVEL_0:
|
||||
rm = replication.ReplicationManager(
|
||||
realm=api.env.realm,
|
||||
@@ -1098,7 +1156,7 @@ def uninstall(installer):
|
||||
except Exception:
|
||||
pass
|
||||
|
||||
ipaclient.install.client.restore_time_sync(sstore, fstore)
|
||||
restore_time_sync(sstore, fstore)
|
||||
|
||||
kra.uninstall()
|
||||
|
||||
@@ -1109,13 +1167,13 @@ def uninstall(installer):
|
||||
httpinstance.HTTPInstance(fstore).uninstall()
|
||||
krbinstance.KrbInstance(fstore).uninstall()
|
||||
dsinstance.DsInstance(fstore=fstore).uninstall()
|
||||
if _server_trust_ad_installed:
|
||||
adtrustinstance.ADTRUSTInstance(fstore).uninstall()
|
||||
adtrustinstance.ADTRUSTInstance(fstore).uninstall()
|
||||
# realm isn't used, but IPAKEMKeys parses /etc/ipa/default.conf
|
||||
# otherwise, see https://pagure.io/freeipa/issue/7474 .
|
||||
custodiainstance.CustodiaInstance(realm='REALM.INVALID').uninstall()
|
||||
otpdinstance.OtpdInstance().uninstall()
|
||||
tasks.restore_hostname(fstore, sstore)
|
||||
tasks.restore_pkcs11_modules(fstore)
|
||||
fstore.restore_all_files()
|
||||
try:
|
||||
os.remove(paths.ROOT_IPA_CACHE)
|
||||
@@ -1130,7 +1188,7 @@ def uninstall(installer):
|
||||
|
||||
sstore._load()
|
||||
|
||||
ipaclient.install.timeconf.restore_forced_timeservices(sstore)
|
||||
timeconf.restore_forced_timeservices(sstore)
|
||||
|
||||
# Clean up group_exists (unused since IPA 2.2, not being set since 4.1)
|
||||
sstore.restore_state("install", "group_exists")
|
||||
@@ -1143,6 +1201,7 @@ def uninstall(installer):
|
||||
if fstore.has_files():
|
||||
logger.error('Some files have not been restored, see '
|
||||
'%s/sysrestore.index', SYSRESTORE_DIR_PATH)
|
||||
sstore.delete_state('installation', 'complete')
|
||||
has_state = False
|
||||
for module in IPA_MODULES: # from installutils
|
||||
if sstore.has_state(module):
|
||||
@@ -1162,11 +1221,11 @@ def uninstall(installer):
|
||||
else:
|
||||
# sysrestore.state has no state left, remove it
|
||||
sysrestore = os.path.join(SYSRESTORE_DIR_PATH, 'sysrestore.state')
|
||||
installutils.remove_file(sysrestore)
|
||||
ipautil.remove_file(sysrestore)
|
||||
|
||||
# Note that this name will be wrong after the first uninstall.
|
||||
dirname = dsinstance.config_dirname(
|
||||
installutils.realm_to_serverid(api.env.realm))
|
||||
ipaldap.realm_to_serverid(api.env.realm))
|
||||
dirs = [dirname, paths.PKI_TOMCAT_ALIAS_DIR, paths.HTTPD_ALIAS_DIR]
|
||||
ids = certmonger.check_state(dirs)
|
||||
if ids:
|
||||
|
||||
@@ -9,8 +9,6 @@ import logging
|
||||
|
||||
import dns.exception as dnsexception
|
||||
import dns.name as dnsname
|
||||
import dns.resolver as dnsresolver
|
||||
import dns.reversename as dnsreversename
|
||||
import os
|
||||
import shutil
|
||||
import socket
|
||||
@@ -22,28 +20,31 @@ import traceback
|
||||
from pkg_resources import parse_version
|
||||
import six
|
||||
|
||||
from ipaclient.install.client import check_ldap_conf
|
||||
from ipaclient.install.ipachangeconf import IPAChangeConf
|
||||
from ipaclient.install.client import check_ldap_conf, sssd_enable_ifp
|
||||
import ipaclient.install.timeconf
|
||||
from ipalib.install import certstore, sysrestore
|
||||
from ipalib.install.kinit import kinit_keytab
|
||||
from ipapython import ipaldap, ipautil
|
||||
from ipapython.dn import DN
|
||||
from ipapython.dnsutil import DNSResolver
|
||||
from ipapython.admintool import ScriptError
|
||||
from ipapython.ipachangeconf import IPAChangeConf
|
||||
from ipaplatform import services
|
||||
from ipaplatform.tasks import tasks
|
||||
from ipaplatform.paths import paths
|
||||
from ipalib import api, constants, create_api, errors, rpc, x509
|
||||
from ipalib.config import Env
|
||||
from ipalib.facts import is_ipa_configured, is_ipa_client_configured
|
||||
from ipalib.util import no_matching_interface_for_ip_address_warning
|
||||
from ipaclient.install.client import configure_krb5_conf, purge_host_keytab
|
||||
from ipaserver.install import (
|
||||
adtrust, bindinstance, ca, dns, dsinstance, httpinstance,
|
||||
installutils, kra, krbinstance, otpdinstance, custodiainstance, service)
|
||||
from ipaserver.install.installutils import (
|
||||
ReplicaConfig, load_pkcs12, is_ipa_configured)
|
||||
ReplicaConfig, load_pkcs12, validate_mask)
|
||||
from ipaserver.install.replication import (
|
||||
ReplicationManager, replica_conn_check)
|
||||
from ipaserver.masters import find_providing_servers, find_providing_server
|
||||
import SSSDConfig
|
||||
from subprocess import CalledProcessError
|
||||
|
||||
@@ -219,8 +220,7 @@ def create_ipa_conf(fstore, config, ca_enabled, master=None):
|
||||
else:
|
||||
xmlrpc_uri = 'https://{0}/ipa/xml'.format(
|
||||
ipautil.format_netloc(config.host_name))
|
||||
ldapi_uri = 'ldapi://%2fvar%2frun%2fslapd-{0}.socket\n'.format(
|
||||
installutils.realm_to_serverid(config.realm_name))
|
||||
ldapi_uri = ipaldap.realm_to_ldapi_uri(config.realm_name)
|
||||
|
||||
# [global] section
|
||||
gopts = [
|
||||
@@ -288,7 +288,7 @@ def check_dns_resolution(host_name, dns_servers):
|
||||
logger.error(
|
||||
'Could not resolve any DNS server hostname: %s', dns_servers)
|
||||
return False
|
||||
resolver = dnsresolver.Resolver()
|
||||
resolver = DNSResolver()
|
||||
resolver.nameservers = server_ips
|
||||
|
||||
logger.debug('Search DNS server %s (%s) for %s',
|
||||
@@ -298,7 +298,7 @@ def check_dns_resolution(host_name, dns_servers):
|
||||
addresses = set()
|
||||
for rtype in 'A', 'AAAA':
|
||||
try:
|
||||
result = resolver.query(host_name, rtype)
|
||||
result = resolver.resolve(host_name, rtype)
|
||||
except dnsexception.DNSException:
|
||||
rrset = []
|
||||
else:
|
||||
@@ -326,8 +326,7 @@ def check_dns_resolution(host_name, dns_servers):
|
||||
checked.add(address)
|
||||
try:
|
||||
logger.debug('Check reverse address %s (%s)', address, host_name)
|
||||
revname = dnsreversename.from_address(address)
|
||||
rrset = resolver.query(revname, 'PTR').rrset
|
||||
rrset = resolver.resolve_address(address).rrset
|
||||
except Exception as e:
|
||||
logger.debug('Check failed: %s %s', type(e).__name__, e)
|
||||
logger.error(
|
||||
@@ -362,11 +361,13 @@ def check_dns_resolution(host_name, dns_servers):
|
||||
|
||||
def configure_certmonger():
|
||||
dbus = services.knownservices.dbus
|
||||
try:
|
||||
dbus.start()
|
||||
except Exception as e:
|
||||
raise ScriptError("dbus service unavailable: %s" % str(e),
|
||||
rval=3)
|
||||
if not dbus.is_running():
|
||||
# some platforms protect dbus with RefuseManualStart=True
|
||||
try:
|
||||
dbus.start()
|
||||
except Exception as e:
|
||||
raise ScriptError("dbus service unavailable: %s" % str(e),
|
||||
rval=3)
|
||||
|
||||
# Ensure that certmonger has been started at least once to generate the
|
||||
# cas files in /var/lib/certmonger/cas.
|
||||
@@ -460,6 +461,9 @@ def promote_sssd(host_name):
|
||||
domain.set_option('ipa_server', host_name)
|
||||
domain.set_option('ipa_server_mode', True)
|
||||
sssdconfig.save_domain(domain)
|
||||
|
||||
sssd_enable_ifp(sssdconfig)
|
||||
|
||||
sssdconfig.write()
|
||||
|
||||
sssd = services.service('sssd', api)
|
||||
@@ -492,7 +496,7 @@ def promote_openldap_conf(hostname, master):
|
||||
for opt in old_opts:
|
||||
if opt['type'] == 'comment' and master in opt['value']:
|
||||
continue
|
||||
elif (opt['type'] == 'option' and opt['name'] == 'URI' and
|
||||
if (opt['type'] == 'option' and opt['name'] == 'URI' and
|
||||
master in opt['value']):
|
||||
continue
|
||||
new_opts.append(opt)
|
||||
@@ -565,11 +569,18 @@ def check_remote_version(client, local_version):
|
||||
"the local version ({})".format(remote_version, local_version))
|
||||
|
||||
|
||||
def common_check(no_ntp):
|
||||
def common_check(no_ntp, skip_mem_check, setup_ca):
|
||||
if not skip_mem_check:
|
||||
installutils.check_available_memory(ca=setup_ca)
|
||||
tasks.check_ipv6_stack_enabled()
|
||||
tasks.check_selinux_status()
|
||||
check_ldap_conf()
|
||||
|
||||
mask_str = validate_mask()
|
||||
if mask_str:
|
||||
raise ScriptError(
|
||||
"Unexpected system mask: %s, expected 0022" % mask_str)
|
||||
|
||||
if is_ipa_configured():
|
||||
raise ScriptError(
|
||||
"IPA server is already configured on this system.\n"
|
||||
@@ -735,7 +746,7 @@ def ensure_enrolled(installer):
|
||||
|
||||
def promotion_check_ipa_domain(master_ldap_conn, basedn):
|
||||
entry = master_ldap_conn.get_entry(basedn, ['associatedDomain'])
|
||||
if not 'associatedDomain' in entry:
|
||||
if 'associatedDomain' not in entry:
|
||||
raise RuntimeError('IPA domain not found in LDAP.')
|
||||
|
||||
if len(entry['associatedDomain']) > 1:
|
||||
@@ -767,10 +778,15 @@ def promote_check(installer):
|
||||
installer._top_dir = tempfile.mkdtemp("ipa")
|
||||
|
||||
# check selinux status, http and DS ports, NTP conflicting services
|
||||
common_check(options.no_ntp)
|
||||
common_check(options.no_ntp, options.skip_mem_check, options.setup_ca)
|
||||
|
||||
client_fstore = sysrestore.FileStore(paths.IPA_CLIENT_SYSRESTORE)
|
||||
if not client_fstore.has_files():
|
||||
if options.setup_ca and any([options.dirsrv_cert_files,
|
||||
options.http_cert_files,
|
||||
options.pkinit_cert_files]):
|
||||
raise ScriptError("--setup-ca and --*-cert-file options are "
|
||||
"mutually exclusive")
|
||||
|
||||
if not is_ipa_client_configured(on_master=True):
|
||||
# One-step replica installation
|
||||
if options.password and options.admin_password:
|
||||
raise ScriptError("--password and --admin-password options are "
|
||||
@@ -782,6 +798,8 @@ def promote_check(installer):
|
||||
print("IPA client is already configured on this system, ignoring "
|
||||
"the --domain, --server, --realm, --hostname, --password "
|
||||
"and --keytab options.")
|
||||
# Make sure options.server is not used
|
||||
options.server = None
|
||||
|
||||
# The NTP configuration can not be touched on pre-installed client:
|
||||
if options.no_ntp or options.ntp_servers or options.ntp_pool:
|
||||
@@ -801,7 +819,7 @@ def promote_check(installer):
|
||||
api.bootstrap(in_server=True,
|
||||
context='installer',
|
||||
confdir=paths.ETC_IPA,
|
||||
ldap_uri=installutils.realm_to_ldapi_uri(env.realm),
|
||||
ldap_uri=ipaldap.realm_to_ldapi_uri(env.realm),
|
||||
xmlrpc_uri=xmlrpc_uri)
|
||||
# pylint: enable=no-member
|
||||
api.finalize()
|
||||
@@ -811,13 +829,19 @@ def promote_check(installer):
|
||||
config.host_name = api.env.host
|
||||
config.domain_name = api.env.domain
|
||||
config.master_host_name = api.env.server
|
||||
config.ca_host_name = api.env.ca_host
|
||||
if not api.env.ca_host or api.env.ca_host == api.env.host:
|
||||
# ca_host has not been configured explicitly, prefer source master
|
||||
config.ca_host_name = api.env.server
|
||||
else:
|
||||
# default to ca_host from IPA config
|
||||
config.ca_host_name = api.env.ca_host
|
||||
config.kra_host_name = config.ca_host_name
|
||||
config.ca_ds_port = 389
|
||||
config.setup_ca = options.setup_ca
|
||||
config.setup_kra = options.setup_kra
|
||||
config.dir = installer._top_dir
|
||||
config.basedn = api.env.basedn
|
||||
config.hidden_replica = options.hidden_replica
|
||||
|
||||
http_pkcs12_file = None
|
||||
http_pkcs12_info = None
|
||||
@@ -891,7 +915,11 @@ def promote_check(installer):
|
||||
"certificate")
|
||||
|
||||
installutils.verify_fqdn(config.host_name, options.no_host_dns)
|
||||
installutils.verify_fqdn(config.master_host_name, options.no_host_dns)
|
||||
# Inside the container environment master's IP address does not
|
||||
# resolve to its name. See https://pagure.io/freeipa/issue/6210
|
||||
container_environment = tasks.detect_container() is not None
|
||||
installutils.verify_fqdn(config.master_host_name, options.no_host_dns,
|
||||
local_hostname=not container_environment)
|
||||
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
kinit_keytab('host/{env.host}@{env.realm}'.format(env=api.env),
|
||||
@@ -991,8 +1019,9 @@ def promote_check(installer):
|
||||
|
||||
# Detect if the other master can handle replication managers
|
||||
# cn=replication managers,cn=sysaccounts,cn=etc,$SUFFIX
|
||||
dn = DN(('cn', 'replication managers'), ('cn', 'sysaccounts'),
|
||||
('cn', 'etc'), ipautil.realm_to_suffix(config.realm_name))
|
||||
dn = DN(('cn', 'replication managers'),
|
||||
api.env.container_sysaccounts,
|
||||
ipautil.realm_to_suffix(config.realm_name))
|
||||
try:
|
||||
conn.get_entry(dn)
|
||||
except errors.NotFound:
|
||||
@@ -1025,9 +1054,17 @@ def promote_check(installer):
|
||||
if subject_base is not None:
|
||||
config.subject_base = DN(subject_base)
|
||||
|
||||
# Find if any server has a CA
|
||||
ca_host = service.find_providing_server(
|
||||
'CA', conn, config.ca_host_name)
|
||||
# Find any server with a CA
|
||||
# The order of preference is
|
||||
# 1. the first server specified in --server, if any
|
||||
# 2. the server specified in the config file
|
||||
# 3. any other
|
||||
preferred_cas = [config.ca_host_name]
|
||||
if options.server:
|
||||
preferred_cas.insert(0, options.server)
|
||||
ca_host = find_providing_server(
|
||||
'CA', conn, preferred_cas
|
||||
)
|
||||
if ca_host is not None:
|
||||
config.ca_host_name = ca_host
|
||||
ca_enabled = True
|
||||
@@ -1035,6 +1072,14 @@ def promote_check(installer):
|
||||
logger.error("Certificates could not be provided when "
|
||||
"CA is present on some master.")
|
||||
raise ScriptError(rval=3)
|
||||
if options.setup_ca and options.server and \
|
||||
ca_host != options.server:
|
||||
# Installer was provided with a specific master
|
||||
# but this one doesn't provide CA
|
||||
logger.error("The specified --server %s does not provide CA, "
|
||||
"please provide a server with the CA role",
|
||||
options.server)
|
||||
raise ScriptError(rval=4)
|
||||
else:
|
||||
if options.setup_ca:
|
||||
logger.error("The remote master does not have a CA "
|
||||
@@ -1048,14 +1093,31 @@ def promote_check(installer):
|
||||
"custom certificates.")
|
||||
raise ScriptError(rval=3)
|
||||
|
||||
kra_host = service.find_providing_server(
|
||||
'KRA', conn, config.kra_host_name)
|
||||
# Find any server with a KRA
|
||||
# The order of preference is
|
||||
# 1. the first server specified in --server, if any
|
||||
# 2. the server specified in the config file
|
||||
# 3. any other
|
||||
preferred_kras = [config.kra_host_name]
|
||||
if options.server:
|
||||
preferred_kras.insert(0, options.server)
|
||||
kra_host = find_providing_server(
|
||||
'KRA', conn, preferred_kras
|
||||
)
|
||||
if kra_host is not None:
|
||||
config.kra_host_name = kra_host
|
||||
kra_enabled = True
|
||||
if options.setup_kra and options.server and \
|
||||
kra_host != options.server:
|
||||
# Installer was provided with a specific master
|
||||
# but this one doesn't provide KRA
|
||||
logger.error("The specified --server %s does not provide KRA, "
|
||||
"please provide a server with the KRA role",
|
||||
options.server)
|
||||
raise ScriptError(rval=4)
|
||||
else:
|
||||
if options.setup_kra:
|
||||
logger.error("There is no KRA server in the domain, "
|
||||
logger.error("There is no active KRA server in the domain, "
|
||||
"can't setup a KRA clone")
|
||||
raise ScriptError(rval=3)
|
||||
kra_enabled = False
|
||||
@@ -1143,6 +1205,7 @@ def install(installer):
|
||||
ca_enabled = installer._ca_enabled
|
||||
kra_enabled = installer._kra_enabled
|
||||
fstore = installer._fstore
|
||||
sstore = installer._sstore
|
||||
config = installer._config
|
||||
cafile = installer._ca_file
|
||||
dirsrv_pkcs12_info = installer._dirsrv_pkcs12_info
|
||||
@@ -1153,6 +1216,12 @@ def install(installer):
|
||||
conn = remote_api.Backend.ldap2
|
||||
ccache = os.environ['KRB5CCNAME']
|
||||
|
||||
# Be clear that the installation process is beginning but not done
|
||||
sstore.backup_state('installation', 'complete', False)
|
||||
|
||||
if tasks.configure_pkcs11_modules(fstore):
|
||||
print("Disabled p11-kit-proxy")
|
||||
|
||||
if installer._add_to_ipaservers:
|
||||
try:
|
||||
conn.connect(ccache=installer._ccache)
|
||||
@@ -1286,13 +1355,28 @@ def install(installer):
|
||||
if options.setup_adtrust:
|
||||
adtrust.install(False, options, fstore, api)
|
||||
|
||||
# Enable configured services and update DNS SRV records
|
||||
service.enable_services(config.host_name)
|
||||
if options.hidden_replica:
|
||||
# Set services to hidden
|
||||
service.hide_services(config.host_name)
|
||||
else:
|
||||
# Enable configured services
|
||||
service.enable_services(config.host_name)
|
||||
# update DNS SRV records. Although it's only really necessary in
|
||||
# enabled-service case, also perform update in hidden replica case.
|
||||
api.Command.dns_update_system_records()
|
||||
ca_servers = service.find_providing_servers('CA', api.Backend.ldap2, api)
|
||||
|
||||
if options.setup_adtrust:
|
||||
dns_help = adtrust.generate_dns_service_records_help(api)
|
||||
if dns_help:
|
||||
for line in dns_help:
|
||||
service.print_msg(line, sys.stdout)
|
||||
|
||||
ca_servers = find_providing_servers('CA', api.Backend.ldap2, api=api)
|
||||
api.Backend.ldap2.disconnect()
|
||||
|
||||
# Everything installed properly, activate ipa service.
|
||||
sstore.delete_state('installation', 'complete')
|
||||
sstore.backup_state('installation', 'complete', True)
|
||||
services.knownservices.ipa.enable()
|
||||
|
||||
# Print a warning if CA role is only installed on one server
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user