Hi,

The checks make sure that SELinux is:
  - installed and enabled (on server install)
  - installed and enabled OR not installed (on client install)

Please note that client installs with SELinux not installed are
allowed since freeipa-client package has no dependency on SELinux.
(any objections to this approach?)

The (unsupported) option --allow-no-selinux has been added. It can
used to bypass the checks.

Parts of platform-dependant code were refactored to use newly added
is_selinux_enabled() function.

https://fedorahosted.org/freeipa/ticket/3359

Tomas
>From f038bb7b79d5a048e9c9ae7fd7391edabb6ac3ac Mon Sep 17 00:00:00 2001
From: Tomas Babej <tba...@redhat.com>
Date: Thu, 24 Jan 2013 15:37:21 -0500
Subject: [PATCH] Add checks for SElinux in install scripts

The checks make sure that SELinux is:
  - installed and enabled (on server install)
  - installed and enabled OR not installed (on client install)

Please note that client installs with SELinux not installed are
allowed since freeipa-client package has no dependency on SELinux.

The (unsupported) option --allow-no-selinux has been added. It can
used to bypass the checks.

Parts of platform-dependant code were refactored to use newly added
is_selinux_enabled() function.

https://fedorahosted.org/freeipa/ticket/3359
---
 install/tools/ipa-server-install          | 11 +++++++
 ipa-client/ipa-install/ipa-client-install | 17 ++++++++++
 ipapython/platform/fedora16/__init__.py   |  3 +-
 ipapython/platform/fedora16/selinux.py    |  3 ++
 ipapython/platform/fedora18/__init__.py   |  3 +-
 ipapython/platform/redhat/__init__.py     | 53 +++++++++++++++++--------------
 ipapython/services.py.in                  |  7 ++++
 7 files changed, 72 insertions(+), 25 deletions(-)

diff --git a/install/tools/ipa-server-install b/install/tools/ipa-server-install
index 15591071b0983511394a2cba3d829e1b84fe328e..b5159e6ec14837cf9b51f740bd7f2f8a459e3c67 100755
--- a/install/tools/ipa-server-install
+++ b/install/tools/ipa-server-install
@@ -153,6 +153,8 @@ def parse_options():
                       help="do not configure OpenSSH client")
     basic_group.add_option("--no-sshd", dest="conf_sshd", default=True, action="store_false",
                       help="do not configure OpenSSH server")
+    basic_group.add_option("--allow-selinux-disabled", dest="selinux_disabled", action="store_true",
+                      default=False, help="allow installation with SELinux disabled (not supported)")
     basic_group.add_option("-d", "--debug", dest="debug", action="store_true",
                       default=False, help="print debugging information")
     basic_group.add_option("-U", "--unattended", dest="unattended", action="store_true",
@@ -639,6 +641,13 @@ def main():
             print "CA is not installed yet. To install with an external CA is a two-stage process.\nFirst run the installer with --external-ca."
             sys.exit(1)
 
+    is_selinux_disabled = not ipaservices.is_selinux_enabled()
+    if (not options.selinux_disabled) and is_selinux_disabled:
+        print("Installation with SELinux disabled is not supported. \n"
+              "Put SELinux either in permissive / enabled mode or use"
+              " --allow-selinux-disabled option.")
+        sys.exit(1)
+
     # This will override any settings passed in on the cmdline
     if ipautil.file_exists(ANSWER_CACHE):
         if options.dm_password is not None:
@@ -1126,6 +1135,8 @@ def main():
             args.append("--no-dns-sshfp")
         if options.trust_sshfp:
             args.append("--ssh-trust-dns")
+        if options.selinux_disabled:
+            args.append("--allow-selinux-disabled")
         if not options.conf_ssh:
             args.append("--no-ssh")
         if not options.conf_sshd:
diff --git a/ipa-client/ipa-install/ipa-client-install b/ipa-client/ipa-install/ipa-client-install
index aa8bc79341682a6987ad47f9331e8d09205608fb..4d0a3e51e42a40779e36109af0d2ad8ae5f77a83 100755
--- a/ipa-client/ipa-install/ipa-client-install
+++ b/ipa-client/ipa-install/ipa-client-install
@@ -128,6 +128,8 @@ def parse_options():
                       help="do not automatically create DNS SSHFP records")
     basic_group.add_option("--noac", dest="no_ac", default=False, action="store_true",
                       help="do not use Authconfig to modify the nsswitch.conf and PAM configuration")
