Martin Kosek wrote:
On Fri, 2012-05-18 at 11:53 -0400, Rob Crittenden wrote:
We don't have an explicit requires on the policycoreutils package in the
client because SELinux is not required (just recommended).

SELinux can be enabled without this package so check for that condition
and don't allow installation if it is the case. The resulting install
will be rather broken.

Also check on the server when installing. This should never happen but
in theory it could do the server install then fail in the client because
of this.

rob

This works fine. I am just thinking if we should not rather use paths
in /usr/ for the check if a binary exists, i.e. check
for /usr/sbin/restorecon instead of /sbin/restorecon on Fedora.

If we don't do this we need to be sure that the /sbin ->  /usr/sbin
symlink created during UsrMove will stay on the system.

Martin


Ok, that makes sense. Updated patch.

rob
>From de6b5bf3aa13ea9f0540faea9860b78ac3c7ddfe Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcrit...@redhat.com>
Date: Thu, 24 May 2012 11:24:12 -0400
Subject: [PATCH] If SELinux is enabled ensure we also have
 /usr/sbin/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 /usr/sbin/restorecon 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
---
 install/tools/ipa-replica-install         |    1 +
 install/tools/ipa-server-install          |    2 ++
 ipa-client/ipa-install/ipa-client-install |    1 +
 ipapython/platform/fedora16.py            |   23 +++++++++----
 ipapython/platform/redhat.py              |   52 +++++++++++++++++++++++------
 ipapython/services.py.in                  |   14 +++++---
 6 files changed, 72 insertions(+), 21 deletions(-)

diff --git a/install/tools/ipa-replica-install b/install/tools/ipa-replica-install
index 7cfe7627e2d0b85d3584ab757c3ca5b78c51b801..f0c67e008a3c3ba5a934594f3c6100113f93ff43 100755
--- a/install/tools/ipa-replica-install
+++ b/install/tools/ipa-replica-install
@@ -276,6 +276,7 @@ def check_bind():
         sys.exit(1)
 
 def main():
+    ipaservices.check_selinux_status()
     safe_options, options, filename = parse_options()
     standard_logging_setup("/var/log/ipareplica-install.log", debug=options.debug)
     root_logger.debug('%s was invoked with argument "%s" and options: %s' % (sys.argv[0], filename, safe_options))
diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index 2f06a9e879902eb1c2ac340757fcd1762959fe30..e7b82364a550bfbc2f818b5e6f353715237a9769 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -539,6 +539,8 @@ def main():
     if os.getegid() != 0:
         sys.exit("Must be root to set up server")
 
+    ipaservices.check_selinux_status()
+
     signal.signal(signal.SIGTERM, signal_handler)
     signal.signal(signal.SIGINT, signal_handler)
 
diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index dce363a356d1e60712a2da813d78ae42a84ec92b..ae79a174cbc05c4b9f9f49412fece67a844b22fe 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -1534,6 +1534,7 @@ def main():
 
     if not os.getegid() == 0:
         sys.exit("\nYou must be root to run ipa-client-install.\n")
+    ipaservices.check_selinux_status()
     logging_setup(options)
     root_logger.debug('%s was invoked with options: %s' % (sys.argv[0], safe_options))
     root_logger.debug("missing options might be asked for interactively later\n")
diff --git a/ipapython/platform/fedora16.py b/ipapython/platform/fedora16.py
index 4b662b3b86d4af9f39bae1dcf6268668da5c9013..2000a4ad230b0fbe44aa80efeec6880831a52fac 100644
--- a/ipapython/platform/fedora16.py
+++ b/ipapython/platform/fedora16.py
@@ -22,13 +22,21 @@ 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
@@ -127,3 +135,4 @@ service = f16_service
 knownservices = Fedora16Services()
 restore_context = redhat.restore_context
 backup_and_replace_hostname = redhat.backup_and_replace_hostname
+check_selinux_status = redhat.check_selinux_status
diff --git a/ipapython/platform/redhat.py b/ipapython/platform/redhat.py
index 42819cb756997da4f39c52f6829069a53dc28679..8424b5575db9f4641e7645f2260bfaf200bcc5bb 100644
--- a/ipapython/platform/redhat.py
+++ b/ipapython/platform/redhat.py
@@ -29,13 +29,22 @@ from ipapython.platform import base
 from ipalib import api
 
 # 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 __wait_for_open_ports(self, instance_name=""):
@@ -151,7 +160,7 @@ knownservices = RedHatServices()
 def restore_context(filepath):
     """
     restore security context on the file path
-    SELinux equivalent is /sbin/restorecon <filepath>
+    SELinux equivalent is /usr/sbin/restorecon <filepath>
 
     restorecon's return values are not reliable so we have to
     ignore them (BZ #739604).
@@ -168,8 +177,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('/usr/sbin/restorecon')):
+        ipautil.run(["/usr/sbin/restorecon", filepath], raiseonerr=False)
 
 def backup_and_replace_hostname(fstore, statestore, hostname):
     old_hostname = socket.gethostname()
@@ -186,3 +195,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():
+    """
+    We don't have a specific package requirement for policycoreutils
+    which provides /usr/sbin/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 /usr/sbin/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('/usr/sbin/restorecon'):
+        raise RuntimeError('SELinux is enabled but /usr/sbin/restorecon does not exist.\nInstall the policycoreutils package and start the installation again.')
diff --git a/ipapython/services.py.in b/ipapython/services.py.in
index 60bd8b53194db0806dc5b35cbb75886f1e720aba..8fe663763d06d89c62604086a3eea7a9a983f49d 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 *
-- 
1.7.10.1

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to