summaryrefslogtreecommitdiffstats
path: root/ipapython
diff options
context:
space:
mode:
authorRob Crittenden <rcritten@redhat.com>2012-05-31 13:59:33 +0200
committerMartin Kosek <mkosek@redhat.com>2012-05-31 14:07:05 +0200
commit9e877585e213a9fccec8ff9b3dcb876b2ec65696 (patch)
treeea25cb0bb60302b5f2564685539ea1bdcd5b974a /ipapython
parent5b465811ce15e26d4c05c589601eebee1b9e984d (diff)
downloadfreeipa-9e877585e213a9fccec8ff9b3dcb876b2ec65696.tar.gz
freeipa-9e877585e213a9fccec8ff9b3dcb876b2ec65696.tar.xz
freeipa-9e877585e213a9fccec8ff9b3dcb876b2ec65696.zip
If SELinux is enabled ensure we also have restorecon.
We don't have a specific requires on the policycoreutils package. It gets pulled in as a dependency on the server anyway, but checking there is like a belt and suspenders. On the client we don't require SELinux at all. If SELinux is enabled however we need to set things up properly. This is provided by the policycoreutils package so fail if that isn't available. https://fedorahosted.org/freeipa/ticket/2368
Diffstat (limited to 'ipapython')
-rw-r--r--ipapython/platform/fedora16.py77
-rw-r--r--ipapython/platform/redhat.py54
-rw-r--r--ipapython/services.py.in14
3 files changed, 103 insertions, 42 deletions
diff --git a/ipapython/platform/fedora16.py b/ipapython/platform/fedora16.py
index 2d0ede99a..830771d83 100644
--- a/ipapython/platform/fedora16.py
+++ b/ipapython/platform/fedora16.py
@@ -22,25 +22,36 @@ from ipapython.platform import base, redhat, systemd
import os
# 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']
+# Everything else is made available through these symbols when they are
+# 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
+# check_selinux_status -- platform-specific way to see if SELinux is enabled
+# and restorecon is installed.
+__all__ = ['authconfig', 'service', 'knownservices', 'backup_and_replace_hostname', 'restore_context', 'check_selinux_status']
# For beginning just remap names to add .service
# As more services will migrate to systemd, unit names will deviate and
# mapping will be kept in this dictionary
system_units = dict(map(lambda x: (x, "%s.service" % (x)), base.wellknownservices))
-# Rewrite dirsrv and pki-cad services as they support instances via separate service generator
-# To make this working, one needs to have both foo@.service and foo.target -- the latter is used
-# when request should be coming for all instances (like stop). systemd, unfortunately, does not allow
-# to request action for all service instances at once if only foo@.service unit is available.
-# To add more, if any of those services need to be started/stopped automagically, one needs to manually
-# create symlinks in /etc/systemd/system/foo.target.wants/ (look into systemd.py's enable() code).
+# Rewrite dirsrv and pki-cad services as they support instances via separate
+# service generator. To make this working, one needs to have both foo@.servic
+# and foo.target -- the latter is used when request should be coming for
+# all instances (like stop). systemd, unfortunately, does not allow one
+# to request action for all service instances at once if only foo@.service
+# unit is available. To add more, if any of those services need to be
+# started/stopped automagically, one needs to manually create symlinks in
+# /etc/systemd/system/foo.target.wants/ (look into systemd.py's enable()
+# code).
system_units['dirsrv'] = 'dirsrv@.service'
# Our directory server instance for PKI is dirsrv@PKI-IPA.service
system_units['pkids'] = 'dirsrv@PKI-IPA.service'
@@ -53,30 +64,35 @@ class Fedora16Service(systemd.SystemdService):
service_name = system_units[service_name]
else:
if len(service_name.split('.')) == 1:
- # if service_name does not have a dot, it is not foo.service and not a foo.target
- # Thus, not correct service name for systemd, default to foo.service style then
+ # if service_name does not have a dot, it is not foo.service
+ # and not a foo.target. Thus, not correct service name for
+ # systemd, default to foo.service style then
service_name = "%s.service" % (service_name)
super(Fedora16Service, self).__init__(service_name)
# Special handling of directory server service
#
-# 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.
+# 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 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().
class Fedora16DirectoryService(Fedora16Service):
def enable(self, instance_name=""):
super(Fedora16DirectoryService, self).enable(instance_name)
dirsrv_systemd = "/etc/sysconfig/dirsrv.systemd"
if os.path.exists(dirsrv_systemd):
# We need to enable LimitNOFILE=8192 in the dirsrv@.service
- # Since 389-ds-base-1.2.10-0.8.a7 the configuration of the service parameters is performed
- # via /etc/sysconfig/dirsrv.systemd file which is imported by systemd into dirsrv@.service unit
+ # Since 389-ds-base-1.2.10-0.8.a7 the configuration of the
+ # service parameters is performed via
+ # /etc/sysconfig/dirsrv.systemd file which is imported by systemd
+ # into dirsrv@.service unit
replacevars = {'LimitNOFILE':'8192'}
ipautil.inifile_replace_variables(dirsrv_systemd, 'service', replacevars=replacevars)
- redhat.restore_context(dirsrv_systemd)
+ restore_context(dirsrv_systemd)
ipautil.run(["/bin/systemctl", "--system", "daemon-reload"],raiseonerr=False)
def restart(self, instance_name="", capture_output=True):
@@ -93,8 +109,9 @@ class Fedora16DirectoryService(Fedora16Service):
super(Fedora16DirectoryService, self).restart(instance_name, capture_output=capture_output)
# Enforce restart of IPA services when we do enable it
-# This gets around the fact that after ipa-server-install systemd thinks ipa.service is not yet started
-# but all services were actually started already.
+# This gets around the fact that after ipa-server-install systemd thinks
+# ipa.service is not yet started but all services were actually started
+# already.
class Fedora16IPAService(Fedora16Service):
def enable(self, instance_name=""):
super(Fedora16IPAService, self).enable(instance_name)
@@ -104,7 +121,8 @@ class Fedora16SSHService(Fedora16Service):
def get_config_dir(self, instance_name=""):
return '/etc/ssh'
-# Redirect directory server service through special sub-class due to its special handling of instances
+# Redirect directory server service through special sub-class due to its
+# special handling of instances
def f16_service(name):
if name == 'dirsrv':
return Fedora16DirectoryService(name)
@@ -122,8 +140,13 @@ class Fedora16Services(base.KnownServices):
# Call base class constructor. This will lock services to read-only
super(Fedora16Services, self).__init__(services)
+def restore_context(filepath, restorecon='/usr/sbin/restorecon'):
+ return redhat.restore_context(filepath, restorecon)
+
+def check_selinux_status(restorecon='/usr/sbin/restorecon'):
+ return redhat.check_selinux_status(restorecon)
+
authconfig = redhat.authconfig
service = f16_service
knownservices = Fedora16Services()
-restore_context = redhat.restore_context
backup_and_replace_hostname = redhat.backup_and_replace_hostname
diff --git a/ipapython/platform/redhat.py b/ipapython/platform/redhat.py
index bd79a5312..28a43e588 100644
--- a/ipapython/platform/redhat.py
+++ b/ipapython/platform/redhat.py
@@ -28,13 +28,22 @@ from ipapython import ipautil
from ipapython.platform import base
# 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']
+# Everything else is made available through these symbols when they are
+# 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
+# check_selinux_status -- platform-specific way to see if SELinux is enabled
+# and restorecon is installed.
+__all__ = ['authconfig', 'service', 'knownservices', 'backup_and_replace_hostname', 'restore_context', 'check_selinux_status']
class RedHatService(base.PlatformService):
def stop(self, instance_name="", capture_output=True):
@@ -130,10 +139,10 @@ authconfig = RedHatAuthConfig
service = redhat_service
knownservices = RedHatServices()
-def restore_context(filepath):
+def restore_context(filepath, restorecon='/sbin/restorecon'):
"""
restore security context on the file path
- SELinux equivalent is /sbin/restorecon <filepath>
+ SELinux equivalent is /path/to/restorecon <filepath>
restorecon's return values are not reliable so we have to
ignore them (BZ #739604).
@@ -150,8 +159,8 @@ def restore_context(filepath):
# selinuxenabled returns 1 if not enabled
return
- if (os.path.exists('/sbin/restorecon')):
- ipautil.run(["/sbin/restorecon", filepath], raiseonerr=False)
+ if (os.path.exists(restorecon)):
+ ipautil.run([restorecon, filepath], raiseonerr=False)
def backup_and_replace_hostname(fstore, statestore, hostname):
old_hostname = socket.gethostname()
@@ -168,3 +177,26 @@ def backup_and_replace_hostname(fstore, statestore, hostname):
statestore.backup_state('network', 'hostname', old_values['HOSTNAME'])
else:
statestore.backup_state('network', 'hostname', old_hostname)
+
+def check_selinux_status(restorecon='/sbin/restorecon'):
+ """
+ We don't have a specific package requirement for policycoreutils
+ which provides restorecon. This is because we don't require
+ SELinux on client installs. However if SELinux is enabled then
+ this package is required.
+
+ This function returns nothing but may raise a Runtime exception
+ if SELinux is enabled but restorecon is not available.
+ """
+ try:
+ if (os.path.exists('/usr/sbin/selinuxenabled')):
+ ipautil.run(["/usr/sbin/selinuxenabled"])
+ else:
+ # No selinuxenabled, no SELinux
+ return
+ except ipautil.CalledProcessError:
+ # selinuxenabled returns 1 if not enabled
+ return
+
+ if not os.path.exists(restorecon):
+ raise RuntimeError('SELinux is enabled but %s does not exist.\nInstall the policycoreutils package and start the installation again.' % restorecon)
diff --git a/ipapython/services.py.in b/ipapython/services.py.in
index 60bd8b531..8fe663763 100644
--- a/ipapython/services.py.in
+++ b/ipapython/services.py.in
@@ -32,8 +32,8 @@ def restore_context_default(filepath):
return
# Restore security context for a path
-# If the platform has security features where context is important, implement your own
-# version in platform services
+# If the platform has security features where context is important, implement
+# your own version in platform services
restore_context = restore_context_default
# Default implementation of backup and replace hostname that does nothing
@@ -41,8 +41,14 @@ def backup_and_replace_hostname_default(fstore, statestore, hostname):
return
# Backup and replace system's hostname
-# Since many platforms have their own way how to store system's hostname, this method must be
-# implemented in platform services
+# Since many platforms have their own way how to store system's hostname,
+# this method must be implemented in platform services
backup_and_replace_hostname = backup_and_replace_hostname_default
+# See if SELinux is enabled and /usr/sbin/restorecon is installed.
+# Default to a no-op. Those platforms that support SELinux should
+# implement this function.
+def check_selinux_status():
+ return
+
from ipapython.platform.SUPPORTED_PLATFORM import *