+    basic_group.add_option("--allow-selinux-disabled", dest="selinux_disabled", action="store_true",
+                      default=False, help="allow installation with SELinux disabled (not supported)")
     basic_group.add_option("-f", "--force", dest="force", action="store_true",
                       default=False, help="force setting of LDAP/Kerberos conf")
     basic_group.add_option("-d", "--debug", dest="debug", action="store_true",
@@ -2318,7 +2320,9 @@ 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)
@@ -2342,6 +2346,19 @@ def main():
             "using 'ipa-client-install --uninstall'.")
         return CLIENT_ALREADY_CONFIGURED
 
+    # We want to allow clients with no SELinux installed, therefore use
+    # is_selinux_enabled with allow_not_installed flag set to true
+    is_selinux_disabled = not ipaservices.is_selinux_enabled(
+                                  allow_not_installed=True)
+
+    if (not options.selinux_disabled) and is_selinux_disabled:
+
+        root_logger.error("Installation with SELinux disabled is not"
+                          " supported.")
+        root_logger.info("Put SELinux either in permissive/enabled mode or use"
+                         " --allow-selinux-disabled option.")
+        return CLIENT_INSTALL_ERROR
+
     rval = install(options, env, fstore, statestore)
     if rval == CLIENT_INSTALL_ERROR:
         if options.force:
diff --git a/ipapython/platform/fedora16/__init__.py b/ipapython/platform/fedora16/__init__.py
index 26a6afd286f83f7c2781f1edf3e80fec8ebff06e..36a1baa67bf692678cdc1f48f23a801557086ab3 100644
--- a/ipapython/platform/fedora16/__init__.py
+++ b/ipapython/platform/fedora16/__init__.py
@@ -38,7 +38,7 @@ from ipapython.platform.fedora16.service import f16_service, Fedora16Services
 #                         and restorecon is installed.
 __all__ = ['authconfig', 'service', 'knownservices',
     'backup_and_replace_hostname', 'restore_context', 'check_selinux_status',
-    'restore_network_configuration', 'timedate_services']
+    'restore_network_configuration', 'timedate_services','is_selinux_enabled']
 
 # Just copy a referential list of timedate services
 timedate_services = list(base.timedate_services)
@@ -49,4 +49,5 @@ knownservices = Fedora16Services()
 backup_and_replace_hostname = redhat.backup_and_replace_hostname
 restore_context = selinux.restore_context
 check_selinux_status = selinux.check_selinux_status
+is_selinux_enabled = selinux.is_selinux_enabled
 restore_network_configuration = redhat.restore_network_configuration
diff --git a/ipapython/platform/fedora16/selinux.py b/ipapython/platform/fedora16/selinux.py
index cf71a38e43355420b5ff7fbedbfea6e9e82c2d1c..70ac9fbbaf694937197c06b17110069df17fea14 100644
--- a/ipapython/platform/fedora16/selinux.py
+++ b/ipapython/platform/fedora16/selinux.py
@@ -24,3 +24,6 @@ def restore_context(filepath, restorecon='/usr/sbin/restorecon'):
 
 def check_selinux_status(restorecon='/usr/sbin/restorecon'):
     return redhat.check_selinux_status(restorecon)
