Imported Debian patch 4.7.2-3
This commit is contained in:
committed by
Mario Fetka
parent
27edeba051
commit
8bc559c5a1
@@ -1,7 +1,7 @@
|
||||
# Makefile.in generated by automake 1.16.2 from Makefile.am.
|
||||
# Makefile.in generated by automake 1.16.1 from Makefile.am.
|
||||
# @configure_input@
|
||||
|
||||
# Copyright (C) 1994-2020 Free Software Foundation, Inc.
|
||||
# Copyright (C) 1994-2018 Free Software Foundation, Inc.
|
||||
|
||||
# This Makefile.in is free software; the Free Software Foundation
|
||||
# gives unlimited permission to copy and/or distribute it,
|
||||
@@ -185,8 +185,6 @@ JSLINT = @JSLINT@
|
||||
KRAD_LIBS = @KRAD_LIBS@
|
||||
KRB5KDC_SERVICE = @KRB5KDC_SERVICE@
|
||||
KRB5_CFLAGS = @KRB5_CFLAGS@
|
||||
KRB5_GSSAPI_CFLAGS = @KRB5_GSSAPI_CFLAGS@
|
||||
KRB5_GSSAPI_LIBS = @KRB5_GSSAPI_LIBS@
|
||||
KRB5_LIBS = @KRB5_LIBS@
|
||||
LD = @LD@
|
||||
LDAP_CFLAGS = @LDAP_CFLAGS@
|
||||
@@ -229,10 +227,11 @@ NM = @NM@
|
||||
NMEDIT = @NMEDIT@
|
||||
NSPR_CFLAGS = @NSPR_CFLAGS@
|
||||
NSPR_LIBS = @NSPR_LIBS@
|
||||
NSS_CFLAGS = @NSS_CFLAGS@
|
||||
NSS_LIBS = @NSS_LIBS@
|
||||
NUM_VERSION = @NUM_VERSION@
|
||||
OBJDUMP = @OBJDUMP@
|
||||
OBJEXT = @OBJEXT@
|
||||
ODS_GROUP = @ODS_GROUP@
|
||||
ODS_USER = @ODS_USER@
|
||||
OTOOL = @OTOOL@
|
||||
OTOOL64 = @OTOOL64@
|
||||
@@ -253,6 +252,8 @@ POPT_LIBS = @POPT_LIBS@
|
||||
POSUB = @POSUB@
|
||||
PYLINT = @PYLINT@
|
||||
PYTHON = @PYTHON@
|
||||
PYTHON2 = @PYTHON2@
|
||||
PYTHON3 = @PYTHON3@
|
||||
PYTHON_EXEC_PREFIX = @PYTHON_EXEC_PREFIX@
|
||||
PYTHON_INSTALL_EXTRA_OPTIONS = @PYTHON_INSTALL_EXTRA_OPTIONS@
|
||||
PYTHON_PLATFORM = @PYTHON_PLATFORM@
|
||||
@@ -340,9 +341,7 @@ program_transform_name = @program_transform_name@
|
||||
psdir = @psdir@
|
||||
pyexecdir = @pyexecdir@
|
||||
pythondir = @pythondir@
|
||||
runstatedir = @runstatedir@
|
||||
sbindir = @sbindir@
|
||||
selinux_makefile = @selinux_makefile@
|
||||
sharedstatedir = @sharedstatedir@
|
||||
srcdir = @srcdir@
|
||||
sysconfdir = @sysconfdir@
|
||||
|
||||
@@ -1,50 +0,0 @@
|
||||
# IPA platform abstraction
|
||||
|
||||
The ``ipaplatform`` package provides an abstraction layer for
|
||||
supported Linux distributions and flavors. The package contains
|
||||
constants, paths to commands and config files, services, and tasks.
|
||||
|
||||
* **base** abstract base platform
|
||||
* **debian** Debian- and Ubuntu-like
|
||||
* **redhat** abstract base for Red Hat platforms
|
||||
* **fedora** Fedora
|
||||
* **fedora_container** freeipa-container on Fedora
|
||||
* **rhel** RHEL and CentOS
|
||||
* **rhel_container** freeipa-container on RHEL and CentOS
|
||||
* **suse** OpenSUSE and SLES
|
||||
|
||||
```
|
||||
[base]
|
||||
├─ debian
|
||||
├─[redhat]
|
||||
│ ├─ fedora
|
||||
│ │ └─ fedora_container
|
||||
│ └─ rhel
|
||||
│ └─ rhel_container
|
||||
└─ suse
|
||||
```
|
||||
(Note: Debian and SUSE use some definitions from Red Hat namespace.)
|
||||
|
||||
|
||||
## freeipa-container platform
|
||||
|
||||
The **fedora_container** and **rhel_container** platforms are flavors
|
||||
of the **fedora** and **rhel** platforms. These platform definitions
|
||||
are specifically designed for
|
||||
[freeipa-container](https://github.com/freeipa/freeipa-container).
|
||||
The FreeIPA server container implements a read-only container. Paths
|
||||
like ``/etc``, ``/usr``, and ``/var`` are mounted read-only and cannot
|
||||
be modified. The image uses symlinks to store all variable data like
|
||||
config files and LDAP database in ``/data``.
|
||||
|
||||
* Some commands don't write through dangling symlinks. The IPA
|
||||
platforms for containers prefix some paths with ``/data``.
|
||||
* ``ipa-server-upgrade`` verifies that the platform does not change
|
||||
between versions. To allow upgrades of old containers, sysupgrade
|
||||
maps ``$distro_container`` to ``$distro`` platform.
|
||||
* The container images come with authselect pre-configured with
|
||||
``sssd with-sudo`` option. The tasks ``modify_nsswitch_pam_stack``
|
||||
and ``migrate_auth_configuration`` are no-ops. ``ipa-restore``
|
||||
does not restore authselect settings. ``ipa-backup`` still stores
|
||||
authselect settings in backup data.
|
||||
* The ``--mkhomedir`` option is not supported.
|
||||
@@ -1,6 +1,11 @@
|
||||
#
|
||||
# Copyright (C) 2017 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
"""ipaplatform package
|
||||
"""ipaplatform namespace package
|
||||
|
||||
In the presence of a namespace package, any code in this module will be
|
||||
ignore.
|
||||
"""
|
||||
__import__('pkg_resources').declare_namespace(__name__)
|
||||
|
||||
NAME = None # initialized by ipaplatform.osinfo
|
||||
|
||||
@@ -10,7 +10,7 @@ import sys
|
||||
from ipaplatform.osinfo import osinfo
|
||||
|
||||
|
||||
class IpaMetaImporter:
|
||||
class IpaMetaImporter(object):
|
||||
modules = {
|
||||
'ipaplatform.constants',
|
||||
'ipaplatform.paths',
|
||||
|
||||
@@ -8,10 +8,8 @@ This base platform module exports platform dependant constants.
|
||||
import sys
|
||||
|
||||
|
||||
class BaseConstantsNamespace:
|
||||
class BaseConstantsNamespace(object):
|
||||
IS_64BITS = sys.maxsize > 2 ** 32
|
||||
DEFAULT_ADMIN_SHELL = '/bin/bash'
|
||||
DEFAULT_SHELL = '/bin/sh'
|
||||
DS_USER = 'dirsrv'
|
||||
DS_GROUP = 'dirsrv'
|
||||
HTTPD_USER = "apache"
|
||||
@@ -43,31 +41,6 @@ class BaseConstantsNamespace:
|
||||
'httpd_run_ipa': 'on',
|
||||
'httpd_dbus_sssd': 'on',
|
||||
}
|
||||
# Unlike above, there are multiple use cases for SMB sharing
|
||||
# SELINUX_BOOLEAN_SMBSERVICE is a dictionary of dictionaries
|
||||
# to define set of booleans for each use case
|
||||
SELINUX_BOOLEAN_SMBSERVICE = {
|
||||
'share_home_dirs': {
|
||||
'samba_enable_home_dirs': 'on',
|
||||
},
|
||||
'reshare_nfs_with_samba': {
|
||||
'samba_share_nfs': 'on',
|
||||
},
|
||||
}
|
||||
SELINUX_MCS_MAX = 1023
|
||||
SELINUX_MCS_REGEX = r"^c(\d+)([.,-]c(\d+))*$"
|
||||
SELINUX_MLS_MAX = 15
|
||||
SELINUX_MLS_REGEX = r"^s(\d+)(-s(\d+))?$"
|
||||
SELINUX_USER_REGEX = r"^[a-zA-Z][a-zA-Z_\.]*$"
|
||||
SELINUX_USERMAP_DEFAULT = "unconfined_u:s0-s0:c0.c1023"
|
||||
SELINUX_USERMAP_ORDER = (
|
||||
"guest_u:s0"
|
||||
"$xguest_u:s0"
|
||||
"$user_u:s0"
|
||||
"$staff_u:s0-s0:c0.c1023"
|
||||
"$sysadm_u:s0-s0:c0.c1023"
|
||||
"$unconfined_u:s0-s0:c0.c1023"
|
||||
)
|
||||
SSSD_USER = "sssd"
|
||||
# WSGI module override, only used on Fedora
|
||||
MOD_WSGI_PYTHON2 = None
|
||||
|
||||
@@ -21,20 +21,20 @@
|
||||
This base platform module exports default filesystem paths.
|
||||
'''
|
||||
|
||||
import os
|
||||
|
||||
|
||||
class BasePathNamespace:
|
||||
class BasePathNamespace(object):
|
||||
BASH = "/bin/bash"
|
||||
BIN_HOSTNAMECTL = "/bin/hostnamectl"
|
||||
ECHO = "/bin/echo"
|
||||
FIPS_MODE_SETUP = "/usr/bin/fips-mode-setup"
|
||||
GZIP = "/bin/gzip"
|
||||
GZIP = "/usr/bin/gzip"
|
||||
LS = "/bin/ls"
|
||||
SH = "/bin/sh"
|
||||
SYSTEMCTL = "/bin/systemctl"
|
||||
SYSTEMD_DETECT_VIRT = "/usr/bin/systemd-detect-virt"
|
||||
SYSTEMD_TMPFILES = "/usr/bin/systemd-tmpfiles"
|
||||
TAR = "/bin/tar"
|
||||
AUTOFS_LDAP_AUTH_CONF = "/etc/autofs_ldap_auth.conf"
|
||||
ETC_DIRSRV = "/etc/dirsrv"
|
||||
DS_KEYTAB = "/etc/dirsrv/ds.keytab"
|
||||
ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE = "/etc/dirsrv/slapd-%s"
|
||||
ETC_FEDORA_RELEASE = "/etc/fedora-release"
|
||||
GROUP = "/etc/group"
|
||||
ETC_HOSTNAME = "/etc/hostname"
|
||||
@@ -76,23 +76,15 @@ class BasePathNamespace:
|
||||
COMMON_KRB5_CONF_DIR = "/etc/krb5.conf.d/"
|
||||
KRB5_CONF = "/etc/krb5.conf"
|
||||
KRB5_FREEIPA = COMMON_KRB5_CONF_DIR + "freeipa"
|
||||
KRB5_FREEIPA_SERVER = COMMON_KRB5_CONF_DIR + "freeipa-server"
|
||||
KRB5_KEYTAB = "/etc/krb5.keytab"
|
||||
LDAP_CONF = "/etc/ldap.conf"
|
||||
LIBNSS_LDAP_CONF = "/etc/libnss-ldap.conf"
|
||||
NAMED_CONF = "/etc/named.conf"
|
||||
NAMED_CONF_BAK = "/etc/named.conf.ipa-backup"
|
||||
NAMED_CUSTOM_CONF = "/etc/named/ipa-ext.conf"
|
||||
NAMED_CUSTOM_OPTIONS_CONF = "/etc/named/ipa-options-ext.conf"
|
||||
NAMED_CONF_SRC = '/usr/share/ipa/bind.named.conf.template'
|
||||
NAMED_CUSTOM_CONF_SRC = '/usr/share/ipa/bind.ipa-ext.conf.template'
|
||||
NAMED_CUSTOM_OPTIONS_CONF_SRC = (
|
||||
'/usr/share/ipa/bind.ipa-options-ext.conf.template'
|
||||
)
|
||||
NAMED_VAR_DIR = "/var/named"
|
||||
NAMED_KEYTAB = "/etc/named.keytab"
|
||||
NAMED_RFC1912_ZONES = "/etc/named.rfc1912.zones"
|
||||
NAMED_ROOT_KEY = "/etc/named.root.key"
|
||||
NAMED_BINDKEYS_FILE = "/etc/named.iscdlv.key"
|
||||
NAMED_MANAGED_KEYS_DIR = "/var/named/dynamic"
|
||||
NAMED_CRYPTO_POLICY_FILE = None
|
||||
NSLCD_CONF = "/etc/nslcd.conf"
|
||||
@@ -108,19 +100,13 @@ class BasePathNamespace:
|
||||
OPENLDAP_LDAP_CONF = "/etc/openldap/ldap.conf"
|
||||
PAM_LDAP_CONF = "/etc/pam_ldap.conf"
|
||||
PASSWD = "/etc/passwd"
|
||||
# Trusted CA certificates used to be written out to this file. In newer
|
||||
# versions of FreeIPA, it has been replaced by IPA_P11_KIT.
|
||||
SYSTEMWIDE_IPA_CA_CRT = "/etc/pki/ca-trust/source/anchors/ipa-ca.crt"
|
||||
IPA_P11_KIT = "/etc/pki/ca-trust/source/ipa.p11-kit"
|
||||
CA_CERTIFICATES_BUNDLE_PEM = None
|
||||
CA_CERTIFICATES_DIR = None
|
||||
NSS_DB_DIR = "/etc/pki/nssdb"
|
||||
PKI_CONFIGURATION = "/etc/pki"
|
||||
PKI_TOMCAT = "/etc/pki/pki-tomcat"
|
||||
PKI_TOMCAT_ALIAS_DIR = "/etc/pki/pki-tomcat/alias"
|
||||
PKI_TOMCAT_ALIAS_PWDFILE_TXT = "/etc/pki/pki-tomcat/alias/pwdfile.txt"
|
||||
PKI_TOMCAT_PASSWORD_CONF = "/etc/pki/pki-tomcat/password.conf"
|
||||
PKI_TOMCAT_SERVER_XML = "/etc/pki/pki-tomcat/server.xml"
|
||||
ETC_REDHAT_RELEASE = "/etc/redhat-release"
|
||||
RESOLV_CONF = "/etc/resolv.conf"
|
||||
SAMBA_KEYTAB = "/etc/samba/samba.keytab"
|
||||
@@ -129,8 +115,6 @@ class BasePathNamespace:
|
||||
SSH_CONFIG_DIR = "/etc/ssh"
|
||||
SSH_CONFIG = "/etc/ssh/ssh_config"
|
||||
SSHD_CONFIG = "/etc/ssh/sshd_config"
|
||||
SSHD_IPA_CONFIG = "/etc/ssh/sshd_config.d/04-ipa.conf"
|
||||
SSHD_IPA_CONFIG_TEMPLATE = "/usr/share/ipa/client/sshd_ipa.conf.template"
|
||||
SSSD_CONF = "/etc/sssd/sssd.conf"
|
||||
SSSD_CONF_BKP = "/etc/sssd/sssd.conf.bkp"
|
||||
SSSD_CONF_DELETED = "/etc/sssd/sssd.conf.deleted"
|
||||
@@ -158,8 +142,6 @@ class BasePathNamespace:
|
||||
SYSTEMD_IPA_SERVICE = "/etc/systemd/system/multi-user.target.wants/ipa.service"
|
||||
SYSTEMD_SSSD_SERVICE = "/etc/systemd/system/multi-user.target.wants/sssd.service"
|
||||
SYSTEMD_PKI_TOMCAT_SERVICE = "/etc/systemd/system/pki-tomcatd.target.wants/pki-tomcatd@pki-tomcat.service"
|
||||
SYSTEMD_PKI_TOMCAT_IPA_CONF = \
|
||||
"/etc/systemd/system/pki-tomcatd@pki-tomcat.service.d/ipa.conf"
|
||||
ETC_TMPFILESD_DIRSRV = "/etc/tmpfiles.d/dirsrv-%s.conf"
|
||||
DNSSEC_TRUSTED_KEY = "/etc/trusted-key.key"
|
||||
HOME_DIR = "/home"
|
||||
@@ -187,7 +169,6 @@ class BasePathNamespace:
|
||||
FIREFOX = "/usr/bin/firefox"
|
||||
GETCERT = "/usr/bin/getcert"
|
||||
GPG2 = "/usr/bin/gpg2"
|
||||
GPG_CONF = "/usr/bin/gpgconf"
|
||||
GPG_CONNECT_AGENT = "/usr/bin/gpg-connect-agent"
|
||||
GPG_AGENT = "/usr/bin/gpg-agent"
|
||||
IPA_GETCERT = "/usr/bin/ipa-getcert"
|
||||
@@ -195,7 +176,6 @@ class BasePathNamespace:
|
||||
KDESTROY = "/usr/bin/kdestroy"
|
||||
KINIT = "/usr/bin/kinit"
|
||||
KLIST = "/usr/bin/klist"
|
||||
KTUTIL = "/usr/bin/ktutil"
|
||||
BIN_KVNO = "/usr/bin/kvno"
|
||||
LDAPMODIFY = "/usr/bin/ldapmodify"
|
||||
LDAPPASSWD = "/usr/bin/ldappasswd"
|
||||
@@ -205,8 +185,6 @@ class BasePathNamespace:
|
||||
NSUPDATE = "/usr/bin/nsupdate"
|
||||
ODS_KSMUTIL = "/usr/bin/ods-ksmutil"
|
||||
ODS_SIGNER = "/usr/sbin/ods-signer"
|
||||
ODS_ENFORCER = "/usr/sbin/ods-enforcer"
|
||||
ODS_ENFORCER_DB_SETUP = "/usr/sbin/ods-enforcer-db-setup"
|
||||
OPENSSL = "/usr/bin/openssl"
|
||||
PK12UTIL = "/usr/bin/pk12util"
|
||||
SOFTHSM2_UTIL = "/usr/bin/softhsm2-util"
|
||||
@@ -219,28 +197,26 @@ class BasePathNamespace:
|
||||
BIND_LDAP_SO = "/usr/lib/bind/ldap.so"
|
||||
BIND_LDAP_DNS_IPA_WORKDIR = "/var/named/dyndb-ldap/ipa/"
|
||||
BIND_LDAP_DNS_ZONE_WORKDIR = "/var/named/dyndb-ldap/ipa/master/"
|
||||
USR_LIB_DIRSRV = "/usr/lib/dirsrv"
|
||||
LIB_FIREFOX = "/usr/lib/firefox"
|
||||
LIBSOFTHSM2_SO = "/usr/lib/pkcs11/libsofthsm2.so"
|
||||
PAM_KRB5_SO = "/usr/lib/security/pam_krb5.so"
|
||||
LIB_SYSTEMD_SYSTEMD_DIR = "/usr/lib/systemd/system/"
|
||||
BIND_LDAP_SO_64 = "/usr/lib64/bind/ldap.so"
|
||||
USR_LIB_DIRSRV_64 = "/usr/lib64/dirsrv"
|
||||
LIB64_FIREFOX = "/usr/lib64/firefox"
|
||||
LIBSOFTHSM2_SO_64 = "/usr/lib64/pkcs11/libsofthsm2.so"
|
||||
PAM_KRB5_SO_64 = "/usr/lib64/security/pam_krb5.so"
|
||||
LIBEXEC_CERTMONGER_DIR = "/usr/libexec/certmonger"
|
||||
DOGTAG_IPA_CA_RENEW_AGENT_SUBMIT = "/usr/libexec/certmonger/dogtag-ipa-ca-renew-agent-submit"
|
||||
DOGTAG_IPA_RENEW_AGENT_SUBMIT = "/usr/libexec/certmonger/dogtag-ipa-renew-agent-submit"
|
||||
CERTMONGER_DOGTAG_SUBMIT = "/usr/libexec/certmonger/dogtag-submit"
|
||||
IPA_SERVER_GUARD = "/usr/libexec/certmonger/ipa-server-guard"
|
||||
GENERATE_RNDC_KEY = "/usr/libexec/generate-rndc-key.sh"
|
||||
LIBEXEC_IPA_DIR = "/usr/libexec/ipa"
|
||||
IPA_DNSKEYSYNCD_REPLICA = "/usr/libexec/ipa/ipa-dnskeysync-replica"
|
||||
IPA_DNSKEYSYNCD = "/usr/libexec/ipa/ipa-dnskeysyncd"
|
||||
IPA_HTTPD_KDCPROXY = "/usr/libexec/ipa/ipa-httpd-kdcproxy"
|
||||
IPA_ODS_EXPORTER = "/usr/libexec/ipa/ipa-ods-exporter"
|
||||
IPA_PKI_RETRIEVE_KEY = "/usr/libexec/ipa/ipa-pki-retrieve-key"
|
||||
IPA_HTTPD_PASSWD_READER = "/usr/libexec/ipa/ipa-httpd-pwdreader"
|
||||
IPA_PKI_WAIT_RUNNING = "/usr/libexec/ipa/ipa-pki-wait-running"
|
||||
DNSSEC_KEYFROMLABEL = "/usr/sbin/dnssec-keyfromlabel-pkcs11"
|
||||
GETSEBOOL = "/usr/sbin/getsebool"
|
||||
GROUPADD = "/usr/sbin/groupadd"
|
||||
@@ -260,14 +236,14 @@ class BasePathNamespace:
|
||||
PKIDESTROY = "/usr/sbin/pkidestroy"
|
||||
PKISPAWN = "/usr/sbin/pkispawn"
|
||||
PKI = "/usr/bin/pki"
|
||||
REMOVE_DS_PL = "/usr/sbin/remove-ds.pl"
|
||||
RESTORECON = "/usr/sbin/restorecon"
|
||||
SELINUXENABLED = "/usr/sbin/selinuxenabled"
|
||||
SETSEBOOL = "/usr/sbin/setsebool"
|
||||
SETUP_DS_PL = "/usr/sbin/setup-ds.pl"
|
||||
SMBD = "/usr/sbin/smbd"
|
||||
USERADD = "/usr/sbin/useradd"
|
||||
FONTS_DIR = "/usr/share/fonts"
|
||||
FONTS_OPENSANS_DIR = "/usr/share/fonts/open-sans"
|
||||
FONTS_FONTAWESOME_DIR = "/usr/share/fonts/fontawesome"
|
||||
USR_SHARE_IPA_DIR = "/usr/share/ipa/"
|
||||
USR_SHARE_IPA_CLIENT_DIR = "/usr/share/ipa/client"
|
||||
CA_TOPOLOGY_ULDIF = "/usr/share/ipa/ca-topology.uldif"
|
||||
@@ -283,6 +259,7 @@ class BasePathNamespace:
|
||||
IPA_JS_PLUGINS_DIR = "/usr/share/ipa/ui/js/plugins"
|
||||
UPDATES_DIR = "/usr/share/ipa/updates/"
|
||||
DICT_WORDS = "/usr/share/dict/words"
|
||||
CACHE_IPA_SESSIONS = "/var/cache/ipa/sessions"
|
||||
VAR_KERBEROS_KRB5KDC_DIR = "/var/kerberos/krb5kdc/"
|
||||
VAR_KRB5KDC_K5_REALM = "/var/kerberos/krb5kdc/.k5."
|
||||
CACERT_PEM = "/var/kerberos/krb5kdc/cacert.pem"
|
||||
@@ -299,6 +276,11 @@ class BasePathNamespace:
|
||||
CERTMONGER_REQUESTS_DIR = "/var/lib/certmonger/requests/"
|
||||
VAR_LIB_DIRSRV = "/var/lib/dirsrv"
|
||||
DIRSRV_BOOT_LDIF = "/var/lib/dirsrv/boot.ldif"
|
||||
VAR_LIB_DIRSRV_INSTANCE_SCRIPTS_TEMPLATE = "/var/lib/dirsrv/scripts-%s"
|
||||
VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-%s"
|
||||
SLAPD_INSTANCE_BACKUP_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-%s/bak/%s"
|
||||
SLAPD_INSTANCE_DB_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-%s/db/%s"
|
||||
SLAPD_INSTANCE_LDIF_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-%s/ldif"
|
||||
VAR_LIB_IPA = "/var/lib/ipa"
|
||||
IPA_CLIENT_SYSRESTORE = "/var/lib/ipa-client/sysrestore"
|
||||
SYSRESTORE_INDEX = "/var/lib/ipa-client/sysrestore/sysrestore.index"
|
||||
@@ -326,21 +308,22 @@ class BasePathNamespace:
|
||||
"/var/lib/pki/pki-tomcat/ca/profiles/ca/caSignedLogCert.cfg")
|
||||
KRA_CS_CFG_PATH = "/var/lib/pki/pki-tomcat/conf/kra/CS.cfg"
|
||||
KRACERT_P12 = "/root/kracert.p12"
|
||||
SAMBA_DIR = "/var/lib/samba"
|
||||
SAMBA_DIR = "/var/lib/samba/"
|
||||
SSSD_DB = "/var/lib/sss/db"
|
||||
SSSD_MC_GROUP = "/var/lib/sss/mc/group"
|
||||
SSSD_MC_PASSWD = "/var/lib/sss/mc/passwd"
|
||||
SSSD_PUBCONF_DIR = "/var/lib/sss/pubconf"
|
||||
SSSD_PUBCONF_KNOWN_HOSTS = "/var/lib/sss/pubconf/known_hosts"
|
||||
SSSD_PUBCONF_KRB5_INCLUDE_D_DIR = "/var/lib/sss/pubconf/krb5.include.d/"
|
||||
VAR_LOG_AUDIT = "/var/log/audit/audit.log"
|
||||
DIRSRV_LOCK_DIR = "/var/lock/dirsrv"
|
||||
VAR_LOG_DIRSRV_INSTANCE_TEMPLATE = "/var/log/dirsrv/slapd-%s"
|
||||
SLAPD_INSTANCE_ACCESS_LOG_TEMPLATE = "/var/log/dirsrv/slapd-%s/access"
|
||||
SLAPD_INSTANCE_ERROR_LOG_TEMPLATE = "/var/log/dirsrv/slapd-%s/errors"
|
||||
VAR_LOG_HTTPD_DIR = "/var/log/httpd"
|
||||
VAR_LOG_HTTPD_ERROR = "/var/log/httpd/error_log"
|
||||
IPABACKUP_LOG = "/var/log/ipabackup.log"
|
||||
IPACLIENT_INSTALL_LOG = "/var/log/ipaclient-install.log"
|
||||
IPACLIENT_UNINSTALL_LOG = "/var/log/ipaclient-uninstall.log"
|
||||
IPACLIENTSAMBA_INSTALL_LOG = "/var/log/ipaclientsamba-install.log"
|
||||
IPACLIENTSAMBA_UNINSTALL_LOG = "/var/log/ipaclientsamba-uninstall.log"
|
||||
IPAREPLICA_CA_INSTALL_LOG = "/var/log/ipareplica-ca-install.log"
|
||||
IPAREPLICA_CONNCHECK_LOG = "/var/log/ipareplica-conncheck.log"
|
||||
IPAREPLICA_INSTALL_LOG = "/var/log/ipareplica-install.log"
|
||||
@@ -349,13 +332,10 @@ class BasePathNamespace:
|
||||
IPASERVER_KRA_INSTALL_LOG = "/var/log/ipaserver-kra-install.log"
|
||||
IPASERVER_UNINSTALL_LOG = "/var/log/ipaserver-uninstall.log"
|
||||
IPAUPGRADE_LOG = "/var/log/ipaupgrade.log"
|
||||
IPATRUSTENABLEAGENT_LOG = "/var/log/ipatrust-enable-agent.log"
|
||||
IPAEPN_LOG = "/var/log/ipaepn.log"
|
||||
KADMIND_LOG = "/var/log/kadmind.log"
|
||||
KRB5KDC_LOG = "/var/log/krb5kdc.log"
|
||||
MESSAGES = "/var/log/messages"
|
||||
VAR_LOG_PKI_DIR = "/var/log/pki/"
|
||||
BIN_TOMCAT = "/usr/sbin/tomcat"
|
||||
TOMCAT_TOPLEVEL_DIR = "/var/log/pki/pki-tomcat"
|
||||
TOMCAT_CA_DIR = "/var/log/pki/pki-tomcat/ca"
|
||||
TOMCAT_CA_ARCHIVE_DIR = "/var/log/pki/pki-tomcat/ca/archive"
|
||||
@@ -369,28 +349,30 @@ class BasePathNamespace:
|
||||
VAR_OPENDNSSEC_DIR = "/var/opendnssec"
|
||||
OPENDNSSEC_KASP_DB = "/var/opendnssec/kasp.db"
|
||||
IPA_ODS_EXPORTER_CCACHE = "/var/opendnssec/tmp/ipa-ods-exporter.ccache"
|
||||
VAR_RUN_DIRSRV_DIR = "/run/dirsrv"
|
||||
VAR_RUN_DIRSRV_DIR = "/var/run/dirsrv"
|
||||
IPA_CCACHES = "/run/ipa/ccaches"
|
||||
HTTP_CCACHE = "/var/lib/ipa/gssproxy/http.ccache"
|
||||
CA_BUNDLE_PEM = "/var/lib/ipa-client/pki/ca-bundle.pem"
|
||||
KDC_CA_BUNDLE_PEM = "/var/lib/ipa-client/pki/kdc-ca-bundle.pem"
|
||||
IPA_RENEWAL_LOCK = "/run/ipa/renewal.lock"
|
||||
SVC_LIST_FILE = "/run/ipa/services.list"
|
||||
KRB5CC_SAMBA = "/run/samba/krb5cc_samba"
|
||||
SLAPD_INSTANCE_SOCKET_TEMPLATE = "/run/slapd-%s.socket"
|
||||
IPA_RENEWAL_LOCK = "/var/run/ipa/renewal.lock"
|
||||
SVC_LIST_FILE = "/var/run/ipa/services.list"
|
||||
KRB5CC_SAMBA = "/var/run/samba/krb5cc_samba"
|
||||
SLAPD_INSTANCE_SOCKET_TEMPLATE = "/var/run/slapd-%s.socket"
|
||||
ALL_SLAPD_INSTANCE_SOCKETS = "/var/run/slapd-*.socket"
|
||||
ADMIN_CERT_PATH = '/root/.dogtag/pki-tomcat/ca_admin.cert'
|
||||
ENTROPY_AVAIL = '/proc/sys/kernel/random/entropy_avail'
|
||||
LDIF2DB = '/usr/sbin/ldif2db'
|
||||
DB2LDIF = '/usr/sbin/db2ldif'
|
||||
BAK2DB = '/usr/sbin/bak2db'
|
||||
DB2BAK = '/usr/sbin/db2bak'
|
||||
KDCPROXY_CONFIG = '/etc/ipa/kdcproxy/kdcproxy.conf'
|
||||
CERTMONGER = '/usr/sbin/certmonger'
|
||||
NETWORK_MANAGER_CONFIG_DIR = '/etc/NetworkManager/conf.d'
|
||||
NETWORK_MANAGER_IPA_CONF = '/etc/NetworkManager/conf.d/zzz-ipa.conf'
|
||||
SYSTEMD_RESOLVED_IPA_CONF = '/etc/systemd/resolved.conf.d/zzz-ipa.conf'
|
||||
IPA_CUSTODIA_CONF_DIR = '/etc/ipa/custodia'
|
||||
IPA_CUSTODIA_CONF = '/etc/ipa/custodia/custodia.conf'
|
||||
IPA_CUSTODIA_KEYS = '/etc/ipa/custodia/server.keys'
|
||||
IPA_CUSTODIA_SOCKET = '/run/httpd/ipa-custodia.sock'
|
||||
IPA_CUSTODIA_AUDIT_LOG = '/var/log/ipa-custodia.audit.log'
|
||||
IPA_CUSTODIA_HANDLER = "/usr/libexec/ipa/custodia"
|
||||
IPA_GETKEYTAB = '/usr/sbin/ipa-getkeytab'
|
||||
EXTERNAL_SCHEMA_DIR = '/usr/share/ipa/schema.d'
|
||||
GSSPROXY_CONF = '/etc/gssproxy/10-ipa.conf'
|
||||
@@ -400,64 +382,12 @@ class BasePathNamespace:
|
||||
AUTHCONFIG = None
|
||||
AUTHSELECT = None
|
||||
SYSCONF_NETWORK = None
|
||||
ETC_PKCS11_MODULES_DIR = "/etc/pkcs11/modules"
|
||||
# 389 DS related commands.
|
||||
DSCREATE = '/usr/sbin/dscreate'
|
||||
DSCTL = '/usr/sbin/dsctl'
|
||||
DSCONF = '/usr/sbin/dsconf'
|
||||
# DS related constants
|
||||
ETC_DIRSRV = "/etc/dirsrv"
|
||||
DS_KEYTAB = "/etc/dirsrv/ds.keytab"
|
||||
ETC_DIRSRV_SLAPD_INSTANCE_TEMPLATE = "/etc/dirsrv/slapd-%s"
|
||||
USR_LIB_DIRSRV = "/usr/lib/dirsrv"
|
||||
USR_LIB_DIRSRV_64 = "/usr/lib64/dirsrv"
|
||||
VAR_LIB_DIRSRV_INSTANCE_SCRIPTS_TEMPLATE = "/var/lib/dirsrv/scripts-%s"
|
||||
VAR_LIB_SLAPD_INSTANCE_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-%s"
|
||||
SLAPD_INSTANCE_BACKUP_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-%s/bak/%s"
|
||||
SLAPD_INSTANCE_DB_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-%s/db/%s"
|
||||
SLAPD_INSTANCE_LDIF_DIR_TEMPLATE = "/var/lib/dirsrv/slapd-%s/ldif"
|
||||
DIRSRV_LOCK_DIR = "/run/lock/dirsrv"
|
||||
ALL_SLAPD_INSTANCE_SOCKETS = "/run/slapd-*.socket"
|
||||
VAR_LOG_DIRSRV_INSTANCE_TEMPLATE = "/var/log/dirsrv/slapd-%s"
|
||||
VAR_LOG_DIRSRV = "/var/log/dirsrv/"
|
||||
SLAPD_INSTANCE_ACCESS_LOG_TEMPLATE = "/var/log/dirsrv/slapd-%s/access"
|
||||
SLAPD_INSTANCE_ERROR_LOG_TEMPLATE = "/var/log/dirsrv/slapd-%s/errors"
|
||||
SLAPD_INSTANCE_AUDIT_LOG_TEMPLATE = "/var/log/dirsrv/slapd-%s/audit"
|
||||
SLAPD_INSTANCE_SYSTEMD_IPA_ENV_TEMPLATE = \
|
||||
"/etc/systemd/system/dirsrv@%s.service.d/ipa-env.conf"
|
||||
IPA_SERVER_UPGRADE = '/usr/sbin/ipa-server-upgrade'
|
||||
KEYCTL = '/bin/keyctl'
|
||||
KEYCTL = '/usr/bin/keyctl'
|
||||
GETENT = '/usr/bin/getent'
|
||||
SSHD = '/usr/sbin/sshd'
|
||||
SSSCTL = '/usr/sbin/sssctl'
|
||||
LIBARCH = "64"
|
||||
TDBTOOL = '/usr/bin/tdbtool'
|
||||
SECRETS_TDB = '/var/lib/samba/private/secrets.tdb'
|
||||
|
||||
def check_paths(self):
|
||||
"""Check paths for missing files
|
||||
|
||||
python3 -c 'from ipaplatform.paths import paths; paths.check_paths()'
|
||||
"""
|
||||
executables = (
|
||||
"/bin", "/sbin", "/usr/bin", "/usr/sbin",
|
||||
self.LIBEXEC_IPA_DIR, self.LIBEXEC_CERTMONGER_DIR
|
||||
)
|
||||
for name in sorted(dir(self)):
|
||||
if not name[0].isupper():
|
||||
continue
|
||||
|
||||
value = getattr(self, name)
|
||||
if not value or not isinstance(value, str):
|
||||
# skip empty values
|
||||
continue
|
||||
if "%" in value or "{" in value:
|
||||
# skip templates
|
||||
continue
|
||||
|
||||
if value.startswith(executables) and value not in executables:
|
||||
if not os.path.isfile(value):
|
||||
print("Missing executable {}={}".format(name, value))
|
||||
|
||||
|
||||
paths = BasePathNamespace()
|
||||
|
||||
@@ -35,7 +35,6 @@ import six
|
||||
|
||||
from ipapython import ipautil
|
||||
from ipaplatform.paths import paths
|
||||
from ipaplatform.tasks import tasks
|
||||
|
||||
# pylint: disable=no-name-in-module, import-error
|
||||
if six.PY3:
|
||||
@@ -50,16 +49,11 @@ logger = logging.getLogger(__name__)
|
||||
# *some* naming, set them as in Red Hat distributions. Actual implementation
|
||||
# should make them available through knownservices.<name> and take care of
|
||||
# re-mapping internally, if needed
|
||||
wellknownservices = [
|
||||
'certmonger', 'dirsrv', 'httpd', 'ipa', 'krb5kdc',
|
||||
'dbus', 'nslcd', 'nscd', 'ntpd', 'portmap',
|
||||
'rpcbind', 'kadmin', 'sshd', 'autofs', 'rpcgssd',
|
||||
'rpcidmapd', 'pki_tomcatd', 'chronyd', 'domainname',
|
||||
'named', 'ods_enforcerd', 'ods_signerd', 'gssproxy',
|
||||
'nfs-utils', 'sssd', 'NetworkManager', 'ipa-custodia',
|
||||
'ipa-dnskeysyncd', 'ipa-otpd', 'ipa-ods-exporter',
|
||||
'systemd-resolved',
|
||||
]
|
||||
wellknownservices = ['certmonger', 'dirsrv', 'httpd', 'ipa', 'krb5kdc',
|
||||
'dbus', 'nslcd', 'nscd', 'ntpd', 'portmap',
|
||||
'rpcbind', 'kadmin', 'sshd', 'autofs', 'rpcgssd',
|
||||
'rpcidmapd', 'pki_tomcatd', 'chronyd', 'domainname',
|
||||
'named', 'ods_enforcerd', 'ods_signerd', 'gssproxy']
|
||||
|
||||
# The common ports for these services. This is used to wait for the
|
||||
# service to become available.
|
||||
@@ -102,7 +96,7 @@ class KnownServices(Mapping):
|
||||
raise AttributeError(name)
|
||||
|
||||
|
||||
class PlatformService:
|
||||
class PlatformService(object):
|
||||
"""
|
||||
PlatformService abstracts out external process running on the system
|
||||
which is possible to administer (start, stop, check status, etc).
|
||||
@@ -174,9 +168,6 @@ class PlatformService:
|
||||
def restart(self, instance_name="", capture_output=True, wait=True):
|
||||
pass
|
||||
|
||||
def try_restart(self, instance_name="", capture_output=True, wait=True):
|
||||
pass
|
||||
|
||||
def is_running(self, instance_name="", wait=True):
|
||||
return False
|
||||
|
||||
@@ -342,10 +333,6 @@ class SystemdService(PlatformService):
|
||||
self._restart_base(instance_name, "restart",
|
||||
capture_output, wait)
|
||||
|
||||
def try_restart(self, instance_name="", capture_output=True, wait=True):
|
||||
self._restart_base(instance_name, "try-restart",
|
||||
capture_output, wait)
|
||||
|
||||
def is_running(self, instance_name="", wait=True):
|
||||
instance = self.service_instance(instance_name, 'is-active')
|
||||
|
||||
@@ -464,7 +451,7 @@ class SystemdService(PlatformService):
|
||||
# Link exists and it is broken, make new one
|
||||
os.unlink(srv_lnk)
|
||||
os.symlink(self.lib_path, srv_lnk)
|
||||
tasks.systemd_daemon_reload()
|
||||
ipautil.run([paths.SYSTEMCTL, "--system", "daemon-reload"])
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
@@ -487,7 +474,7 @@ class SystemdService(PlatformService):
|
||||
if os.path.isdir(srv_tgt):
|
||||
if os.path.islink(srv_lnk):
|
||||
os.unlink(srv_lnk)
|
||||
tasks.systemd_daemon_reload()
|
||||
ipautil.run([paths.SYSTEMCTL, "--system", "daemon-reload"])
|
||||
except Exception:
|
||||
pass
|
||||
else:
|
||||
|
||||
@@ -24,31 +24,17 @@ This module contains default platform-specific implementations of system tasks.
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import os
|
||||
import logging
|
||||
import textwrap
|
||||
|
||||
from pkg_resources import parse_version
|
||||
|
||||
from ipaplatform.paths import paths
|
||||
from ipapython import ipautil
|
||||
from ipapython.ipachangeconf import IPAChangeConf
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
# TODO: Add other masters as FallbackDNS ?
|
||||
RESOLVE1_IPA_CONF = textwrap.dedent("""
|
||||
# auto-generated by IPA installer
|
||||
[Resolve]
|
||||
# use local BIND instance
|
||||
DNS=127.0.0.1
|
||||
# make local BIND default DNS server, add search suffixes
|
||||
Domains=~. {searchdomains}
|
||||
""")
|
||||
|
||||
|
||||
class BaseTaskNamespace:
|
||||
class BaseTaskNamespace(object):
|
||||
|
||||
def restore_context(self, filepath, force=False):
|
||||
"""Restore SELinux security context on the given filepath.
|
||||
@@ -84,23 +70,6 @@ class BaseTaskNamespace:
|
||||
Returns True if the operation succeeded, False otherwise.
|
||||
"""
|
||||
|
||||
try:
|
||||
if self.platform_insert_ca_certs(ca_certs):
|
||||
return self.reload_systemwide_ca_store()
|
||||
except Exception:
|
||||
logger.exception('Could not populate systemwide CA store')
|
||||
|
||||
return False
|
||||
|
||||
def platform_insert_ca_certs(self, ca_certs):
|
||||
"""
|
||||
Platform implementations override this method to implement
|
||||
population of the systemwide CA store.
|
||||
|
||||
Returns True if changes were made to the CA store, False otherwise.
|
||||
|
||||
Raises Exception if something went wrong.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def remove_ca_certs_from_systemwide_ca_store(self):
|
||||
@@ -111,25 +80,6 @@ class BaseTaskNamespace:
|
||||
Returns True if the operation succeeded, False otherwise.
|
||||
"""
|
||||
|
||||
try:
|
||||
if self.platform_remove_ca_certs():
|
||||
return self.reload_systemwide_ca_store()
|
||||
except Exception:
|
||||
logger.exception(
|
||||
'Could not remove certificates from systemwide CA store'
|
||||
)
|
||||
|
||||
return False
|
||||
|
||||
def platform_remove_ca_certs(self):
|
||||
"""
|
||||
Platform implementations override this method to implement
|
||||
removal of certificates from the systemwide CA store.
|
||||
|
||||
Returns True if changes were made to the CA store, False otherwise.
|
||||
|
||||
Raises Exception if something went wrong.
|
||||
"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def get_svc_list_file(self):
|
||||
@@ -139,24 +89,16 @@ class BaseTaskNamespace:
|
||||
|
||||
return paths.SVC_LIST_FILE
|
||||
|
||||
def is_selinux_enabled(self):
|
||||
"""Check if SELinux is available and enabled
|
||||
|
||||
:return: True if SELinux is available and enabled
|
||||
"""
|
||||
return False
|
||||
|
||||
def check_selinux_status(self):
|
||||
"""Checks if SELinux is available on the platform.
|
||||
|
||||
If it is, this task also makes sure that restorecon tool is available.
|
||||
"""
|
||||
Checks if SELinux is available on the platform. If it is, this task
|
||||
also makes sure that restorecon tool is available.
|
||||
|
||||
If SELinux is available, but restorcon tool is not installed, raises
|
||||
an RuntimeError, which suggest installing the package containing
|
||||
restorecon and rerunning the installation.
|
||||
|
||||
:return: True if SELinux is available and enabled
|
||||
"""
|
||||
|
||||
raise NotImplementedError()
|
||||
|
||||
def check_ipv6_stack_enabled(self):
|
||||
@@ -164,14 +106,6 @@ class BaseTaskNamespace:
|
||||
|
||||
raise NotImplementedError()
|
||||
|
||||
def detect_container(self):
|
||||
"""Check if running inside a container
|
||||
|
||||
:returns: container runtime or None
|
||||
:rtype: str, None
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def restore_hostname(self, fstore, statestore):
|
||||
"""
|
||||
Restores the original hostname as backed up in the
|
||||
@@ -221,12 +155,7 @@ class BaseTaskNamespace:
|
||||
"""
|
||||
Check if the flag --no-sssd is supported for client install.
|
||||
"""
|
||||
return True
|
||||
|
||||
def is_mkhomedir_supported(self):
|
||||
"""
|
||||
Check if the flag --mkhomedir is supported for client install.
|
||||
"""
|
||||
return True
|
||||
|
||||
def backup_auth_configuration(self, path):
|
||||
@@ -299,10 +228,6 @@ class BaseTaskNamespace:
|
||||
"""Configure WSGI for correct Python version"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def configure_httpd_protocol(self):
|
||||
"""Configure TLS protocols in Apache"""
|
||||
raise NotImplementedError()
|
||||
|
||||
def is_fips_enabled(self):
|
||||
return False
|
||||
|
||||
@@ -318,225 +243,5 @@ class BaseTaskNamespace:
|
||||
def setup_httpd_logging(self):
|
||||
raise NotImplementedError()
|
||||
|
||||
def systemd_daemon_reload(self):
|
||||
"""Tell systemd to reload config files"""
|
||||
raise NotImplementedError
|
||||
|
||||
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 resolve1_enabled: is systemd-resolved enabled?
|
||||
:param fstore: optional file store for backup
|
||||
"""
|
||||
if resolve1_enabled:
|
||||
# break circular import
|
||||
from ipaplatform.services import knownservices
|
||||
|
||||
confd = os.path.dirname(paths.SYSTEMD_RESOLVED_IPA_CONF)
|
||||
os.makedirs(confd, exist_ok=True)
|
||||
|
||||
cfg = RESOLVE1_IPA_CONF.format(
|
||||
searchdomains=" ".join(searchdomains)
|
||||
)
|
||||
with open(paths.SYSTEMD_RESOLVED_IPA_CONF, "w") as f:
|
||||
os.fchmod(f.fileno(), 0o644)
|
||||
f.write(cfg)
|
||||
|
||||
knownservices["systemd-resolved"].reload_or_restart()
|
||||
|
||||
def unconfigure_dns_resolver(self, fstore=None):
|
||||
"""Unconfigure global DNS resolver (e.g. /etc/resolv.conf)
|
||||
|
||||
:param fstore: optional file store for restore
|
||||
"""
|
||||
if fstore is not None and fstore.has_file(paths.RESOLV_CONF):
|
||||
fstore.restore_file(paths.RESOLV_CONF)
|
||||
|
||||
if os.path.isfile(paths.SYSTEMD_RESOLVED_IPA_CONF):
|
||||
# break circular import
|
||||
from ipaplatform.services import knownservices
|
||||
|
||||
os.unlink(paths.SYSTEMD_RESOLVED_IPA_CONF)
|
||||
knownservices["systemd-resolved"].reload_or_restart()
|
||||
|
||||
def configure_pkcs11_modules(self, fstore):
|
||||
"""Disable p11-kit modules
|
||||
|
||||
The p11-kit configuration injects p11-kit-proxy into all NSS
|
||||
databases. Amongst other p11-kit loads SoftHSM2 PKCS#11 provider.
|
||||
This interferes with 389-DS, certmonger, Dogtag and other services.
|
||||
For example certmonger tries to open OpenDNSSEC's SoftHSM2 token,
|
||||
although it doesn't use it at all. It also breaks Dogtag HSM support
|
||||
testing with SoftHSM2.
|
||||
|
||||
IPA server does neither need nor use SoftHSM2 proxied by p11-kit.
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def restore_pkcs11_modules(self, fstore):
|
||||
"""Restore global p11-kit modules for NSS
|
||||
"""
|
||||
raise NotImplementedError
|
||||
|
||||
def get_pkcs11_modules(self):
|
||||
"""Return the list of module config files setup by IPA.
|
||||
"""
|
||||
return ()
|
||||
|
||||
def configure_nsswitch_database(self, fstore, database, services,
|
||||
preserve=True, append=True,
|
||||
default_value=()):
|
||||
"""
|
||||
Edits the specified nsswitch.conf database (e.g. passwd, group,
|
||||
sudoers) to use the specified service(s).
|
||||
|
||||
Arguments:
|
||||
fstore - FileStore to backup the nsswitch.conf
|
||||
database - database configuration that should be ammended,
|
||||
e.g. 'sudoers'
|
||||
service - list of services that should be added, e.g. ['sss']
|
||||
preserve - if True, the already configured services will be
|
||||
preserved
|
||||
|
||||
The next arguments modify the behaviour if preserve=True:
|
||||
append - if True, the services will be appended, if False,
|
||||
prepended
|
||||
default_value - list of services that are considered as default (if
|
||||
the database is not mentioned in nsswitch.conf),
|
||||
e.g. ['files']
|
||||
"""
|
||||
|
||||
# Backup the original version of nsswitch.conf, we're going to edit it
|
||||
# now
|
||||
if not fstore.has_file(paths.NSSWITCH_CONF):
|
||||
fstore.backup_file(paths.NSSWITCH_CONF)
|
||||
|
||||
conf = IPAChangeConf("IPA Installer")
|
||||
conf.setOptionAssignment(':')
|
||||
|
||||
if preserve:
|
||||
# Read the existing configuration
|
||||
with open(paths.NSSWITCH_CONF, 'r') as f:
|
||||
opts = conf.parse(f)
|
||||
raw_database_entry = conf.findOpts(opts, 'option', database)[1]
|
||||
|
||||
# Detect the list of already configured services
|
||||
if not raw_database_entry:
|
||||
# If there is no database entry, database is not present in
|
||||
# the nsswitch.conf. Set the list of services to the
|
||||
# default list, if passed.
|
||||
configured_services = list(default_value)
|
||||
else:
|
||||
configured_services = raw_database_entry[
|
||||
'value'].strip().split()
|
||||
|
||||
# Make sure no service is added if already mentioned in the list
|
||||
added_services = [s for s in services
|
||||
if s not in configured_services]
|
||||
|
||||
# Prepend / append the list of new services
|
||||
if append:
|
||||
new_value = ' ' + ' '.join(configured_services +
|
||||
added_services)
|
||||
else:
|
||||
new_value = ' ' + ' '.join(added_services +
|
||||
configured_services)
|
||||
|
||||
else:
|
||||
# Preserve not set, let's rewrite existing configuration
|
||||
new_value = ' ' + ' '.join(services)
|
||||
|
||||
# Set new services as sources for database
|
||||
opts = [
|
||||
conf.setOption(database, new_value),
|
||||
conf.emptyLine(),
|
||||
]
|
||||
|
||||
conf.changeConf(paths.NSSWITCH_CONF, opts)
|
||||
logger.info("Configured %s in %s", database, paths.NSSWITCH_CONF)
|
||||
|
||||
def enable_sssd_sudo(self, fstore):
|
||||
"""Configure nsswitch.conf to use sssd for sudo"""
|
||||
self.configure_nsswitch_database(
|
||||
fstore, 'sudoers', ['sss'],
|
||||
default_value=['files'])
|
||||
|
||||
def enable_ldap_automount(self, statestore):
|
||||
"""
|
||||
Point automount to ldap in nsswitch.conf.
|
||||
This function is for non-SSSD setups only.
|
||||
"""
|
||||
conf = IPAChangeConf("IPA Installer")
|
||||
conf.setOptionAssignment(':')
|
||||
|
||||
with open(paths.NSSWITCH_CONF, 'r') as f:
|
||||
current_opts = conf.parse(f)
|
||||
current_nss_value = conf.findOpts(
|
||||
current_opts, name='automount', type='option'
|
||||
)[1]
|
||||
if current_nss_value is None:
|
||||
# no automount database present
|
||||
current_nss_value = False # None cannot be backed up
|
||||
else:
|
||||
current_nss_value = current_nss_value['value']
|
||||
statestore.backup_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount',
|
||||
current_nss_value
|
||||
)
|
||||
|
||||
nss_value = ' files ldap'
|
||||
opts = [
|
||||
{
|
||||
'name': 'automount',
|
||||
'type': 'option',
|
||||
'action': 'set',
|
||||
'value': nss_value,
|
||||
},
|
||||
{'name': 'empty', 'type': 'empty'},
|
||||
]
|
||||
conf.changeConf(paths.NSSWITCH_CONF, opts)
|
||||
|
||||
logger.info("Configured %s", paths.NSSWITCH_CONF)
|
||||
|
||||
def disable_ldap_automount(self, statestore):
|
||||
"""Disable automount using LDAP"""
|
||||
if statestore.get_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount'
|
||||
) is False:
|
||||
# Previous nsswitch.conf had no automount database configured
|
||||
# so remove it.
|
||||
conf = IPAChangeConf("IPA automount installer")
|
||||
conf.setOptionAssignment(':')
|
||||
changes = [conf.rmOption('automount')]
|
||||
conf.changeConf(paths.NSSWITCH_CONF, changes)
|
||||
self.restore_context(paths.NSSWITCH_CONF)
|
||||
statestore.delete_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount'
|
||||
)
|
||||
elif statestore.get_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount'
|
||||
) is not None:
|
||||
nss_value = statestore.get_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount'
|
||||
)
|
||||
opts = [
|
||||
{
|
||||
'name': 'automount',
|
||||
'type': 'option',
|
||||
'action': 'set',
|
||||
'value': nss_value,
|
||||
},
|
||||
{'name': 'empty', 'type': 'empty'},
|
||||
]
|
||||
conf = IPAChangeConf("IPA automount installer")
|
||||
conf.setOptionAssignment(':')
|
||||
conf.changeConf(paths.NSSWITCH_CONF, opts)
|
||||
self.restore_context(paths.NSSWITCH_CONF)
|
||||
statestore.delete_state(
|
||||
'ipa-client-automount-nsswitch', 'previous-automount'
|
||||
)
|
||||
|
||||
tasks = BaseTaskNamespace()
|
||||
|
||||
@@ -33,24 +33,16 @@ class DebianPathNamespace(BasePathNamespace):
|
||||
OLD_IPA_KEYTAB = "/etc/apache2/ipa.keytab"
|
||||
HTTPD_PASSWORD_CONF = "/etc/apache2/password.conf"
|
||||
NAMED_CONF = "/etc/bind/named.conf"
|
||||
NAMED_CONF_BAK = "/etc/bind/named.conf.ipa-backup"
|
||||
NAMED_CUSTOM_CONF = "/etc/bind/ipa-ext.conf"
|
||||
NAMED_CUSTOM_OPTIONS_CONF = "/etc/bind/ipa-options-ext.conf"
|
||||
NAMED_VAR_DIR = "/var/cache/bind"
|
||||
NAMED_KEYTAB = "/etc/bind/named.keytab"
|
||||
NAMED_RFC1912_ZONES = "/etc/bind/named.conf.default-zones"
|
||||
NAMED_ROOT_KEY = "/etc/bind/bind.keys"
|
||||
NAMED_BINDKEYS_FILE = "/etc/bind/bind.keys"
|
||||
NAMED_MANAGED_KEYS_DIR = "/var/cache/bind/dynamic"
|
||||
CHRONY_CONF = "/etc/chrony/chrony.conf"
|
||||
OPENLDAP_LDAP_CONF = "/etc/ldap/ldap.conf"
|
||||
ETC_DEBIAN_VERSION = "/etc/debian_version"
|
||||
# Old versions of freeipa wrote all trusted certificates to a single
|
||||
# file, which is not supported by ca-certificates.
|
||||
CA_CERTIFICATES_BUNDLE_PEM = "/usr/local/share/ca-certificates/ipa-ca.crt"
|
||||
CA_CERTIFICATES_DIR = "/usr/local/share/ca-certificates/ipa-ca"
|
||||
# Debian's p11-kit does not use ipa.p11-kit, so the file is provided
|
||||
# for information only.
|
||||
IPA_P11_KIT = "/usr/local/share/ca-certificates/ipa.p11-kit"
|
||||
IPA_P11_KIT = "/usr/local/share/ca-certificates/ipa-ca.crt"
|
||||
ETC_SYSCONFIG_DIR = "/etc/default"
|
||||
SYSCONFIG_AUTOFS = "/etc/default/autofs"
|
||||
SYSCONFIG_DIRSRV = "/etc/default/dirsrv"
|
||||
@@ -66,15 +58,14 @@ class DebianPathNamespace(BasePathNamespace):
|
||||
SYSCONFIG_PKI = "/etc/dogtag/"
|
||||
SYSCONFIG_PKI_TOMCAT = "/etc/default/pki-tomcat"
|
||||
SYSCONFIG_PKI_TOMCAT_PKI_TOMCAT_DIR = "/etc/dogtag/tomcat/pki-tomcat"
|
||||
BIN_TOMCAT = "/usr/share/tomcat9/bin/version.sh"
|
||||
SYSTEMD_SYSTEM_HTTPD_D_DIR = "/etc/systemd/system/apache2.service.d/"
|
||||
SYSTEMD_SYSTEM_HTTPD_IPA_CONF = "/etc/systemd/system/apache2.service.d/ipa.conf"
|
||||
DNSSEC_TRUSTED_KEY = "/etc/bind/trusted-key.key"
|
||||
GSSAPI_SESSION_KEY = "/etc/apache2/ipasession.key"
|
||||
OLD_KRA_AGENT_PEM = "/etc/apache2/nssdb/kra-agent.pem"
|
||||
KEYCTL = "/bin/keyctl"
|
||||
SBIN_SERVICE = "/usr/sbin/service"
|
||||
CERTMONGER_COMMAND_TEMPLATE = "/usr/lib/ipa/certmonger/%s"
|
||||
ODS_KSMUTIL = None
|
||||
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/"
|
||||
@@ -82,32 +73,28 @@ class DebianPathNamespace(BasePathNamespace):
|
||||
LIBSOFTHSM2_SO = "/usr/lib/softhsm/libsofthsm2.so"
|
||||
PAM_KRB5_SO = "/usr/lib/{0}/security/pam_krb5.so".format(MULTIARCH)
|
||||
LIB_SYSTEMD_SYSTEMD_DIR = "/lib/systemd/system/"
|
||||
LIBEXEC_CERTMONGER_DIR = "/usr/lib/certmonger"
|
||||
DOGTAG_IPA_CA_RENEW_AGENT_SUBMIT = "/usr/lib/certmonger/dogtag-ipa-ca-renew-agent-submit"
|
||||
DOGTAG_IPA_RENEW_AGENT_SUBMIT = "/usr/lib/certmonger/dogtag-ipa-renew-agent-submit"
|
||||
CERTMONGER_DOGTAG_SUBMIT = "/usr/lib/certmonger/dogtag-submit"
|
||||
IPA_SERVER_GUARD = "/usr/lib/certmonger/ipa-server-guard"
|
||||
GENERATE_RNDC_KEY = "/bin/true"
|
||||
LIBEXEC_IPA_DIR = "/usr/lib/ipa"
|
||||
IPA_DNSKEYSYNCD_REPLICA = "/usr/lib/ipa/ipa-dnskeysync-replica"
|
||||
IPA_DNSKEYSYNCD = "/usr/lib/ipa/ipa-dnskeysyncd"
|
||||
IPA_HTTPD_KDCPROXY = "/usr/lib/ipa/ipa-httpd-kdcproxy"
|
||||
IPA_ODS_EXPORTER = "/usr/lib/ipa/ipa-ods-exporter"
|
||||
IPA_PKI_RETRIEVE_KEY = "/usr/lib/ipa/ipa-pki-retrieve-key"
|
||||
IPA_HTTPD_PASSWD_READER = "/usr/lib/ipa/ipa-httpd-pwdreader"
|
||||
IPA_PKI_WAIT_RUNNING = "/usr/lib/ipa/ipa-pki-wait-running"
|
||||
HTTPD = "/usr/sbin/apache2ctl"
|
||||
REMOVE_DS_PL = "/usr/sbin/remove-ds"
|
||||
SETUP_DS_PL = "/usr/sbin/setup-ds"
|
||||
FONTS_DIR = "/usr/share/fonts/truetype"
|
||||
FONTS_OPENSANS_DIR = "/usr/share/fonts/truetype/open-sans"
|
||||
FONTS_FONTAWESOME_DIR = "/usr/share/fonts/truetype/font-awesome"
|
||||
VAR_KERBEROS_KRB5KDC_DIR = "/var/lib/krb5kdc/"
|
||||
VAR_KRB5KDC_K5_REALM = "/var/lib/krb5kdc/.k5."
|
||||
CACERT_PEM = "/var/lib/ipa/certs/cacert.pem"
|
||||
CACERT_PEM = "/var/lib/krb5kdc/cacert.pem"
|
||||
KRB5KDC_KADM5_ACL = "/etc/krb5kdc/kadm5.acl"
|
||||
KRB5KDC_KADM5_KEYTAB = "/etc/krb5kdc/kadm5.keytab"
|
||||
KRB5KDC_KDC_CONF = "/etc/krb5kdc/kdc.conf"
|
||||
KDC_CERT = "/var/lib/ipa/certs/kdc.crt"
|
||||
KDC_KEY = "/var/lib/ipa/certs/kdc.key"
|
||||
KDC_CERT = "/var/lib/krb5kdc/kdc.crt"
|
||||
KDC_KEY = "/var/lib/krb5kdc/kdc.key"
|
||||
VAR_LOG_HTTPD_DIR = "/var/log/apache2"
|
||||
VAR_LOG_HTTPD_ERROR = "/var/log/apache2/error.log"
|
||||
NAMED_RUN = "/var/cache/bind/named.run"
|
||||
@@ -116,7 +103,6 @@ class DebianPathNamespace(BasePathNamespace):
|
||||
IPA_ODS_EXPORTER_CCACHE = "/var/lib/opendnssec/tmp/ipa-ods-exporter.ccache"
|
||||
IPA_CUSTODIA_SOCKET = "/run/apache2/ipa-custodia.sock"
|
||||
IPA_CUSTODIA_AUDIT_LOG = '/var/log/ipa-custodia.audit.log'
|
||||
IPA_CUSTODIA_HANDLER = "/usr/lib/ipa/custodia"
|
||||
WSGI_PREFIX_DIR = "/run/apache2/wsgi"
|
||||
|
||||
paths = DebianPathNamespace()
|
||||
|
||||
@@ -153,8 +153,6 @@ def debian_service_class_factory(name, api=None):
|
||||
return DebianNoService(name, api)
|
||||
if name == 'ipa':
|
||||
return redhat_services.RedHatIPAService(name, api)
|
||||
if name in ('pki-tomcatd', 'pki_tomcatd'):
|
||||
return redhat_services.RedHatCAService(name, api)
|
||||
if name == 'ntpd':
|
||||
return DebianSysvService("ntp", api)
|
||||
return DebianService(name, api)
|
||||
|
||||
@@ -8,21 +8,10 @@ This module contains default Debian-specific implementations of system tasks.
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
import logging
|
||||
import os
|
||||
import shutil
|
||||
from pathlib import Path
|
||||
|
||||
from ipaplatform.base.tasks import BaseTaskNamespace
|
||||
from ipaplatform.redhat.tasks import RedHatTaskNamespace
|
||||
from ipaplatform.paths import paths
|
||||
|
||||
from ipapython import directivesetter
|
||||
from ipapython import ipautil
|
||||
from ipapython.dn import DN
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class DebianTaskNamespace(RedHatTaskNamespace):
|
||||
@staticmethod
|
||||
@@ -68,146 +57,17 @@ class DebianTaskNamespace(RedHatTaskNamespace):
|
||||
# Debian doesn't use authconfig, nothing to restore
|
||||
return True
|
||||
|
||||
def migrate_auth_configuration(self, statestore):
|
||||
# Debian doesn't have authselect
|
||||
return True
|
||||
@staticmethod
|
||||
def parse_ipa_version(version):
|
||||
return BaseTaskNamespace.parse_ipa_version(version)
|
||||
|
||||
def configure_httpd_wsgi_conf(self):
|
||||
# Debian doesn't require special mod_wsgi configuration
|
||||
pass
|
||||
|
||||
def configure_httpd_protocol(self):
|
||||
# TLS 1.3 is not yet supported
|
||||
directivesetter.set_directive(paths.HTTPD_SSL_CONF,
|
||||
'SSLProtocol',
|
||||
'TLSv1.2', False)
|
||||
|
||||
def setup_httpd_logging(self):
|
||||
# Debian handles httpd logging differently
|
||||
pass
|
||||
|
||||
def configure_pkcs11_modules(self, fstore):
|
||||
# Debian doesn't use p11-kit
|
||||
pass
|
||||
|
||||
def restore_pkcs11_modules(self, fstore):
|
||||
pass
|
||||
|
||||
def platform_insert_ca_certs(self, ca_certs):
|
||||
# ca-certificates does not use this file, so it doesn't matter if we
|
||||
# fail to create it.
|
||||
try:
|
||||
self.write_p11kit_certs(paths.IPA_P11_KIT, ca_certs),
|
||||
except Exception:
|
||||
logger.exception("""\
|
||||
Could not create p11-kit anchor trust file. On Debian this file is not
|
||||
used by ca-certificates and is provided for information only.\
|
||||
""")
|
||||
|
||||
return any([
|
||||
self.write_ca_certificates_dir(
|
||||
paths.CA_CERTIFICATES_DIR, ca_certs
|
||||
),
|
||||
self.remove_ca_certificates_bundle(
|
||||
paths.CA_CERTIFICATES_BUNDLE_PEM
|
||||
),
|
||||
])
|
||||
|
||||
def write_ca_certificates_dir(self, directory, ca_certs):
|
||||
# pylint: disable=ipa-forbidden-import
|
||||
from ipalib import x509 # FixMe: break import cycle
|
||||
# pylint: enable=ipa-forbidden-import
|
||||
|
||||
path = Path(directory)
|
||||
try:
|
||||
path.mkdir(mode=0o755, exist_ok=True)
|
||||
except Exception:
|
||||
logger.error("Could not create %s", path)
|
||||
raise
|
||||
|
||||
for cert, nickname, trusted, _ext_key_usage in ca_certs:
|
||||
if not trusted:
|
||||
continue
|
||||
|
||||
# I'm not handling errors here because they have already
|
||||
# been checked by the time we get here
|
||||
subject = DN(cert.subject)
|
||||
issuer = DN(cert.issuer)
|
||||
|
||||
# Construct the certificate filename using the Subject DN so that
|
||||
# the user can see which CA a particular file is for, and include
|
||||
# the serial number to disambiguate clashes where a subordinate CA
|
||||
# had a new certificate issued.
|
||||
#
|
||||
# Strictly speaking, certificates are uniquely idenified by (Issuer
|
||||
# DN, Serial Number). Do we care about the possibility of a clash
|
||||
# where a subordinate CA had two certificates issued by different
|
||||
# CAs who used the same serial number?)
|
||||
filename = f'{subject.ldap_text()} {cert.serial_number}.crt'
|
||||
|
||||
# pylint: disable=old-division
|
||||
cert_path = path / filename
|
||||
# pylint: enable=old-division
|
||||
try:
|
||||
f = open(cert_path, 'w')
|
||||
except Exception:
|
||||
logger.error("Could not create %s", cert_path)
|
||||
raise
|
||||
|
||||
with f:
|
||||
try:
|
||||
os.fchmod(f.fileno(), 0o644)
|
||||
except Exception:
|
||||
logger.error("Could not set mode of %s", cert_path)
|
||||
raise
|
||||
|
||||
try:
|
||||
f.write(f"""\
|
||||
This file was created by IPA. Do not edit.
|
||||
|
||||
Description: {nickname}
|
||||
Subject: {subject.ldap_text()}
|
||||
Issuer: {issuer.ldap_text()}
|
||||
Serial Number (dec): {cert.serial_number}
|
||||
Serial Number (hex): {cert.serial_number:#x}
|
||||
|
||||
""")
|
||||
pem = cert.public_bytes(x509.Encoding.PEM).decode('ascii')
|
||||
f.write(pem)
|
||||
except Exception:
|
||||
logger.error("Could not write to %s", cert_path)
|
||||
raise
|
||||
|
||||
return True
|
||||
|
||||
def platform_remove_ca_certs(self):
|
||||
return any([
|
||||
self.remove_ca_certificates_dir(paths.CA_CERTIFICATES_DIR),
|
||||
self.remove_ca_certificates_bundle(paths.IPA_P11_KIT),
|
||||
self.remove_ca_certificates_bundle(
|
||||
paths.CA_CERTIFICATES_BUNDLE_PEM
|
||||
),
|
||||
])
|
||||
|
||||
def remove_ca_certificates_dir(self, directory):
|
||||
path = Path(paths.CA_CERTIFICATES_DIR)
|
||||
if not path.exists():
|
||||
return False
|
||||
|
||||
try:
|
||||
shutil.rmtree(path)
|
||||
except Exception:
|
||||
logger.error("Could not remove %s", path)
|
||||
raise
|
||||
|
||||
return True
|
||||
|
||||
# Debian doesn't use authselect, so call enable/disable_ldap_automount
|
||||
# from BaseTaskNamespace.
|
||||
def enable_ldap_automount(self, statestore):
|
||||
return BaseTaskNamespace.enable_ldap_automount(self, statestore)
|
||||
|
||||
def disable_ldap_automount(self, statestore):
|
||||
return BaseTaskNamespace.disable_ldap_automount(self, statestore)
|
||||
|
||||
tasks = DebianTaskNamespace()
|
||||
|
||||
@@ -10,12 +10,6 @@ This Fedora base platform module exports platform related constants.
|
||||
from __future__ import absolute_import
|
||||
|
||||
from ipaplatform.redhat.constants import RedHatConstantsNamespace
|
||||
from ipaplatform.osinfo import osinfo
|
||||
|
||||
# Fedora 28 and earlier use /etc/sysconfig/nfs
|
||||
# Fedora 30 and later use /etc/nfs.conf
|
||||
# Fedora 29 has both
|
||||
HAS_NFS_CONF = osinfo.version_number >= (30,)
|
||||
|
||||
|
||||
class FedoraConstantsNamespace(RedHatConstantsNamespace):
|
||||
@@ -24,7 +18,10 @@ class FedoraConstantsNamespace(RedHatConstantsNamespace):
|
||||
MOD_WSGI_PYTHON2 = "modules/mod_wsgi.so"
|
||||
MOD_WSGI_PYTHON3 = "modules/mod_wsgi_python3.so"
|
||||
|
||||
if HAS_NFS_CONF:
|
||||
SECURE_NFS_VAR = None
|
||||
# System-wide crypto policy, but without TripleDES, pre-shared key,
|
||||
# secure remote password, and DSA cert authentication.
|
||||
# see https://fedoraproject.org/wiki/Changes/CryptoPolicy
|
||||
TLS_HIGH_CIPHERS = "PROFILE=SYSTEM:!3DES:!PSK:!SRP:!aDSS"
|
||||
|
||||
|
||||
constants = FedoraConstantsNamespace()
|
||||
|
||||
@@ -26,7 +26,6 @@ in Fedora-based systems.
|
||||
from __future__ import absolute_import
|
||||
|
||||
from ipaplatform.redhat.paths import RedHatPathNamespace
|
||||
from ipaplatform.fedora.constants import HAS_NFS_CONF
|
||||
|
||||
|
||||
class FedoraPathNamespace(RedHatPathNamespace):
|
||||
@@ -34,8 +33,6 @@ class FedoraPathNamespace(RedHatPathNamespace):
|
||||
"/etc/httpd/conf.modules.d/02-ipa-wsgi.conf"
|
||||
)
|
||||
NAMED_CRYPTO_POLICY_FILE = "/etc/crypto-policies/back-ends/bind.config"
|
||||
if HAS_NFS_CONF:
|
||||
SYSCONFIG_NFS = '/etc/nfs.conf'
|
||||
|
||||
|
||||
paths = FedoraPathNamespace()
|
||||
|
||||
@@ -24,12 +24,21 @@ Contains Fedora-specific service class implementations.
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
from ipaplatform.osinfo import osinfo
|
||||
from ipaplatform.redhat import services as redhat_services
|
||||
|
||||
# Mappings from service names as FreeIPA code references to these services
|
||||
# to their actual systemd service names
|
||||
fedora_system_units = redhat_services.redhat_system_units.copy()
|
||||
|
||||
# Fedora 28 and earlier have fedora-domainname.service. Starting from
|
||||
# Fedora 29, the service is called nis-domainname.service as defined in
|
||||
# ipaplatform.redhat.services.
|
||||
HAS_FEDORA_DOMAINNAME_SERVICE = int(osinfo.version_id) <= 28
|
||||
|
||||
if HAS_FEDORA_DOMAINNAME_SERVICE:
|
||||
fedora_system_units['domainname'] = 'fedora-domainname.service'
|
||||
|
||||
|
||||
# Service classes that implement Fedora-specific behaviour
|
||||
|
||||
@@ -41,6 +50,8 @@ class FedoraService(redhat_services.RedHatService):
|
||||
# of specified name
|
||||
|
||||
def fedora_service_class_factory(name, api=None):
|
||||
if HAS_FEDORA_DOMAINNAME_SERVICE and name == 'domainname':
|
||||
return FedoraService(name, api)
|
||||
return redhat_services.redhat_service_class_factory(name, api)
|
||||
|
||||
|
||||
|
||||
@@ -25,22 +25,11 @@ This module contains default Fedora-specific implementations of system tasks.
|
||||
|
||||
from __future__ import absolute_import
|
||||
|
||||
from ipapython import directivesetter
|
||||
from ipaplatform.redhat.tasks import RedHatTaskNamespace
|
||||
from ipaplatform.paths import paths
|
||||
|
||||
|
||||
class FedoraTaskNamespace(RedHatTaskNamespace):
|
||||
|
||||
def configure_httpd_protocol(self):
|
||||
# On Fedora 31 and earlier DEFAULT crypto-policy has TLS 1.0 and 1.1
|
||||
# enabled.
|
||||
directivesetter.set_directive(
|
||||
paths.HTTPD_SSL_CONF,
|
||||
'SSLProtocol',
|
||||
"all -SSLv3 -TLSv1 -TLSv1.1",
|
||||
False
|
||||
)
|
||||
pass
|
||||
|
||||
|
||||
tasks = FedoraTaskNamespace()
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
"""
|
||||
This module contains Fedora Container specific platform files.
|
||||
"""
|
||||
NAME = "fedora_container"
|
||||
@@ -1,13 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
"""Fedora container constants
|
||||
"""
|
||||
from ipaplatform.fedora.constants import FedoraConstantsNamespace
|
||||
|
||||
|
||||
class FedoraContainerConstantsNamespace(FedoraConstantsNamespace):
|
||||
pass
|
||||
|
||||
|
||||
constants = FedoraContainerConstantsNamespace()
|
||||
@@ -1,30 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
"""Fedora container paths
|
||||
"""
|
||||
import os
|
||||
|
||||
from ipaplatform.fedora.paths import FedoraPathNamespace
|
||||
|
||||
|
||||
def data(path):
|
||||
return os.path.join("/data", path[1:])
|
||||
|
||||
|
||||
class FedoraContainerPathNamespace(FedoraPathNamespace):
|
||||
KRB5_CONF = data(FedoraPathNamespace.KRB5_CONF)
|
||||
KRB5_KEYTAB = data(FedoraPathNamespace.KRB5_KEYTAB)
|
||||
NAMED_KEYTAB = data(FedoraPathNamespace.NAMED_KEYTAB)
|
||||
NAMED_CUSTOM_CONF = data(FedoraPathNamespace.NAMED_CUSTOM_CONF)
|
||||
NAMED_CUSTOM_OPTIONS_CONF = data(
|
||||
FedoraPathNamespace.NAMED_CUSTOM_OPTIONS_CONF
|
||||
)
|
||||
NSSWITCH_CONF = data(FedoraPathNamespace.NSSWITCH_CONF)
|
||||
PKI_CONFIGURATION = data(FedoraPathNamespace.PKI_CONFIGURATION)
|
||||
SAMBA_DIR = data(FedoraPathNamespace.SAMBA_DIR)
|
||||
HTTPD_IPA_WSGI_MODULES_CONF = None
|
||||
HTTPD_PASSWD_FILE_FMT = data(FedoraPathNamespace.HTTPD_PASSWD_FILE_FMT)
|
||||
|
||||
|
||||
paths = FedoraContainerPathNamespace()
|
||||
@@ -1,27 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
"""Fedora container services
|
||||
"""
|
||||
from ipaplatform.fedora import services as fedora_services
|
||||
|
||||
|
||||
fedora_container_system_units = fedora_services.fedora_system_units.copy()
|
||||
|
||||
|
||||
class FedoraContainerService(fedora_services.FedoraService):
|
||||
system_units = fedora_container_system_units
|
||||
|
||||
|
||||
def fedora_container_service_class_factory(name, api=None):
|
||||
return fedora_services.fedora_service_class_factory(name, api)
|
||||
|
||||
|
||||
class FedoraContainerServices(fedora_services.FedoraServices):
|
||||
def service_class_factory(self, name, api=None):
|
||||
return fedora_container_service_class_factory(name, api)
|
||||
|
||||
|
||||
timedate_services = fedora_services.timedate_services
|
||||
service = fedora_container_service_class_factory
|
||||
knownservices = FedoraContainerServices()
|
||||
@@ -1,34 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
"""Fedora container tasks
|
||||
"""
|
||||
import logging
|
||||
|
||||
from ipaplatform.fedora.tasks import FedoraTaskNamespace
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class FedoraContainerTaskNamespace(FedoraTaskNamespace):
|
||||
def modify_nsswitch_pam_stack(
|
||||
self, sssd, mkhomedir, statestore, sudo=True
|
||||
):
|
||||
# freeipa-container images are preconfigured
|
||||
# authselect select sssd with-sudo --force
|
||||
logger.debug("Authselect is pre-configured in container images.")
|
||||
|
||||
def is_mkhomedir_supported(self):
|
||||
# authselect is not pre-configured with mkhomedir
|
||||
return False
|
||||
|
||||
def restore_auth_configuration(self, path):
|
||||
# backup is supported but restore is a no-op
|
||||
logger.debug("Authselect is pre-configured in container images.")
|
||||
|
||||
def migrate_auth_configuration(self, statestore):
|
||||
logger.debug("Authselect is pre-configured in container images.")
|
||||
|
||||
|
||||
tasks = FedoraContainerTaskNamespace()
|
||||
@@ -1,6 +1,6 @@
|
||||
Metadata-Version: 1.2
|
||||
Name: ipaplatform
|
||||
Version: 4.8.10
|
||||
Version: 4.7.2
|
||||
Summary: FreeIPA platform
|
||||
Home-page: https://www.freeipa.org/
|
||||
Author: FreeIPA Developers
|
||||
@@ -16,9 +16,10 @@ Classifier: Development Status :: 5 - Production/Stable
|
||||
Classifier: Intended Audience :: System Administrators
|
||||
Classifier: License :: OSI Approved :: GNU General Public License v3 (GPLv3)
|
||||
Classifier: Programming Language :: C
|
||||
Classifier: Programming Language :: Python :: 2
|
||||
Classifier: Programming Language :: Python :: 2.7
|
||||
Classifier: Programming Language :: Python :: 3
|
||||
Classifier: Programming Language :: Python :: 3.6
|
||||
Classifier: Programming Language :: Python :: 3.7
|
||||
Classifier: Programming Language :: Python :: Implementation :: CPython
|
||||
Classifier: Operating System :: POSIX
|
||||
Classifier: Operating System :: POSIX :: Linux
|
||||
@@ -26,4 +27,4 @@ Classifier: Operating System :: Unix
|
||||
Classifier: Topic :: Internet :: Name Service (DNS)
|
||||
Classifier: Topic :: Security
|
||||
Classifier: Topic :: System :: Systems Administration :: Authentication/Directory :: LDAP
|
||||
Requires-Python: >=3.6.0
|
||||
Requires-Python: >=2.7.5,!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
README.md
|
||||
__init__.py
|
||||
_importhook.py
|
||||
constants.py
|
||||
@@ -9,7 +8,6 @@ services.py
|
||||
setup.cfg
|
||||
setup.py
|
||||
tasks.py
|
||||
../COPYING
|
||||
base/__init__.py
|
||||
base/constants.py
|
||||
base/paths.py
|
||||
@@ -25,14 +23,10 @@ fedora/constants.py
|
||||
fedora/paths.py
|
||||
fedora/services.py
|
||||
fedora/tasks.py
|
||||
fedora_container/__init__.py
|
||||
fedora_container/constants.py
|
||||
fedora_container/paths.py
|
||||
fedora_container/services.py
|
||||
fedora_container/tasks.py
|
||||
ipaplatform.egg-info/PKG-INFO
|
||||
ipaplatform.egg-info/SOURCES.txt
|
||||
ipaplatform.egg-info/dependency_links.txt
|
||||
ipaplatform.egg-info/namespace_packages.txt
|
||||
ipaplatform.egg-info/requires.txt
|
||||
ipaplatform.egg-info/top_level.txt
|
||||
redhat/__init__.py
|
||||
@@ -45,14 +39,4 @@ rhel/__init__.py
|
||||
rhel/constants.py
|
||||
rhel/paths.py
|
||||
rhel/services.py
|
||||
rhel/tasks.py
|
||||
rhel_container/__init__.py
|
||||
rhel_container/constants.py
|
||||
rhel_container/paths.py
|
||||
rhel_container/services.py
|
||||
rhel_container/tasks.py
|
||||
suse/__init__.py
|
||||
suse/constants.py
|
||||
suse/paths.py
|
||||
suse/services.py
|
||||
suse/tasks.py
|
||||
rhel/tasks.py
|
||||
1
ipaplatform/ipaplatform.egg-info/namespace_packages.txt
Normal file
1
ipaplatform/ipaplatform.egg-info/namespace_packages.txt
Normal file
@@ -0,0 +1 @@
|
||||
ipaplatform
|
||||
@@ -1,4 +1,4 @@
|
||||
cffi
|
||||
ipapython==4.8.10
|
||||
ipapython==4.7.2
|
||||
pyasn1
|
||||
six
|
||||
|
||||
@@ -12,23 +12,16 @@ Known Linux distros with /etc/os-release
|
||||
- fedora
|
||||
- rhel
|
||||
- ubuntu (like debian)
|
||||
|
||||
The platform ids for ipaplatform providers are based on:
|
||||
|
||||
1) IPAPLATFORM_OVERRIDE env var
|
||||
2) ipaplatform.override.OVERRIDE value
|
||||
3) ID field of /etc/os-release (Linux)
|
||||
4) ID_LIKE fields of /etc/os-release (Linux)
|
||||
"""
|
||||
from __future__ import absolute_import
|
||||
|
||||
from collections.abc import Mapping
|
||||
import importlib
|
||||
import io
|
||||
import re
|
||||
import os
|
||||
import sys
|
||||
import warnings
|
||||
|
||||
import six
|
||||
|
||||
import ipaplatform
|
||||
try:
|
||||
@@ -37,6 +30,13 @@ except ImportError:
|
||||
OVERRIDE = None
|
||||
|
||||
|
||||
# pylint: disable=no-name-in-module, import-error
|
||||
if six.PY3:
|
||||
from collections.abc import Mapping
|
||||
else:
|
||||
from collections import Mapping
|
||||
# pylint: enable=no-name-in-module, import-error
|
||||
|
||||
_osrelease_line = re.compile(
|
||||
u"^(?!#)(?P<name>[a-zA-Z0-9_]+)="
|
||||
u"(?P<quote>[\"\']?)(?P<value>.+)(?P=quote)$"
|
||||
@@ -49,7 +49,7 @@ def _parse_osrelease(filename='/etc/os-release'):
|
||||
https://www.freedesktop.org/software/systemd/man/os-release.html
|
||||
"""
|
||||
release = {}
|
||||
with open(filename) as f:
|
||||
with io.open(filename, encoding='utf-8') as f:
|
||||
for line in f:
|
||||
mo = _osrelease_line.match(line)
|
||||
if mo is not None:
|
||||
@@ -71,7 +71,7 @@ def _parse_osrelease(filename='/etc/os-release'):
|
||||
|
||||
|
||||
class OSInfo(Mapping):
|
||||
__slots__ = ('_info', '_platform', '_container')
|
||||
__slots__ = ('_info', '_platform')
|
||||
|
||||
bsd_family = (
|
||||
'freebsd',
|
||||
@@ -95,7 +95,6 @@ class OSInfo(Mapping):
|
||||
raise ValueError("Unsupported platform: {}".format(sys.platform))
|
||||
self._info = info
|
||||
self._platform = None
|
||||
self._container = None
|
||||
|
||||
def _handle_linux(self):
|
||||
"""Detect Linux distribution from /etc/os-release
|
||||
@@ -173,28 +172,20 @@ class OSInfo(Mapping):
|
||||
return self._info.get('VERSION')
|
||||
|
||||
@property
|
||||
def version_number(self):
|
||||
"""Version number tuple based on version_id
|
||||
def version_id(self):
|
||||
"""Version identifier
|
||||
"""
|
||||
version_id = self._info.get('VERSION_ID')
|
||||
if not version_id:
|
||||
return ()
|
||||
return tuple(int(p) for p in version_id.split('.'))
|
||||
return self._info.get('VERSION_ID')
|
||||
|
||||
@property
|
||||
def platform_ids(self):
|
||||
"""Ordered tuple of detected platforms (including override)
|
||||
"""
|
||||
platforms = []
|
||||
# env var first
|
||||
env = os.environ.get("IPAPLATFORM_OVERRIDE")
|
||||
if env:
|
||||
platforms.append(env)
|
||||
# override from package definition
|
||||
if OVERRIDE is not None and OVERRIDE not in platforms:
|
||||
if OVERRIDE is not None:
|
||||
# allow RPM and Debian packages to override platform
|
||||
platforms.append(OVERRIDE)
|
||||
if self.id not in platforms:
|
||||
if OVERRIDE != self.id:
|
||||
platforms.append(self.id)
|
||||
platforms.extend(self.id_like)
|
||||
return tuple(platforms)
|
||||
@@ -214,17 +205,6 @@ class OSInfo(Mapping):
|
||||
raise ImportError('No ipaplatform available for "{}"'.format(
|
||||
', '.join(self.platform_ids)))
|
||||
|
||||
@property
|
||||
def container(self):
|
||||
if self._container is not None:
|
||||
return self._container
|
||||
from ipaplatform.tasks import tasks
|
||||
try:
|
||||
self._container = tasks.detect_container()
|
||||
except NotImplementedError:
|
||||
raise NotImplementedError(
|
||||
'Platform does not support detecting containers')
|
||||
return self._container
|
||||
|
||||
osinfo = OSInfo()
|
||||
ipaplatform.NAME = osinfo.platform
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -10,17 +10,10 @@ This RHEL base platform module exports platform related constants.
|
||||
from __future__ import absolute_import
|
||||
|
||||
from ipaplatform.redhat.constants import RedHatConstantsNamespace
|
||||
from ipaplatform.osinfo import osinfo
|
||||
|
||||
# RHEL 7 and earlier use /etc/sysconfig/nfs
|
||||
# RHEL 8 uses /etc/nfs.conf
|
||||
HAS_NFS_CONF = osinfo.version_number >= (8,)
|
||||
|
||||
|
||||
class RHELConstantsNamespace(RedHatConstantsNamespace):
|
||||
IPA_ADTRUST_PACKAGE_NAME = "ipa-server-trust-ad"
|
||||
IPA_DNS_PACKAGE_NAME = "ipa-server-dns"
|
||||
if HAS_NFS_CONF:
|
||||
SECURE_NFS_VAR = None
|
||||
|
||||
constants = RHELConstantsNamespace()
|
||||
|
||||
@@ -26,12 +26,10 @@ in RHEL-based systems.
|
||||
from __future__ import absolute_import
|
||||
|
||||
from ipaplatform.redhat.paths import RedHatPathNamespace
|
||||
from ipaplatform.rhel.constants import HAS_NFS_CONF
|
||||
|
||||
|
||||
class RHELPathNamespace(RedHatPathNamespace):
|
||||
if HAS_NFS_CONF:
|
||||
SYSCONFIG_NFS = '/etc/nfs.conf'
|
||||
pass
|
||||
|
||||
|
||||
paths = RHELPathNamespace()
|
||||
|
||||
@@ -28,7 +28,10 @@ from ipaplatform.redhat import services as redhat_services
|
||||
|
||||
# Mappings from service names as FreeIPA code references to these services
|
||||
# to their actual systemd service names
|
||||
rhel_system_units = redhat_services.redhat_system_units.copy()
|
||||
rhel_system_units = redhat_services.redhat_system_units
|
||||
|
||||
# Service that sets domainname on RHEL is called rhel-domainname.service
|
||||
rhel_system_units['domainname'] = 'rhel-domainname.service'
|
||||
|
||||
|
||||
# Service classes that implement RHEL-specific behaviour
|
||||
@@ -41,6 +44,8 @@ class RHELService(redhat_services.RedHatService):
|
||||
# of specified name
|
||||
|
||||
def rhel_service_class_factory(name, api=None):
|
||||
if name == 'domainname':
|
||||
return RHELService(name, api)
|
||||
return redhat_services.redhat_service_class_factory(name, api)
|
||||
|
||||
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
"""
|
||||
This module contains RHEL Container specific platform files.
|
||||
"""
|
||||
NAME = "rhel_container"
|
||||
@@ -1,13 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
"""RHEL container constants
|
||||
"""
|
||||
from ipaplatform.rhel.constants import RHELConstantsNamespace
|
||||
|
||||
|
||||
class RHELContainerConstantsNamespace(RHELConstantsNamespace):
|
||||
pass
|
||||
|
||||
|
||||
constants = RHELContainerConstantsNamespace()
|
||||
@@ -1,30 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
"""RHEL container paths
|
||||
"""
|
||||
import os
|
||||
|
||||
from ipaplatform.rhel.paths import RHELPathNamespace
|
||||
|
||||
|
||||
def data(path):
|
||||
return os.path.join("/data", path[1:])
|
||||
|
||||
|
||||
class RHELContainerPathNamespace(RHELPathNamespace):
|
||||
KRB5_CONF = data(RHELPathNamespace.KRB5_CONF)
|
||||
KRB5_KEYTAB = data(RHELPathNamespace.KRB5_KEYTAB)
|
||||
NAMED_KEYTAB = data(RHELPathNamespace.NAMED_KEYTAB)
|
||||
NAMED_CUSTOM_CONF = data(RHELPathNamespace.NAMED_CUSTOM_CONF)
|
||||
NAMED_CUSTOM_OPTIONS_CONF = data(
|
||||
RHELPathNamespace.NAMED_CUSTOM_OPTIONS_CONF
|
||||
)
|
||||
NSSWITCH_CONF = data(RHELPathNamespace.NSSWITCH_CONF)
|
||||
PKI_CONFIGURATION = data(RHELPathNamespace.PKI_CONFIGURATION)
|
||||
SAMBA_DIR = data(RHELPathNamespace.SAMBA_DIR)
|
||||
HTTPD_IPA_WSGI_MODULES_CONF = None
|
||||
HTTPD_PASSWD_FILE_FMT = data(RHELPathNamespace.HTTPD_PASSWD_FILE_FMT)
|
||||
|
||||
|
||||
paths = RHELContainerPathNamespace()
|
||||
@@ -1,27 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
"""RHEL container services
|
||||
"""
|
||||
from ipaplatform.rhel import services as rhel_services
|
||||
|
||||
|
||||
rhel_container_system_units = rhel_services.rhel_system_units.copy()
|
||||
|
||||
|
||||
class RHELContainerService(rhel_services.RHELService):
|
||||
system_units = rhel_container_system_units
|
||||
|
||||
|
||||
def rhel_container_service_class_factory(name, api=None):
|
||||
return rhel_services.rhel_service_class_factory(name, api)
|
||||
|
||||
|
||||
class RHELContainerServices(rhel_services.RHELServices):
|
||||
def service_class_factory(self, name, api=None):
|
||||
return rhel_container_service_class_factory(name, api)
|
||||
|
||||
|
||||
timedate_services = rhel_services.timedate_services
|
||||
service = rhel_container_service_class_factory
|
||||
knownservices = RHELContainerServices()
|
||||
@@ -1,34 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
|
||||
#
|
||||
"""RHEL container tasks
|
||||
"""
|
||||
import logging
|
||||
|
||||
from ipaplatform.rhel.tasks import RHELTaskNamespace
|
||||
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class RHELContainerTaskNamespace(RHELTaskNamespace):
|
||||
def modify_nsswitch_pam_stack(
|
||||
self, sssd, mkhomedir, statestore, sudo=True
|
||||
):
|
||||
# freeipa-container images are preconfigured
|
||||
# authselect select sssd with-sudo --force
|
||||
logger.debug("Authselect is pre-configured in container images.")
|
||||
|
||||
def is_mkhomedir_supported(self):
|
||||
# authselect is not pre-configured with mkhomedir
|
||||
return False
|
||||
|
||||
def restore_auth_configuration(self, path):
|
||||
# backup is supported but restore is a no-op
|
||||
logger.debug("Authselect is pre-configured in container images.")
|
||||
|
||||
def migrate_auth_configuration(self, statestore):
|
||||
logger.debug("Authselect is pre-configured in container images.")
|
||||
|
||||
|
||||
tasks = RHELContainerTaskNamespace()
|
||||
@@ -31,16 +31,14 @@ if __name__ == '__main__':
|
||||
name="ipaplatform",
|
||||
doc=__doc__,
|
||||
package_dir={'ipaplatform': ''},
|
||||
namespace_packages=['ipaplatform'],
|
||||
packages=[
|
||||
"ipaplatform",
|
||||
"ipaplatform.base",
|
||||
"ipaplatform.debian",
|
||||
"ipaplatform.fedora",
|
||||
"ipaplatform.fedora_container",
|
||||
"ipaplatform.redhat",
|
||||
"ipaplatform.rhel",
|
||||
"ipaplatform.rhel_container",
|
||||
"ipaplatform.suse"
|
||||
"ipaplatform.rhel"
|
||||
],
|
||||
install_requires=[
|
||||
"cffi",
|
||||
|
||||
@@ -1,7 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors, see COPYING for license
|
||||
#
|
||||
|
||||
"""
|
||||
This module contains SUSE specific platform files.
|
||||
"""
|
||||
@@ -1,22 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors, see COPYING for license
|
||||
#
|
||||
|
||||
"""
|
||||
This SUSE OS family base platform module exports default platform
|
||||
related constants for the SUSE OS family-based systems.
|
||||
"""
|
||||
|
||||
# Fallback to default path definitions
|
||||
from ipaplatform.base.constants import BaseConstantsNamespace
|
||||
|
||||
|
||||
class SuseConstantsNamespace(BaseConstantsNamespace):
|
||||
HTTPD_USER = "wwwrun"
|
||||
HTTPD_GROUP = "www"
|
||||
# Don't have it yet
|
||||
SSSD_USER = "root"
|
||||
TLS_HIGH_CIPHERS = None
|
||||
|
||||
|
||||
constants = SuseConstantsNamespace()
|
||||
@@ -1,88 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors, see COPYING for license
|
||||
#
|
||||
|
||||
"""
|
||||
This SUSE OS family base platform module exports default filesystem paths as
|
||||
common in SUSE OS family-based systems.
|
||||
"""
|
||||
|
||||
from ipaplatform.base.paths import BasePathNamespace
|
||||
|
||||
|
||||
class SusePathNamespace(BasePathNamespace):
|
||||
BIN_HOSTNAMECTL = "/usr/bin/hostnamectl"
|
||||
SYSTEMCTL = "/usr/bin/systemctl"
|
||||
ETC_HTTPD_DIR = "/etc/apache2"
|
||||
HTTPD_ALIAS_DIR = "/etc/apache2/ipa"
|
||||
GSSAPI_SESSION_KEY = "/etc/apache2/ipa/ipasession.key"
|
||||
HTTPD_CONF_D_DIR = "/etc/apache2/conf.d/"
|
||||
HTTPD_IPA_KDCPROXY_CONF_SYMLINK = "/etc/apache2/conf.d/ipa-kdc-proxy.conf"
|
||||
HTTPD_IPA_PKI_PROXY_CONF = "/etc/apache2/conf.d/ipa-pki-proxy.conf"
|
||||
HTTPD_IPA_REWRITE_CONF = "/etc/apache2/conf.d/ipa-rewrite.conf"
|
||||
HTTPD_IPA_CONF = "/etc/apache2/conf.d/ipa.conf"
|
||||
HTTPD_NSS_CONF = "/etc/apache2/conf.d/nss.conf"
|
||||
HTTPD_SSL_CONF = "/etc/apache2/conf.d/ssl.conf"
|
||||
HTTPD_SSL_SITE_CONF = "/etc/apache2/conf.d/ssl.conf"
|
||||
HTTPD_PASSWORD_CONF = "/etc/apache2/ipa/password.conf"
|
||||
NAMED_CUSTOM_CONF = "/etc/named.d/ipa-ext.conf"
|
||||
NAMED_CUSTOM_OPTIONS_CONF = "/etc/named.d/ipa-options-ext.conf"
|
||||
NAMED_VAR_DIR = "/var/lib/named"
|
||||
NAMED_MANAGED_KEYS_DIR = "/var/lib/named/dyn"
|
||||
IPA_P11_KIT = "/etc/pki/trust/ipa.p11-kit"
|
||||
# Those files are only here to be able to configure them, we copy those in
|
||||
# rpm spec to fillupdir
|
||||
SYSCONFIG_HTTPD = "/etc/sysconfig/apache2"
|
||||
SYSCONFIG_NAMED = "/etc/sysconfig/named-named"
|
||||
SYSCONFIG_NTPD = "/etc/sysconfig/ntp"
|
||||
SYSCONF_NETWORK = "/etc/sysconfig/network/config"
|
||||
SYSTEMD_SYSTEM_HTTPD_D_DIR = "/etc/systemd/system/apache2.service.d/"
|
||||
SYSTEMD_SYSTEM_HTTPD_IPA_CONF = (
|
||||
"/etc/systemd/system/apache2.service.d/ipa.conf"
|
||||
)
|
||||
CERTMONGER_COMMAND_TEMPLATE = "/usr/lib/ipa/certmonger/%s"
|
||||
CHROMIUM_BROWSER = "/usr/bin/chromium"
|
||||
BIN_NISDOMAINNAME = "/bin/nisdomainname"
|
||||
BIND_LDAP_DNS_IPA_WORKDIR = "/var/lib/named/dyndb-ldap/ipa/"
|
||||
BIND_LDAP_DNS_ZONE_WORKDIR = "/var/lib/named/dyndb-ldap/ipa/master/"
|
||||
PAM_KRB5_SO = "/lib/security/pam_krb5.so"
|
||||
PAM_KRB5_SO_64 = PAM_KRB5_SO
|
||||
# openSUSE still uses lib for libexec, this will change when we don't
|
||||
# anymore
|
||||
LIBEXEC_CERTMONGER_DIR = "/usr/lib/certmonger"
|
||||
DOGTAG_IPA_CA_RENEW_AGENT_SUBMIT = (
|
||||
"/usr/lib/certmonger/dogtag-ipa-ca-renew-agent-submit"
|
||||
)
|
||||
DOGTAG_IPA_RENEW_AGENT_SUBMIT = (
|
||||
"/usr/lib/certmonger/dogtag-ipa-renew-agent-submit"
|
||||
)
|
||||
CERTMONGER_DOGTAG_SUBMIT = "/usr/lib/certmonger/dogtag-submit"
|
||||
IPA_SERVER_GUARD = "/usr/lib/certmonger/ipa-server-guard"
|
||||
GENERATE_RNDC_KEY = "/usr/lib/generate-rndc-key.sh"
|
||||
LIBEXEC_IPA_DIR = "/usr/lib/ipa"
|
||||
IPA_DNSKEYSYNCD_REPLICA = "/usr/lib/ipa/ipa-dnskeysync-replica"
|
||||
IPA_DNSKEYSYNCD = "/usr/lib/ipa/ipa-dnskeysyncd"
|
||||
IPA_HTTPD_KDCPROXY = "/usr/lib/ipa/ipa-httpd-kdcproxy"
|
||||
IPA_ODS_EXPORTER = "/usr/lib/ipa/ipa-ods-exporter"
|
||||
IPA_PKI_RETRIEVE_KEY = "/usr/lib/ipa/ipa-pki-retrieve-key"
|
||||
IPA_HTTPD_PASSWD_READER = "/usr/lib/ipa/ipa-httpd-pwdreader"
|
||||
IPA_PKI_WAIT_RUNNING = "/usr/lib/ipa/ipa-pki-wait-running"
|
||||
DNSSEC_KEYFROMLABEL = "/usr/sbin/dnssec-keyfromlabel-pkcs11"
|
||||
VAR_KERBEROS_KRB5KDC_DIR = "/var/lib/kerberos/krb5kdc/"
|
||||
VAR_KRB5KDC_K5_REALM = "/var/lib/kerberos/krb5kdc/.k5."
|
||||
CACERT_PEM = "/var/lib/kerberos/krb5kdc/cacert.pem"
|
||||
KRB5KDC_KADM5_ACL = "/var/lib/kerberos/krb5kdc/kadm5.acl"
|
||||
KRB5KDC_KADM5_KEYTAB = "/var/lib/kerberos/krb5kdc/kadm5.keytab"
|
||||
KRB5KDC_KDC_CONF = "/var/lib/kerberos/krb5kdc/kdc.conf"
|
||||
KDC_CERT = "/var/lib/kerberos/krb5kdc/kdc.crt"
|
||||
KDC_KEY = "/var/lib/kerberos/krb5kdc/kdc.key"
|
||||
NAMED_RUN = "/var/lib/named/data/named.run"
|
||||
IPA_CUSTODIA_HANDLER = "/usr/lib/ipa/custodia"
|
||||
WSGI_PREFIX_DIR = "/run/apache2/wsgi"
|
||||
KDESTROY = "/usr/lib/mit/bin/kdestroy"
|
||||
BIN_KVNO = "/usr/lib/mit/bin/kvno"
|
||||
UPDATE_CA_TRUST = "/usr/sbin/update-ca-certificates"
|
||||
AUTHSELECT = "/usr/bin/authselect"
|
||||
|
||||
|
||||
paths = SusePathNamespace()
|
||||
@@ -1,194 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors, see COPYING for license
|
||||
#
|
||||
|
||||
import os
|
||||
import logging
|
||||
import time
|
||||
import contextlib
|
||||
|
||||
from ipaplatform.base import services as base_services
|
||||
from ipapython import ipautil, dogtag
|
||||
from ipaplatform.paths import paths
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
suse_system_units = dict(
|
||||
(x, "%s.service" % x) for x in base_services.wellknownservices
|
||||
)
|
||||
suse_system_units["httpd"] = "apache2.service"
|
||||
|
||||
suse_system_units["dirsrv"] = "dirsrv@.service"
|
||||
suse_system_units["pki-tomcatd"] = "pki-tomcatd@pki-tomcat.service"
|
||||
suse_system_units["pki_tomcatd"] = suse_system_units["pki-tomcatd"]
|
||||
suse_system_units["ipa-otpd"] = "ipa-otpd.socket"
|
||||
suse_system_units["ipa-dnskeysyncd"] = "ipa-dnskeysyncd.service"
|
||||
suse_system_units["named-regular"] = "named.service"
|
||||
suse_system_units["named-pkcs11"] = "named.service"
|
||||
suse_system_units["named"] = "named.service"
|
||||
suse_system_units["ods-enforcerd"] = "ods-enforcerd.service"
|
||||
suse_system_units["ods_enforcerd"] = suse_system_units["ods-enforcerd"]
|
||||
suse_system_units["ods-signerd"] = "ods-signerd.service"
|
||||
suse_system_units["ods_signerd"] = suse_system_units["ods-signerd"]
|
||||
|
||||
|
||||
class SuseService(base_services.SystemdService):
|
||||
system_units = suse_system_units
|
||||
|
||||
def __init__(self, service_name, api=None):
|
||||
systemd_name = service_name
|
||||
if service_name in self.system_units:
|
||||
systemd_name = self.system_units[service_name]
|
||||
else:
|
||||
if "." not in service_name:
|
||||
systemd_name = "%s.service" % (service_name)
|
||||
super().__init__(service_name, systemd_name, api)
|
||||
|
||||
|
||||
class SuseDirectoryService(SuseService):
|
||||
def is_installed(self, instance_name):
|
||||
file_path = "{}/{}-{}".format(
|
||||
paths.ETC_DIRSRV, "slapd", instance_name
|
||||
)
|
||||
return os.path.exists(file_path)
|
||||
|
||||
def restart(
|
||||
self, instance_name="", capture_output=True, wait=True, ldapi=False
|
||||
):
|
||||
# We need to explicitly enable instances to install proper symlinks as
|
||||
# dirsrv.target.wants/ dependencies. Standard systemd service class
|
||||
# does it on enable() method call. Unfortunately, ipa-server-install
|
||||
# does not do explicit dirsrv.enable() because the service startup is
|
||||
# handled by ipactl.
|
||||
#
|
||||
# If we wouldn't do this, our instances will not be started as systemd
|
||||
# would not have any clue about instances (PKI-IPA and the domain we
|
||||
# serve) at all. Thus, hook into dirsrv.restart().
|
||||
|
||||
if instance_name:
|
||||
elements = self.systemd_name.split("@")
|
||||
|
||||
srv_etc = os.path.join(
|
||||
paths.ETC_SYSTEMD_SYSTEM_DIR, self.systemd_name
|
||||
)
|
||||
srv_tgt = os.path.join(
|
||||
paths.ETC_SYSTEMD_SYSTEM_DIR,
|
||||
self.SYSTEMD_SRV_TARGET % (elements[0]),
|
||||
)
|
||||
srv_lnk = os.path.join(
|
||||
srv_tgt, self.service_instance(instance_name)
|
||||
)
|
||||
|
||||
if not os.path.exists(srv_etc):
|
||||
self.enable(instance_name)
|
||||
elif not os.path.samefile(srv_etc, srv_lnk):
|
||||
os.unlink(srv_lnk)
|
||||
os.symlink(srv_etc, srv_lnk)
|
||||
|
||||
with self._wait(instance_name, wait, ldapi) as wait:
|
||||
super().restart(
|
||||
instance_name, capture_output=capture_output, wait=wait
|
||||
)
|
||||
|
||||
def start(
|
||||
self, instance_name="", capture_output=True, wait=True, ldapi=False
|
||||
):
|
||||
with self._wait(instance_name, wait, ldapi) as wait:
|
||||
super().start(
|
||||
instance_name, capture_output=capture_output, wait=wait
|
||||
)
|
||||
|
||||
@contextlib.contextmanager
|
||||
def _wait(self, instance_name, wait, ldapi):
|
||||
if ldapi:
|
||||
instance_name = self.service_instance(instance_name)
|
||||
if instance_name.endswith(".service"):
|
||||
instance_name = instance_name[:-8]
|
||||
if instance_name.startswith("dirsrv"):
|
||||
# this is intentional, return the empty string if the instance
|
||||
# name is 'dirsrv'
|
||||
instance_name = instance_name[7:]
|
||||
if not instance_name:
|
||||
ldapi = False
|
||||
if ldapi:
|
||||
yield False
|
||||
socket_name = paths.SLAPD_INSTANCE_SOCKET_TEMPLATE % instance_name
|
||||
ipautil.wait_for_open_socket(
|
||||
socket_name, self.api.env.startup_timeout
|
||||
)
|
||||
else:
|
||||
yield wait
|
||||
|
||||
|
||||
class SuseIPAService(SuseService):
|
||||
# Credits to upstream developer
|
||||
def enable(self, instance_name=""):
|
||||
super().enable(instance_name)
|
||||
self.restart(instance_name)
|
||||
|
||||
|
||||
class SuseCAService(SuseService):
|
||||
# Credits to upstream developer
|
||||
def wait_until_running(self):
|
||||
logger.debug("Waiting until the CA is running")
|
||||
timeout = float(self.api.env.startup_timeout)
|
||||
op_timeout = time.time() + timeout
|
||||
while time.time() < op_timeout:
|
||||
try:
|
||||
# check status of CA instance on this host, not remote ca_host
|
||||
status = dogtag.ca_status(self.api.env.host)
|
||||
except Exception as e:
|
||||
status = "check interrupted due to error: %s" % e
|
||||
logger.debug("The CA status is: %s", status)
|
||||
if status == "running":
|
||||
break
|
||||
logger.debug("Waiting for CA to start...")
|
||||
time.sleep(1)
|
||||
else:
|
||||
raise RuntimeError("CA did not start in %ss" % timeout)
|
||||
|
||||
def is_running(self, instance_name="", wait=True):
|
||||
if instance_name:
|
||||
return super().is_running(instance_name)
|
||||
try:
|
||||
status = dogtag.ca_status()
|
||||
if status == "running":
|
||||
return True
|
||||
elif status == "starting" and wait:
|
||||
# Exception is raised if status is 'starting' even after wait
|
||||
self.wait_until_running()
|
||||
return True
|
||||
except Exception as e:
|
||||
logger.debug("Failed to check CA status: %s", e)
|
||||
return False
|
||||
|
||||
|
||||
def suse_service_class_factory(name, api):
|
||||
if name == "dirsrv":
|
||||
return SuseDirectoryService(name, api)
|
||||
if name == "ipa":
|
||||
return SuseIPAService(name, api)
|
||||
if name in ("pki-tomcatd", "pki_tomcatd"):
|
||||
return SuseCAService(name, api)
|
||||
return SuseService(name, api)
|
||||
|
||||
|
||||
class SuseServices(base_services.KnownServices):
|
||||
def service_class_factory(self, name, api=None):
|
||||
return suse_service_class_factory(name, api)
|
||||
|
||||
# Credits to upstream developer
|
||||
def __init__(self):
|
||||
# pylint: disable=ipa-forbidden-import
|
||||
import ipalib
|
||||
|
||||
# pylint: enable=ipa-forbidden-import
|
||||
services = dict()
|
||||
for s in base_services.wellknownservices:
|
||||
services[s] = self.service_class_factory(s, ipalib.api)
|
||||
super().__init__(services)
|
||||
|
||||
|
||||
timedate_services = ["ntpd"]
|
||||
service = suse_service_class_factory
|
||||
knownservices = SuseServices()
|
||||
@@ -1,46 +0,0 @@
|
||||
#
|
||||
# Copyright (C) 2020 FreeIPA Contributors, see COPYING for license
|
||||
#
|
||||
|
||||
"""
|
||||
This module contains default SUSE OS family-specific implementations of
|
||||
system tasks.
|
||||
"""
|
||||
|
||||
import logging
|
||||
|
||||
from ipaplatform.paths import paths
|
||||
from ipaplatform.redhat.tasks import RedHatTaskNamespace
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class SuseTaskNamespace(RedHatTaskNamespace):
|
||||
def restore_context(self, filepath, force=False):
|
||||
pass # FIXME: Implement after libexec move
|
||||
|
||||
def check_selinux_status(self, restorecon=paths.RESTORECON):
|
||||
pass # FIXME: Implement after libexec move
|
||||
|
||||
def set_nisdomain(self, nisdomain):
|
||||
nis_variable = "NETCONFIG_NIS_STATIC_DOMAIN"
|
||||
try:
|
||||
with open(paths.SYSCONF_NETWORK, "r") as f:
|
||||
content = [
|
||||
line
|
||||
for line in f
|
||||
if not line.strip().upper().startswith(nis_variable)
|
||||
]
|
||||
except IOError:
|
||||
content = []
|
||||
|
||||
content.append("{}={}\n".format(nis_variable, nisdomain))
|
||||
|
||||
with open(paths.SYSCONF_NETWORK, "w") as f:
|
||||
f.writelines(content)
|
||||
|
||||
def set_selinux_booleans(self, required_settings, backup_func=None):
|
||||
return False # FIXME: Implement after libexec move
|
||||
|
||||
|
||||
tasks = SuseTaskNamespace()
|
||||
Reference in New Issue
Block a user