Imported Debian patch 4.7.2-3

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

View File

@@ -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@

View File

@@ -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.

View File

@@ -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

View File

@@ -10,7 +10,7 @@ import sys
from ipaplatform.osinfo import osinfo
class IpaMetaImporter:
class IpaMetaImporter(object):
modules = {
'ipaplatform.constants',
'ipaplatform.paths',

View File

@@ -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

View File

@@ -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()

View File

@@ -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:

View File

@@ -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()

View File

@@ -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()

View File

@@ -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)

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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)

View File

@@ -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()

View File

@@ -1,7 +0,0 @@
#
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
#
"""
This module contains Fedora Container specific platform files.
"""
NAME = "fedora_container"

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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.*

View File

@@ -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

View File

@@ -0,0 +1 @@
ipaplatform

View File

@@ -1,4 +1,4 @@
cffi
ipapython==4.8.10
ipapython==4.7.2
pyasn1
six

View File

@@ -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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -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()

View File

@@ -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()

View File

@@ -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)

View File

@@ -1,7 +0,0 @@
#
# Copyright (C) 2020 FreeIPA Contributors see COPYING for license
#
"""
This module contains RHEL Container specific platform files.
"""
NAME = "rhel_container"

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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",

View File

@@ -1,7 +0,0 @@
#
# Copyright (C) 2020 FreeIPA Contributors, see COPYING for license
#
"""
This module contains SUSE specific platform files.
"""

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()

View File

@@ -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()