Imported Debian patch 4.7.2-3

This commit is contained in:
Timo Aaltonen
2019-05-06 08:43:34 +03:00
committed by Mario Fetka
parent 27edeba051
commit 8bc559c5a1
917 changed files with 1068993 additions and 1184676 deletions

View File

@@ -27,7 +27,6 @@ from ipaplatform.paths import paths
from ipapython import ipautil
from ipapython.admintool import ScriptError
import os
import time
FILES_TO_NOT_BACKUP = ['passwd', 'group', 'shadow', 'gshadow']
@@ -39,7 +38,7 @@ def get_auth_tool():
@six.add_metaclass(abc.ABCMeta)
class RedHatAuthToolBase:
class RedHatAuthToolBase(object):
@abc.abstractmethod
def configure(self, sssd, mkhomedir, statestore, sudo=True):
@@ -104,16 +103,28 @@ class RedHatAuthSelect(RedHatAuthToolBase):
def configure(self, sssd, mkhomedir, statestore, sudo=True):
# In the statestore, the following keys are used for the
# 'authselect' module:
# Old method:
# profile: name of the profile configured pre-installation
# features_list: list of features configured pre-installation
# mkhomedir: True if installation was called with --mkhomedir
# profile and features_list are used when reverting to the
# pre-install state
# New method:
# backup: name of the authselect backup
backup_name = "pre_ipaclient_{}".format(time.strftime("%Y%m%d%H%M%S"))
statestore.backup_state('authselect', 'backup', backup_name)
cfg = self._parse_authselect_output()
if cfg:
statestore.backup_state('authselect', 'profile', cfg[0])
statestore.backup_state(
'authselect', 'features_list', " ".join(cfg[1]))
else:
# cfg = None means that the current conf is not managed by
# authselect but by authconfig.
# As we are using authselect to configure the host,
# it will not be possible to revert to a custom authconfig
# configuration later (during uninstall)
# Best thing to do will be to use sssd profile at this time
logger.warning(
"WARNING: The configuration pre-client installation is not "
"managed by authselect and cannot be backed up. "
"Uninstallation may not be able to revert to the original "
"state.")
cmd = [paths.AUTHSELECT, "select", "sssd"]
if mkhomedir:
@@ -122,7 +133,6 @@ class RedHatAuthSelect(RedHatAuthToolBase):
if sudo:
cmd.append("with-sudo")
cmd.append("--force")
cmd.append("--backup={}".format(backup_name))
ipautil.run(cmd)
@@ -157,10 +167,6 @@ class RedHatAuthSelect(RedHatAuthToolBase):
'authselect', 'features_list'
)
statestore.delete_state('authselect', 'mkhomedir')
# https://pagure.io/freeipa/issue/8054
if fstore.has_file(paths.NSSWITCH_CONF):
logger.info("Restoring user-nsswitch.conf")
fstore.restore_file(paths.NSSWITCH_CONF)
# only non-empty features, https://pagure.io/freeipa/issue/7776
if features_state is not None:
features = [
@@ -169,15 +175,10 @@ class RedHatAuthSelect(RedHatAuthToolBase):
else:
features = []
backup = statestore.restore_state('authselect', 'backup')
if backup:
cmd = [paths.AUTHSELECT, "backup-restore", backup]
ipautil.run(cmd)
else:
cmd = [paths.AUTHSELECT, "select", profile]
cmd.extend(features)
cmd.append("--force")
ipautil.run(cmd)
cmd = [paths.AUTHSELECT, "select", profile]
cmd.extend(features)
cmd.append("--force")
ipautil.run(cmd)
def backup(self, path):
current = self._get_authselect_current_output()

View File

@@ -14,9 +14,6 @@ from ipaplatform.base.constants import BaseConstantsNamespace
class RedHatConstantsNamespace(BaseConstantsNamespace):
# Use system-wide crypto policy
# see https://fedoraproject.org/wiki/Changes/CryptoPolicy
TLS_HIGH_CIPHERS = None
pass
constants = RedHatConstantsNamespace()

View File

@@ -39,7 +39,6 @@ class RedHatPathNamespace(BasePathNamespace):
AUTHCONFIG = '/usr/sbin/authconfig'
AUTHSELECT = '/usr/bin/authselect'
SYSCONF_NETWORK = '/etc/sysconfig/network'
NSSWITCH_CONF = '/etc/authselect/user-nsswitch.conf'
paths = RedHatPathNamespace()

View File

@@ -45,8 +45,8 @@ logger = logging.getLogger(__name__)
redhat_system_units = dict((x, "%s.service" % x)
for x in base_services.wellknownservices)
redhat_system_units['rpcgssd'] = 'rpc-gssd.service'
redhat_system_units['rpcidmapd'] = 'nfs-idmapd.service'
redhat_system_units['rpcgssd'] = 'nfs-secure.service'
redhat_system_units['rpcidmapd'] = 'nfs-idmap.service'
redhat_system_units['domainname'] = 'nis-domainname.service'
# Rewrite dirsrv and pki-tomcatd services as they support instances via separate
@@ -186,6 +186,18 @@ class RedHatCAService(RedHatService):
else:
raise RuntimeError('CA did not start in %ss' % timeout)
def start(self, instance_name="", capture_output=True, wait=True):
super(RedHatCAService, self).start(
instance_name, capture_output=capture_output, wait=wait)
if wait:
self.wait_until_running()
def restart(self, instance_name="", capture_output=True, wait=True):
super(RedHatCAService, self).restart(
instance_name, capture_output=capture_output, wait=wait)
if wait:
self.wait_until_running()
def is_running(self, instance_name="", wait=True):
if instance_name:
return super(RedHatCAService, self).is_running(instance_name)

View File

@@ -28,20 +28,17 @@ from __future__ import print_function, absolute_import
import ctypes
import logging
import os
from pathlib import Path
import socket
import traceback
import errno
import urllib
import subprocess
import sys
import textwrap
from ctypes.util import find_library
from functools import total_ordering
from subprocess import CalledProcessError
from pyasn1.error import PyAsn1Error
from six.moves import urllib
from ipapython import directivesetter
from ipapython import ipautil
@@ -55,29 +52,24 @@ from ipaplatform.base.tasks import BaseTaskNamespace
logger = logging.getLogger(__name__)
# /etc/pkcs11/modules override
# base filen ame, module, list of disabled-in
# 'p11-kit-proxy' disables proxying of module, see man(5) pkcs11.conf
PKCS11_MODULES = [
('softhsm2', paths.LIBSOFTHSM2_SO, ['p11-kit-proxy']),
]
NM_IPA_CONF = textwrap.dedent("""
# auto-generated by IPA installer
[main]
dns={dnsprocessing}
[global-dns]
searches={searches}
[global-dns-domain-*]
servers={servers}
""")
def selinux_enabled():
"""
Check if SELinux is enabled.
"""
if os.path.exists(paths.SELINUXENABLED):
try:
ipautil.run([paths.SELINUXENABLED])
return True
except ipautil.CalledProcessError:
# selinuxenabled returns 1 if not enabled
return False
else:
# No selinuxenabled, no SELinux
return False
@total_ordering
class IPAVersion:
class IPAVersion(object):
_rpmvercmp_func = None
@classmethod
@@ -128,7 +120,7 @@ class RedHatTaskNamespace(BaseTaskNamespace):
ipautil.run() will do the logging.
"""
restorecon = paths.SBIN_RESTORECON
if not self.is_selinux_enabled() or not os.path.exists(restorecon):
if not selinux_enabled() or not os.path.exists(restorecon):
return
# Force reset of context to match file_context for customizable
@@ -140,20 +132,6 @@ class RedHatTaskNamespace(BaseTaskNamespace):
args.append(filepath)
ipautil.run(args, raiseonerr=False)
def is_selinux_enabled(self):
"""Check if SELinux is available and enabled
"""
try:
ipautil.run([paths.SELINUXENABLED])
except ipautil.CalledProcessError:
# selinuxenabled returns 1 if not enabled
return False
except OSError:
# selinuxenabled binary not available
return False
else:
return True
def check_selinux_status(self, restorecon=paths.RESTORECON):
"""
We don't have a specific package requirement for policycoreutils
@@ -164,14 +142,13 @@ class RedHatTaskNamespace(BaseTaskNamespace):
This function returns nothing but may raise a Runtime exception
if SELinux is enabled but restorecon is not available.
"""
if not self.is_selinux_enabled():
return False
if not selinux_enabled():
return
if not os.path.exists(restorecon):
raise RuntimeError('SELinux is enabled but %s does not exist.\n'
'Install the policycoreutils package and start '
'the installation again.' % restorecon)
return True
def check_ipv6_stack_enabled(self):
"""Checks whether IPv6 kernel module is loaded.
@@ -189,6 +166,12 @@ class RedHatTaskNamespace(BaseTaskNamespace):
"globally, disable it on the specific interfaces in "
"sysctl.conf except 'lo' interface.")
# XXX This is a hack to work around an issue with Travis CI by
# skipping IPv6 address test. The Dec 2017 update removed ::1 from
# loopback, see https://github.com/travis-ci/travis-ci/issues/8891.
if os.environ.get('TRAVIS') == 'true':
return
try:
localhost6 = ipautil.CheckedIPAddress('::1', allow_loopback=True)
if localhost6.get_matching_interface() is None:
@@ -200,26 +183,6 @@ class RedHatTaskNamespace(BaseTaskNamespace):
"resolution to 'lo' interface. You might need to enable IPv6 "
"on the interface 'lo' in sysctl.conf.")
def detect_container(self):
"""Check if running inside a container
:returns: container runtime or None
:rtype: str, None
"""
try:
output = subprocess.check_output(
[paths.SYSTEMD_DETECT_VIRT, '--container'],
stderr=subprocess.STDOUT
)
except subprocess.CalledProcessError as e:
if e.returncode == 1:
# No container runtime detected
return None
else:
raise
else:
return output.decode('utf-8').strip()
def restore_pre_ipa_client_configuration(self, fstore, statestore,
was_sssd_installed,
was_sssd_configured):
@@ -297,121 +260,128 @@ class RedHatTaskNamespace(BaseTaskNamespace):
logger.info("Systemwide CA database updated.")
return True
def platform_insert_ca_certs(self, ca_certs):
return any([
self.write_p11kit_certs(paths.IPA_P11_KIT, ca_certs),
self.remove_ca_certificates_bundle(
paths.SYSTEMWIDE_IPA_CA_CRT
),
])
def write_p11kit_certs(self, filename, ca_certs):
def insert_ca_certs_into_systemwide_ca_store(self, ca_certs):
# pylint: disable=ipa-forbidden-import
from ipalib import x509 # FixMe: break import cycle
from ipalib.errors import CertificateError
# pylint: enable=ipa-forbidden-import
path = Path(filename)
try:
f = open(path, 'w')
except IOError:
logger.error("Failed to open %s", path)
raise
with f:
f.write("# This file was created by IPA. Do not edit.\n"
"\n")
new_cacert_path = paths.SYSTEMWIDE_IPA_CA_CRT
if os.path.exists(new_cacert_path):
try:
os.fchmod(f.fileno(), 0o644)
except IOError:
logger.error("Failed to set mode of %s", path)
raise
os.remove(new_cacert_path)
except OSError as e:
logger.error(
"Could not remove %s: %s", new_cacert_path, e)
return False
has_eku = set()
for cert, nickname, trusted, _ext_key_usage in ca_certs:
try:
subject = cert.subject_bytes
issuer = cert.issuer_bytes
serial_number = cert.serial_number_bytes
public_key_info = cert.public_key_info_bytes
except (PyAsn1Error, ValueError, CertificateError):
logger.error(
"Failed to decode certificate \"%s\"", nickname)
raise
new_cacert_path = paths.IPA_P11_KIT
label = urllib.parse.quote(nickname)
subject = urllib.parse.quote(subject)
issuer = urllib.parse.quote(issuer)
serial_number = urllib.parse.quote(serial_number)
public_key_info = urllib.parse.quote(public_key_info)
obj = ("[p11-kit-object-v1]\n"
"class: certificate\n"
"certificate-type: x-509\n"
"certificate-category: authority\n"
"label: \"%(label)s\"\n"
"subject: \"%(subject)s\"\n"
"issuer: \"%(issuer)s\"\n"
"serial-number: \"%(serial_number)s\"\n"
"x-public-key-info: \"%(public_key_info)s\"\n" %
dict(label=label,
subject=subject,
issuer=issuer,
serial_number=serial_number,
public_key_info=public_key_info))
if trusted is True:
obj += "trusted: true\n"
elif trusted is False:
obj += "x-distrusted: true\n"
obj += "{pem}\n\n".format(
pem=cert.public_bytes(x509.Encoding.PEM).decode('ascii'))
f.write(obj)
if (cert.extended_key_usage is not None and
public_key_info not in has_eku):
try:
ext_key_usage = cert.extended_key_usage_bytes
except PyAsn1Error:
logger.error(
"Failed to encode extended key usage for \"%s\"",
nickname)
raise
value = urllib.parse.quote(ext_key_usage)
obj = ("[p11-kit-object-v1]\n"
"class: x-certificate-extension\n"
"label: \"ExtendedKeyUsage for %(label)s\"\n"
"x-public-key-info: \"%(public_key_info)s\"\n"
"object-id: 2.5.29.37\n"
"value: \"%(value)s\"\n\n" %
dict(label=label,
public_key_info=public_key_info,
value=value))
f.write(obj)
has_eku.add(public_key_info)
return True
def platform_remove_ca_certs(self):
return any([
self.remove_ca_certificates_bundle(paths.IPA_P11_KIT),
self.remove_ca_certificates_bundle(paths.SYSTEMWIDE_IPA_CA_CRT),
])
def remove_ca_certificates_bundle(self, filename):
path = Path(filename)
if not path.is_file():
try:
f = open(new_cacert_path, 'w')
os.fchmod(f.fileno(), 0o644)
except IOError as e:
logger.info("Failed to open %s: %s", new_cacert_path, e)
return False
try:
path.unlink()
except Exception:
logger.error("Could not remove %s", path)
raise
f.write("# This file was created by IPA. Do not edit.\n"
"\n")
has_eku = set()
for cert, nickname, trusted, _ext_key_usage in ca_certs:
try:
subject = cert.subject_bytes
issuer = cert.issuer_bytes
serial_number = cert.serial_number_bytes
public_key_info = cert.public_key_info_bytes
except (PyAsn1Error, ValueError, CertificateError) as e:
logger.warning(
"Failed to decode certificate \"%s\": %s", nickname, e)
continue
label = urllib.parse.quote(nickname)
subject = urllib.parse.quote(subject)
issuer = urllib.parse.quote(issuer)
serial_number = urllib.parse.quote(serial_number)
public_key_info = urllib.parse.quote(public_key_info)
obj = ("[p11-kit-object-v1]\n"
"class: certificate\n"
"certificate-type: x-509\n"
"certificate-category: authority\n"
"label: \"%(label)s\"\n"
"subject: \"%(subject)s\"\n"
"issuer: \"%(issuer)s\"\n"
"serial-number: \"%(serial_number)s\"\n"
"x-public-key-info: \"%(public_key_info)s\"\n" %
dict(label=label,
subject=subject,
issuer=issuer,
serial_number=serial_number,
public_key_info=public_key_info))
if trusted is True:
obj += "trusted: true\n"
elif trusted is False:
obj += "x-distrusted: true\n"
obj += "{pem}\n\n".format(
pem=cert.public_bytes(x509.Encoding.PEM).decode('ascii'))
f.write(obj)
if (cert.extended_key_usage is not None and
public_key_info not in has_eku):
try:
ext_key_usage = cert.extended_key_usage_bytes
except PyAsn1Error as e:
logger.warning(
"Failed to encode extended key usage for \"%s\": %s",
nickname, e)
continue
value = urllib.parse.quote(ext_key_usage)
obj = ("[p11-kit-object-v1]\n"
"class: x-certificate-extension\n"
"label: \"ExtendedKeyUsage for %(label)s\"\n"
"x-public-key-info: \"%(public_key_info)s\"\n"
"object-id: 2.5.29.37\n"
"value: \"%(value)s\"\n\n" %
dict(label=label,
public_key_info=public_key_info,
value=value))
f.write(obj)
has_eku.add(public_key_info)
f.close()
# Add the CA to the systemwide CA trust database
if not self.reload_systemwide_ca_store():
return False
return True
def remove_ca_certs_from_systemwide_ca_store(self):
result = True
update = False
# Remove CA cert from systemwide store
for new_cacert_path in (paths.IPA_P11_KIT,
paths.SYSTEMWIDE_IPA_CA_CRT):
if not os.path.exists(new_cacert_path):
continue
try:
os.remove(new_cacert_path)
except OSError as e:
logger.error(
"Could not remove %s: %s", new_cacert_path, e)
result = False
else:
update = True
if update:
if not self.reload_systemwide_ca_store():
return False
return result
def backup_hostname(self, fstore, statestore):
filepath = paths.ETC_HOSTNAME
if os.path.exists(filepath):
@@ -445,7 +415,7 @@ class RedHatTaskNamespace(BaseTaskNamespace):
return args
if not self.is_selinux_enabled():
if not selinux_enabled():
return False
updated_vars = {}
@@ -507,11 +477,9 @@ class RedHatTaskNamespace(BaseTaskNamespace):
os.chmod(paths.SYSTEMD_SYSTEM_HTTPD_IPA_CONF, 0o644)
self.restore_context(paths.SYSTEMD_SYSTEM_HTTPD_IPA_CONF)
self.systemd_daemon_reload()
def systemd_daemon_reload(self):
"""Tell systemd to reload config files"""
ipautil.run([paths.SYSTEMCTL, "--system", "daemon-reload"])
ipautil.run([paths.SYSTEMCTL, "--system", "daemon-reload"],
raiseonerr=False)
def configure_http_gssproxy_conf(self, ipaapi_user):
ipautil.copy_template_file(
@@ -575,13 +543,8 @@ class RedHatTaskNamespace(BaseTaskNamespace):
)
return
self.systemd_daemon_reload()
def configure_httpd_protocol(self):
# use default crypto policy for SSLProtocol
directivesetter.set_directive(
paths.HTTPD_SSL_CONF, 'SSLProtocol', None, False
)
ipautil.run([paths.SYSTEMCTL, "--system", "daemon-reload"],
raiseonerr=False)
def set_hostname(self, hostname):
ipautil.run([paths.BIN_HOSTNAMECTL, 'set-hostname', hostname])
@@ -613,166 +576,5 @@ class RedHatTaskNamespace(BaseTaskNamespace):
'TransferLog',
'logs/access_log', False)
def configure_dns_resolver(self, nameservers, searchdomains, *,
resolve1_enabled=False, fstore=None):
"""Configure global DNS resolver (e.g. /etc/resolv.conf)
:param nameservers: list of IP addresses
:param searchdomains: list of search domaons
:param fstore: optional file store for backup
"""
assert nameservers and isinstance(nameservers, list)
assert searchdomains and isinstance(searchdomains, list)
super().configure_dns_resolver(
nameservers=nameservers,
searchdomains=searchdomains,
resolve1_enabled=resolve1_enabled,
fstore=fstore
)
# break circular import
from ipaplatform.services import knownservices
if fstore is not None and not fstore.has_file(paths.RESOLV_CONF):
fstore.backup_file(paths.RESOLV_CONF)
nm = knownservices['NetworkManager']
nm_enabled = nm.is_enabled()
if nm_enabled:
logger.debug(
"Network Manager is enabled, write %s",
paths.NETWORK_MANAGER_IPA_CONF
)
# write DNS override and reload network manager to have it create
# a new resolv.conf. The file is prefixed with ``zzz`` to
# make it the last file. Global dns options do not stack and last
# man standing wins.
if resolve1_enabled:
# push DNS configuration to systemd-resolved
dnsprocessing = "systemd-resolved"
else:
# update /etc/resolv.conf
dnsprocessing = "default"
cfg = NM_IPA_CONF.format(
dnsprocessing=dnsprocessing,
servers=','.join(nameservers),
searches=','.join(searchdomains)
)
with open(paths.NETWORK_MANAGER_IPA_CONF, 'w') as f:
os.fchmod(f.fileno(), 0o644)
f.write(cfg)
# reload NetworkManager
nm.reload_or_restart()
if not resolve1_enabled and not nm_enabled:
# no NM running, no systemd-resolved detected
# fall back to /etc/resolv.conf
logger.debug(
"Neither Network Manager nor systemd-resolved are enabled, "
"write %s directly.", paths.RESOLV_CONF
)
cfg = [
"# auto-generated by IPA installer",
"search {}".format(' '.join(searchdomains)),
]
for nameserver in nameservers:
cfg.append("nameserver {}".format(nameserver))
with open(paths.RESOLV_CONF, 'w') as f:
f.write('\n'.join(cfg))
def unconfigure_dns_resolver(self, fstore=None):
"""Unconfigure global DNS resolver (e.g. /etc/resolv.conf)
:param fstore: optional file store for restore
"""
super().unconfigure_dns_resolver(fstore=fstore)
# break circular import
from ipaplatform.services import knownservices
nm = knownservices['NetworkManager']
if os.path.isfile(paths.NETWORK_MANAGER_IPA_CONF):
os.unlink(paths.NETWORK_MANAGER_IPA_CONF)
if nm.is_enabled():
nm.reload_or_restart()
def configure_pkcs11_modules(self, fstore):
"""Disable global p11-kit configuration for NSS
"""
filenames = []
for name, module, disabled_in in PKCS11_MODULES:
filename = os.path.join(
paths.ETC_PKCS11_MODULES_DIR,
"{}.module".format(name)
)
if os.path.isfile(filename):
# Only back up if file is not yet backed up and it does not
# look like a file that is generated by IPA.
with open(filename) as f:
content = f.read()
is_ipa_file = "IPA" in content
if not is_ipa_file and not fstore.has_file(filename):
logger.debug("Backing up existing '%s'.", filename)
fstore.backup_file(filename)
with open(filename, "w") as f:
f.write("# created by IPA installer\n")
f.write("module: {}\n".format(module))
# see man(5) pkcs11.conf
f.write("disable-in: {}\n".format(", ".join(disabled_in)))
os.fchmod(f.fileno(), 0o644)
self.restore_context(filename)
logger.debug("Created PKCS#11 module config '%s'.", filename)
filenames.append(filename)
return filenames
def restore_pkcs11_modules(self, fstore):
"""Restore global p11-kit configuration for NSS
"""
filenames = []
for name, _module, _disabled_in in PKCS11_MODULES:
filename = os.path.join(
paths.ETC_PKCS11_MODULES_DIR,
"{}.module".format(name)
)
try:
os.unlink(filename)
except OSError:
pass
else:
filenames.append(filename)
if fstore.has_file(filename):
fstore.restore_file(filename)
return filenames
def get_pkcs11_modules(self):
"""Return the list of module config files setup by IPA
"""
return tuple(os.path.join(paths.ETC_PKCS11_MODULES_DIR,
"{}.module".format(name))
for name, _module, _disabled in PKCS11_MODULES)
def enable_ldap_automount(self, statestore):
"""
Point automount to ldap in nsswitch.conf.
This function is for non-SSSD setups only.
"""
super(RedHatTaskNamespace, self).enable_ldap_automount(statestore)
authselect_cmd = [paths.AUTHSELECT, "enable-feature",
"with-custom-automount"]
ipautil.run(authselect_cmd)
def disable_ldap_automount(self, statestore):
"""Disable ldap-based automount"""
super(RedHatTaskNamespace, self).disable_ldap_automount(statestore)
authselect_cmd = [paths.AUTHSELECT, "disable-feature",
"with-custom-automount"]
ipautil.run(authselect_cmd)
tasks = RedHatTaskNamespace()