diff options
Diffstat (limited to 'ipapython/platform/redhat.py')
-rw-r--r-- | ipapython/platform/redhat.py | 163 |
1 files changed, 110 insertions, 53 deletions
diff --git a/ipapython/platform/redhat.py b/ipapython/platform/redhat.py index c6d2631cd..de97b5be8 100644 --- a/ipapython/platform/redhat.py +++ b/ipapython/platform/redhat.py @@ -18,80 +18,83 @@ # along with this program. If not, see <http://www.gnu.org/licenses/>. # -from ipapython import ipautil +import tempfile +import re +import os +import stat +import sys +from ipapython import ipautil, sysrestore +from ipapython import services as ipaservices -SERVICE_PORTMAP = "portmap" -SERVICE_RPCBIND = "rpcbind" -SERVICE_CERTMONGER = "certmonger" -SERVICE_NSCD = "nscd" -SERVICE_NLSCD = "nlscd" +# All what we allow exporting directly from this module +# Everything else is made available through these symbols when they directly imported into ipapython.services: +# authconfig -- class reference for platform-specific implementation of authconfig(8) +# service -- class reference for platform-specific implementation of a PlatformService class +# knownservices -- factory instance to access named services IPA cares about, names are ipapython.services.wellknownservices +# backup_and_replace_hostname -- platform-specific way to set hostname and make it persistent over reboots +# restore_context -- platform-sepcific way to restore security context, if applicable +__all__ = ['authconfig', 'service', 'knownservices', 'backup_and_replace_hostname', 'restore_context'] -def service_stop(service_name, instance_name="", capture_output=True): - ipautil.run(["/sbin/service", service_name, "stop", instance_name], - capture_output=capture_output) +class RedHatService(ipaservices.PlatformService): + def stop(self, instance_name="", capture_output=True): + ipautil.run(["/sbin/service", self.service_name, "stop", instance_name], capture_output=capture_output) -def service_start(service_name, instance_name="", capture_output=True): - ipautil.run(["/sbin/service", service_name, "start", instance_name], - capture_output=capture_output) + def start(self, instance_name="", capture_output=True): + ipautil.run(["/sbin/service", self.service_name, "start", instance_name], capture_output=capture_output) -def service_restart(service_name, instance_name="", capture_output=True): - ipautil.run(["/sbin/service", service_name, "restart", instance_name], - capture_output=capture_output) + def restart(self, instance_name="", capture_output=True): + ipautil.run(["/sbin/service", self.service_name, "restart", instance_name], capture_output=capture_output) -def service_is_running(service_name, instance_name=""): - ret = True - try: - ipautil.run(["/sbin/service", service_name, "status", instance_name]) - except ipautil.CalledProcessError: - ret = False - return ret + def is_running(self, instance_name=""): + ret = True + try: + (sout,serr,rcode) = ipautil.run(["/sbin/service", self.service_name, "status", instance_name]) + if sout.find("is stopped") >= 0: + ret = False + except ipautil.CalledProcessError: + ret = False + return ret -def service_is_installed(service_name): - installed = True - try: - ipautil.run(["/sbin/service", service_name, "status"]) - except ipautil.CalledProcessError, e: - if e.returncode == 1: - # service is not installed or there is other serious issue - installed = False - return installed + def is_installed(self): + installed = True + try: + ipautil.run(["/sbin/service", self.service_name, "status"]) + except ipautil.CalledProcessError, e: + if e.returncode == 1: + # service is not installed or there is other serious issue + installed = False + return installed -def service_is_enabled(service_name): - (stdout, stderr, returncode) = ipautil.run(["/sbin/chkconfig", service_name], raiseonerr=False) - return (returncode == 0) + def is_enabled(self): + (stdout, stderr, returncode) = ipautil.run(["/sbin/chkconfig", self.service_name],raiseonerr=False) + return (returncode == 0) -def service_on(service_name): - ipautil.run(["/sbin/chkconfig", service_name, "on"]) + def enable(self): + ipautil.run(["/sbin/chkconfig", self.service_name, "on"]) -def service_off(service_name): - ipautil.run(["/sbin/chkconfig", service_name, "off"]) + def disable(self): + ipautil.run(["/sbin/chkconfig", self.service_name, "off"]) -def service_add(service_name): - ipautil.run(["/sbin/chkconfig", "--add", service_name]) + def install(self): + ipautil.run(["/sbin/chkconfig", "--add", self.service_name]) -def service_del(service_name): - ipautil.run(["/sbin/chkconfig", "--del", service_name]) + def remove(self): + ipautil.run(["/sbin/chkconfig", "--del", self.service_name]) -def restore_context(dirname): +def restore_context(filepath): """ - restore security context on the directory - SE Linux equivalent is /sbin/restorecon <dirname> + restore security context on the file path + SE Linux equivalent is /sbin/restorecon <filepath> """ - ipautil.run(["/sbin/restorecon", dirname]) + ipautil.run(["/sbin/restorecon", filepath]) -class RedHatAuthConfig(ipautil.AuthConfig): +class RedHatAuthConfig(ipaservices.AuthConfig): """ AuthConfig class implements system-independent interface to configure system authentication resources. In Red Hat-produced systems this is done with authconfig(8) utility. """ - S_SHADOW = "shadow" - S_MD5 = "md5" - S_NIS = "nis" - S_LDAP = "ldap" - S_SSSD = "sssd" - def __build_args(self): args = [] for (option, value) in self.parameters.items(): @@ -113,4 +116,58 @@ class RedHatAuthConfig(ipautil.AuthConfig): args = self.__build_args() ipautil.run(["/usr/sbin/authconfig"]+args) +def backup_and_replace_hostname(fstore, statestore, hostname): + network_filename = "/etc/sysconfig/network" + # Backup original /etc/sysconfig/network + fstore.backup_file(network_filename) + hostname_pattern = re.compile(''' +(^ + \s* + (?P<option> [^\#;]+?) + (\s*=\s*) + (?P<value> .+?)? + (\s*((\#|;).*)?)? +$)''', re.VERBOSE) + temp_filename = None + with tempfile.NamedTemporaryFile(delete=False) as new_config: + temp_filename = new_config.name + with open(network_filename, 'r') as f: + for line in f: + new_line = line + m = hostname_pattern.match(line) + if m: + option, value = m.group('option', 'value') + if option is not None and option == 'HOSTNAME': + if value is not None and hostname != value: + new_line = u"HOSTNAME=%s\n" % (hostname) + statestore.backup_state('network', 'hostname', value) + new_config.write(new_line) + new_config.flush() + # Make sure the resulting file is readable by others before installing it + os.fchmod(new_config.fileno(), stat.S_IRUSR | stat.S_IWUSR | stat.S_IRGRP | stat.S_IROTH) + os.fchown(new_config.fileno(), 0, 0) + + # At this point new_config is closed but not removed due to 'delete=False' above + # Now, install the temporary file as configuration and ensure old version is available as .orig + # While .orig file is not used during uninstall, it is left there for administrator. + ipautil.install_file(temp_filename, network_filename) + try: + ipautil.run(['/bin/hostname', hostname]) + except ipautil.CalledProcessError, e: + print >>sys.stderr, "Failed to set this machine hostname to %s (%s)." % (hostname, str(e)) + + # For SE Linux environments it is important to reset SE labels to the expected ones + try: + restore_context(network_filename) + except ipautil.CalledProcessError, e: + print >>sys.stderr, "Failed to set permissions for %s (%s)." % (network_filename, str(e)) + +class RedHatServices(ipaservices.KnownServices): + def __init__(self): + for s in ipaservices.wellknownservices: + self.__services__ += RedHatService(s) + authconfig = RedHatAuthConfig +service = RedHatService +knownservices = RedHatServices() + |