diff --git a/ipaplatform/base/constants.py b/ipaplatform/base/constants.py index b24d428ce..c7d1a8766 100644 --- a/ipaplatform/base/constants.py +++ b/ipaplatform/base/constants.py @@ -43,6 +43,17 @@ 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', + }, + } SSSD_USER = "sssd" # WSGI module override, only used on Fedora MOD_WSGI_PYTHON2 = None diff --git a/ipaplatform/base/paths.py b/ipaplatform/base/paths.py index 9328524f2..000cef449 100644 --- a/ipaplatform/base/paths.py +++ b/ipaplatform/base/paths.py @@ -319,6 +319,8 @@ class BasePathNamespace: 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" diff --git a/ipapython/ipautil.py b/ipapython/ipautil.py index 106745354..22434cba7 100644 --- a/ipapython/ipautil.py +++ b/ipapython/ipautil.py @@ -28,6 +28,7 @@ import random import math import os import sys +import errno import copy import shutil import socket @@ -54,6 +55,7 @@ except ImportError: netifaces = None from ipapython.dn import DN +from ipaplatform.paths import paths logger = logging.getLogger(__name__) @@ -1571,3 +1573,61 @@ class APIVersion(tuple): @property def minor(self): return self[1] + + +def remove_keytab(keytab_path): + """ + Remove Kerberos keytab and issue a warning if the procedure fails + + :param keytab_path: path to the keytab file + """ + try: + logger.debug("Removing service keytab: %s", keytab_path) + os.remove(keytab_path) + except OSError as e: + if e.errno != errno.ENOENT: + logger.warning("Failed to remove Kerberos keytab '%s': %s", + keytab_path, e) + logger.warning("You may have to remove it manually") + + +def remove_ccache(ccache_path=None, run_as=None): + """ + remove Kerberos credential cache, essentially a wrapper around kdestroy. + + :param ccache_path: path to the ccache file + :param run_as: run kdestroy as this user + """ + logger.debug("Removing service credentials cache") + kdestroy_cmd = [paths.KDESTROY] + if ccache_path is not None: + logger.debug("Ccache path: '%s'", ccache_path) + kdestroy_cmd.extend(['-c', ccache_path]) + + try: + run(kdestroy_cmd, runas=run_as, env={}) + except CalledProcessError as e: + logger.warning( + "Failed to clear Kerberos credentials cache: %s", e) + + +def remove_file(filename): + """Remove a file and log any exceptions raised. + """ + try: + os.unlink(filename) + except Exception as e: + # ignore missing file + if getattr(e, 'errno', None) != errno.ENOENT: + logger.error('Error removing %s: %s', filename, str(e)) + + +def rmtree(path): + """ + Remove a directory structure and log any exceptions raised. + """ + try: + if os.path.exists(path): + shutil.rmtree(path) + except Exception as e: + logger.error('Error removing %s: %s', path, str(e)) diff --git a/ipaserver/install/adtrustinstance.py b/ipaserver/install/adtrustinstance.py index 51c517c79..7bb9431c5 100644 --- a/ipaserver/install/adtrustinstance.py +++ b/ipaserver/install/adtrustinstance.py @@ -567,7 +567,7 @@ class ADTRUSTInstance(service.Service): Purge old CIFS keys from samba and clean up samba ccache """ self.clean_samba_keytab() - installutils.remove_ccache(paths.KRB5CC_SAMBA) + ipautil.remove_ccache(paths.KRB5CC_SAMBA) def set_keytab_owner(self, keytab=None, owner=None): """ @@ -929,16 +929,16 @@ class ADTRUSTInstance(service.Service): self.print_msg('WARNING: ' + str(e)) # Remove samba's credentials cache - installutils.remove_ccache(ccache_path=paths.KRB5CC_SAMBA) + ipautil.remove_ccache(ccache_path=paths.KRB5CC_SAMBA) # Remove samba's configuration file - installutils.remove_file(self.smb_conf) + ipautil.remove_file(self.smb_conf) # Remove samba's persistent and temporary tdb files tdb_files = [tdb_file for tdb_file in os.listdir(paths.SAMBA_DIR) if tdb_file.endswith(".tdb")] for tdb_file in tdb_files: - installutils.remove_file(tdb_file) + ipautil.remove_file(tdb_file) # Remove our keys from samba's keytab self.clean_samba_keytab() diff --git a/ipaserver/install/bindinstance.py b/ipaserver/install/bindinstance.py index 6dc0288a4..9920d311c 100644 --- a/ipaserver/install/bindinstance.py +++ b/ipaserver/install/bindinstance.py @@ -1217,7 +1217,7 @@ class BindInstance(service.Service): except Exception: logger.exception("Failed to unconfigure DNS resolver") - installutils.rmtree(paths.BIND_LDAP_DNS_IPA_WORKDIR) + ipautil.rmtree(paths.BIND_LDAP_DNS_IPA_WORKDIR) # disabled by default, by ldap_configure() if enabled: @@ -1237,5 +1237,5 @@ class BindInstance(service.Service): if named_regular_running: self.named_regular.start() - installutils.remove_keytab(self.keytab) - installutils.remove_ccache(run_as=self.service_user) + ipautil.remove_keytab(self.keytab) + ipautil.remove_ccache(run_as=self.service_user) diff --git a/ipaserver/install/ca.py b/ipaserver/install/ca.py index 1097e9b26..6b040b311 100644 --- a/ipaserver/install/ca.py +++ b/ipaserver/install/ca.py @@ -427,8 +427,8 @@ def install_step_1(standalone, replica_config, options, custodia): def uninstall(): ca_instance = cainstance.CAInstance(api.env.realm) ca_instance.stop_tracking_certificates() - installutils.remove_file(paths.RA_AGENT_PEM) - installutils.remove_file(paths.RA_AGENT_KEY) + ipautil.remove_file(paths.RA_AGENT_PEM) + ipautil.remove_file(paths.RA_AGENT_KEY) if ca_instance.is_configured(): ca_instance.uninstall() diff --git a/ipaserver/install/cainstance.py b/ipaserver/install/cainstance.py index 51c987278..6e1fc724d 100644 --- a/ipaserver/install/cainstance.py +++ b/ipaserver/install/cainstance.py @@ -69,7 +69,6 @@ from ipaserver.install import sysupgrade from ipaserver.install.dogtaginstance import DogtagInstance from ipaserver.plugins import ldap2 from ipaserver.masters import ENABLED_SERVICE -from ipaserver.install.installutils import remove_file logger = logging.getLogger(__name__) @@ -520,7 +519,7 @@ class CAInstance(DogtagInstance): # if paths.TMP_CA_P12 exists and is not owned by root, # shutil.copy will fail if when fs.protected_regular=1 # so remove the file first - remove_file(paths.TMP_CA_P12) + ipautil.remove_file(paths.TMP_CA_P12) shutil.copy(cafile, paths.TMP_CA_P12) pent = pwd.getpwnam(self.service_user) os.chown(paths.TMP_CA_P12, pent.pw_uid, pent.pw_gid) @@ -1000,7 +999,7 @@ class CAInstance(DogtagInstance): cmonger.stop() # remove ipa-pki-wait-running config - remove_file(paths.SYSTEMD_PKI_TOMCAT_IPA_CONF) + ipautil.remove_file(paths.SYSTEMD_PKI_TOMCAT_IPA_CONF) try: os.rmdir(os.path.dirname(paths.SYSTEMD_PKI_TOMCAT_IPA_CONF)) except OSError: @@ -1012,7 +1011,7 @@ class CAInstance(DogtagInstance): try: for f in get_crl_files(): logger.debug("Remove %s", f) - installutils.remove_file(f) + ipautil.remove_file(f) except OSError as e: logger.warning("Error while removing old CRL files: %s", e) diff --git a/ipaserver/install/custodiainstance.py b/ipaserver/install/custodiainstance.py index 00b2c4c44..df59e70f0 100644 --- a/ipaserver/install/custodiainstance.py +++ b/ipaserver/install/custodiainstance.py @@ -14,7 +14,6 @@ from ipaserver.install.service import SimpleServiceInstance from ipapython import ipautil from ipapython import ipaldap from ipapython.certdb import NSSDatabase -from ipaserver.install import installutils from ipaserver.install import ldapupdate from ipaserver.install import sysupgrade from base64 import b64decode @@ -150,7 +149,7 @@ class CustodiaInstance(SimpleServiceInstance): 'ldap_uri': self.ldap_uri }) keystore.remove_server_keys_file() - installutils.remove_file(self.config_file) + ipautil.remove_file(self.config_file) sysupgrade.set_upgrade_state('custodia', 'installed', False) def __gen_keys(self): diff --git a/ipaserver/install/dnskeysyncinstance.py b/ipaserver/install/dnskeysyncinstance.py index a1651b239..0cc5cd0c4 100644 --- a/ipaserver/install/dnskeysyncinstance.py +++ b/ipaserver/install/dnskeysyncinstance.py @@ -390,7 +390,7 @@ class DNSKeySyncInstance(service.Service): def __setup_principal(self): assert self.ods_gid is not None - installutils.remove_keytab(self.keytab) + ipautil.remove_keytab(self.keytab) installutils.kadmin_addprinc(self.principal) # Store the keytab on disk @@ -465,8 +465,8 @@ class DNSKeySyncInstance(service.Service): # remove softhsm pin, to make sure new installation will generate # new token database # do not delete *so pin*, user can need it to get token data - installutils.remove_file(paths.DNSSEC_SOFTHSM_PIN) - installutils.remove_file(paths.DNSSEC_SOFTHSM2_CONF) + ipautil.remove_file(paths.DNSSEC_SOFTHSM_PIN) + ipautil.remove_file(paths.DNSSEC_SOFTHSM2_CONF) try: shutil.rmtree(paths.DNSSEC_TOKENS_DIR) @@ -476,4 +476,4 @@ class DNSKeySyncInstance(service.Service): "Failed to remove %s", paths.DNSSEC_TOKENS_DIR ) - installutils.remove_keytab(self.keytab) + ipautil.remove_keytab(self.keytab) diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py index ab4af6a7a..9bafedef2 100644 --- a/ipaserver/install/dsinstance.py +++ b/ipaserver/install/dsinstance.py @@ -1098,20 +1098,20 @@ class DsInstance(service.Service): logger.error("Failed to remove DS instance. No serverid present " "in sysrestore file.") - installutils.remove_keytab(paths.DS_KEYTAB) - installutils.remove_ccache(run_as=DS_USER) + ipautil.remove_keytab(paths.DS_KEYTAB) + ipautil.remove_ccache(run_as=DS_USER) if serverid is None: # Remove scripts dir scripts = paths.VAR_LIB_DIRSRV_INSTANCE_SCRIPTS_TEMPLATE % ( serverid) - installutils.rmtree(scripts) + ipautil.rmtree(scripts) # remove systemd unit file unitfile = paths.SLAPD_INSTANCE_SYSTEMD_IPA_ENV_TEMPLATE % ( serverid ) - installutils.remove_file(unitfile) + ipautil.remove_file(unitfile) try: os.rmdir(os.path.dirname(unitfile)) except OSError: diff --git a/ipaserver/install/httpinstance.py b/ipaserver/install/httpinstance.py index 551b1c073..4436b5601 100644 --- a/ipaserver/install/httpinstance.py +++ b/ipaserver/install/httpinstance.py @@ -171,7 +171,7 @@ class HTTPInstance(service.Service): # Clean up existing ccaches # Make sure that empty env is passed to avoid passing KRB5CCNAME from # current env - installutils.remove_file(paths.HTTP_CCACHE) + ipautil.remove_file(paths.HTTP_CCACHE) for f in os.listdir(paths.IPA_CCACHES): os.remove(os.path.join(paths.IPA_CCACHES, f)) @@ -529,7 +529,7 @@ class HTTPInstance(service.Service): logger.debug("%s", error) # Remove the configuration files we create - installutils.remove_keytab(self.keytab) + ipautil.remove_keytab(self.keytab) remove_files = [ paths.HTTP_CCACHE, paths.HTTPD_CERT_FILE, @@ -553,7 +553,7 @@ class HTTPInstance(service.Service): remove_files.append(paths.HTTPD_IPA_WSGI_MODULES_CONF) for filename in remove_files: - installutils.remove_file(filename) + ipautil.remove_file(filename) try: os.rmdir(paths.SYSTEMD_SYSTEM_HTTPD_D_DIR) diff --git a/ipaserver/install/installutils.py b/ipaserver/install/installutils.py index 0778bccc1..ba98e8bed 100644 --- a/ipaserver/install/installutils.py +++ b/ipaserver/install/installutils.py @@ -20,7 +20,6 @@ from __future__ import absolute_import from __future__ import print_function -import errno import logging import socket import getpass @@ -679,23 +678,24 @@ def check_server_configuration(): def remove_file(filename): """Remove a file and log any exceptions raised. """ - try: - os.unlink(filename) - except Exception as e: - # ignore missing file - if getattr(e, 'errno', None) != errno.ENOENT: - logger.error('Error removing %s: %s', filename, str(e)) + warnings.warn( + "Use 'ipapython.ipautil.remove_file'", + DeprecationWarning, + stacklevel=2 + ) + return ipautil.remove_file(filename) def rmtree(path): """ Remove a directory structure and log any exceptions raised. """ - try: - if os.path.exists(path): - shutil.rmtree(path) - except Exception as e: - logger.error('Error removing %s: %s', path, str(e)) + warnings.warn( + "Use 'ipapython.ipautil.rmtree'", + DeprecationWarning, + stacklevel=2 + ) + return ipautil.rmtree(path) def is_ipa_configured(): @@ -1349,14 +1349,12 @@ def remove_keytab(keytab_path): :param keytab_path: path to the keytab file """ - try: - logger.debug("Removing service keytab: %s", keytab_path) - os.remove(keytab_path) - except OSError as e: - if e.errno != errno.ENOENT: - logger.warning("Failed to remove Kerberos keytab '%s': %s", - keytab_path, e) - logger.warning("You may have to remove it manually") + warnings.warn( + "Use 'ipapython.ipautil.remove_keytab'", + DeprecationWarning, + stacklevel=2 + ) + return ipautil.remove_keytab(keytab_path) def remove_ccache(ccache_path=None, run_as=None): @@ -1366,17 +1364,12 @@ def remove_ccache(ccache_path=None, run_as=None): :param ccache_path: path to the ccache file :param run_as: run kdestroy as this user """ - logger.debug("Removing service credentials cache") - kdestroy_cmd = [paths.KDESTROY] - if ccache_path is not None: - logger.debug("Ccache path: '%s'", ccache_path) - kdestroy_cmd.extend(['-c', ccache_path]) - - try: - ipautil.run(kdestroy_cmd, runas=run_as, env={}) - except ipautil.CalledProcessError as e: - logger.warning( - "Failed to clear Kerberos credentials cache: %s", e) + warnings.warn( + "Use 'ipapython.ipautil.remove_ccache'", + DeprecationWarning, + stacklevel=2 + ) + return ipautil.remove_ccache(ccache_path=ccache_path, run_as=run_as) def restart_dirsrv(instance_name="", capture_output=True): diff --git a/ipaserver/install/krbinstance.py b/ipaserver/install/krbinstance.py index cb709874a..f5bac3353 100644 --- a/ipaserver/install/krbinstance.py +++ b/ipaserver/install/krbinstance.py @@ -600,8 +600,8 @@ class KrbInstance(service.Service): certmonger.stop_tracking(certfile=paths.KDC_CERT) def delete_pkinit_cert(self): - installutils.remove_file(paths.KDC_CERT) - installutils.remove_file(paths.KDC_KEY) + ipautil.remove_file(paths.KDC_CERT) + ipautil.remove_file(paths.KDC_KEY) def uninstall(self): if self.is_configured(): @@ -627,7 +627,7 @@ class KrbInstance(service.Service): # stop tracking and remove certificates self.stop_tracking_certs() - installutils.remove_file(paths.CACERT_PEM) + ipautil.remove_file(paths.CACERT_PEM) self.delete_pkinit_cert() if running: diff --git a/ipaserver/install/odsexporterinstance.py b/ipaserver/install/odsexporterinstance.py index 47f7d8a12..54c4e622a 100644 --- a/ipaserver/install/odsexporterinstance.py +++ b/ipaserver/install/odsexporterinstance.py @@ -186,5 +186,5 @@ class ODSExporterInstance(service.Service): if signerd_running: signerd_service.start() - installutils.remove_keytab(self.keytab) - installutils.remove_ccache(ccache_path=paths.IPA_ODS_EXPORTER_CCACHE) + ipautil.remove_keytab(self.keytab) + ipautil.remove_ccache(ccache_path=paths.IPA_ODS_EXPORTER_CCACHE) diff --git a/ipaserver/install/server/install.py b/ipaserver/install/server/install.py index 36ef2ddff..02c8f4d55 100644 --- a/ipaserver/install/server/install.py +++ b/ipaserver/install/server/install.py @@ -1193,7 +1193,7 @@ def uninstall(installer): else: # sysrestore.state has no state left, remove it sysrestore = os.path.join(SYSRESTORE_DIR_PATH, 'sysrestore.state') - installutils.remove_file(sysrestore) + ipautil.remove_file(sysrestore) # Note that this name will be wrong after the first uninstall. dirname = dsinstance.config_dirname( diff --git a/ipaserver/install/server/upgrade.py b/ipaserver/install/server/upgrade.py index 39f697e78..07991204f 100644 --- a/ipaserver/install/server/upgrade.py +++ b/ipaserver/install/server/upgrade.py @@ -267,7 +267,7 @@ def cleanup_kdc(fstore): logger.info('[Checking for deprecated KDC configuration files]') for file in ['kpasswd.keytab', 'ldappwd']: filename = os.path.join(paths.VAR_KERBEROS_KRB5KDC_DIR, file) - installutils.remove_file(filename) + ipautil.remove_file(filename) if fstore.has_file(filename): fstore.untrack_file(filename) logger.debug('Uninstalling %s', filename) @@ -1090,7 +1090,7 @@ def certificate_renewal_update(ca, ds, http): if os.path.exists(filename): with installutils.stopped_service('certmonger'): logger.info("Removing %s", filename) - installutils.remove_file(filename) + ipautil.remove_file(filename) ca.configure_certmonger_renewal() ca.configure_renewal()