+
+def is_selinux_enabled(allow_not_installed=False):
+    return redhat.is_selinux_enabled(allow_not_installed=allow_not_installed)
diff --git a/ipapython/platform/fedora18/__init__.py b/ipapython/platform/fedora18/__init__.py
index d12bdcad5eb53881db5fe94cef97f2fafe2c6442..09f8207ec72906e41a125b3a1037c5f2397626e1 100644
--- a/ipapython/platform/fedora18/__init__.py
+++ b/ipapython/platform/fedora18/__init__.py
@@ -44,7 +44,7 @@ from ipapython.platform import fedora16, base
 #                         and restorecon is installed.
 __all__ = ['authconfig', 'service', 'knownservices',
     'backup_and_replace_hostname', 'restore_context', 'check_selinux_status',
-    'restore_network_configuration', 'timedate_services']
+    'restore_network_configuration', 'timedate_services','is_selinux_enabled']
 
 # Just copy a referential list of timedate services
 timedate_services = list(base.timedate_services)
@@ -111,3 +111,4 @@ service = fedora16.service
 knownservices = fedora16.knownservices
 restore_context = fedora16.restore_context
 check_selinux_status = fedora16.check_selinux_status
+is_selinux_enabled = fedora16.is_selinux_enabled
diff --git a/ipapython/platform/redhat/__init__.py b/ipapython/platform/redhat/__init__.py
index f7680e7ec510d3a2fde4febc88be15fe8d9f98d5..135d3628ed9b908a88c30bd0e6f00d1fc3ff5cf0 100644
--- a/ipapython/platform/redhat/__init__.py
+++ b/ipapython/platform/redhat/__init__.py
@@ -48,7 +48,7 @@ from ipapython.platform.redhat.service import redhat_service, RedHatServices
 #                         and restorecon is installed.
 __all__ = ['authconfig', 'service', 'knownservices',
     'backup_and_replace_hostname', 'restore_context', 'check_selinux_status',
-    'restore_network_configuration', 'timedate_services']
+    'restore_network_configuration', 'timedate_services','is_selinux_enabled']
 
 # Just copy a referential list of timedate services
 timedate_services = list(base.timedate_services)
@@ -67,17 +67,8 @@ def restore_context(filepath, restorecon='/sbin/restorecon'):
 
     ipautil.run() will do the logging.
     """
-    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 (os.path.exists(restorecon)):
+    if is_selinux_enabled() and os.path.exists(restorecon):
         ipautil.run([restorecon, filepath], raiseonerr=False)
 
 def backup_and_replace_hostname(fstore, statestore, hostname):
@@ -114,18 +105,34 @@ def check_selinux_status(restorecon='/sbin/restorecon'):
     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)
+
+    if is_selinux_enabled() and 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)
+
+def is_selinux_enabled(allow_not_installed=False):
+    """"
+    Checks if SELinux is enabled.
+
+    If allow_not_installed is set to True, returns true if and only if SELinux
+    is installed and enabled.
+    With allow_not_installed set to False, returns true if and only if SELinux
+    is installed and enabled, or not installed at all.
+    """
+
+    if os.path.exists('/usr/sbin/selinuxenabled'):
+        (stdout, stderr, rc) = ipautil.run(['/usr/sbin/selinuxenabled'],
+                                           raiseonerr=False,
+                                           capture_output=False)
+    elif allow_not_installed:
+        # SELinux is not required on client installs
+        # Assume that we are on the client with no SELinux
+        return True
+    else:
+        return False
+
+    return (rc == 0)
 
 def restore_network_configuration(fstore, statestore):
     filepath = '/etc/sysconfig/network'
diff --git a/ipapython/services.py.in b/ipapython/services.py.in
index 16b62ca8508d4078e896cd1da6fd664f52a3930e..2cf7619337da2296ddba84ca94476ef2390688e6 100644
--- a/ipapython/services.py.in
+++ b/ipapython/services.py.in
@@ -51,6 +51,13 @@ backup_and_replace_hostname = backup_and_replace_hostname_default
 def check_selinux_status():
     return
 
+# Check if SELinux is installed and enabled (with allow_not_installed=False)
+# or installed and enabled OR not installed (with allow_not_installed=True)
+# Platforms that support SELinux should implement this function.
+# Defaults to passing the check
+def is_selinux_enabled(allow_not_installed=False):
+    return True
+
 from ipapython.platform.base import SVC_LIST_FILE
 def get_svc_list_file():
     return SVC_LIST_FILE
-- 
1.8.1

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

Reply via email to