From 8aec2a4ad087f1561761bddf0d0c28070d14bec7 Mon Sep 17 00:00:00 2001
From: Stephen Fromm <sfromm@gmail.com>
Date: Wed, 30 May 2012 08:42:05 -0700
Subject: [PATCH] Update get_selinux_facts in setup module

This switches to using selinux library calls instead of parsing the
output of sestatus.  This fixes issue #428 where the output was slightly
different than expected on F17.  Tested against debian (non-selinux),
centos5, centos6, and fedora17.
---
 setup | 44 ++++++++++++++++++++++++--------------------
 1 file changed, 24 insertions(+), 20 deletions(-)

diff --git a/setup b/setup
index 6e6f0c3e761..f7b8a17c5d7 100755
--- a/setup
+++ b/setup
@@ -33,6 +33,12 @@ import subprocess
 import traceback
 import syslog
 
+try:
+    import selinux
+    HAVE_SELINUX=True
+except ImportError:
+    HAVE_SELINUX=False
+
 try:
     import json
 except ImportError:
@@ -62,6 +68,7 @@ FORM_FACTOR = [ "Unknown", "Other", "Unknown", "Desktop",
 # This is the fallback to handle unknowns or exceptions
 OSDIST_DICT = { '/etc/redhat-release': 'RedHat',
                 '/etc/vmware-release': 'VMwareESX' }
+SELINUX_MODE_DICT = { 1: 'enforcing', 0: 'permissive', -1: 'disabled' }
 
 def get_file_content(path):
     if os.path.exists(path) and os.access(path, os.R_OK):
@@ -268,27 +275,24 @@ def get_public_ssh_host_keys(facts):
         facts['ssh_host_key_rsa_public'] = rsa.split()[1]
 
 def get_selinux_facts(facts):
-    if os.path.exists("/usr/sbin/sestatus"):
-        cmd = subprocess.Popen("/usr/sbin/sestatus", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-        out, err = cmd.communicate()
-        if err == '':
-            facts['selinux'] = {}
-            list = out.split("\n")
-            status = re.search("(enabled|disabled)", list[0])
-            if status.group() == "enabled":
-                mode = re.search("(enforcing|disabled|permissive)", list[2])
-                config_mode = re.search("(enforcing|disabled|permissive)", list[3])
-                policyvers = re.search("\d+", list[4])
-                type = re.search("(targeted|strict|mls)", list[5])
-                facts['selinux']['status'] = status.group()
-                facts['selinux']['mode'] = mode.group()
-                facts['selinux']['config_mode'] = config_mode.group()
-                facts['selinux']['policyvers'] = policyvers.group()
-                facts['selinux']['type'] = type.group()
-            elif status.group() == "disabled":
-                facts['selinux']['status'] = status.group()            
-    else:
+    if not HAVE_SELINUX:
         facts['selinux'] = False
+        return
+    facts['selinux'] = {}
+    if not selinux.is_selinux_enabled():
+        facts['selinux']['status'] = 'disabled'
+    else:
+        facts['selinux']['status'] = 'enabled'
+        facts['selinux']['policyvers'] = selinux.security_policyvers()
+        (rc, configmode) = selinux.selinux_getenforcemode()
+        if rc == 0 and SELINUX_MODE_DICT.has_key(configmode):
+            facts['selinux']['config_mode'] = SELINUX_MODE_DICT[configmode]
+        mode = selinux.security_getenforce()
+        if SELINUX_MODE_DICT.has_key(mode):
+            facts['selinux']['mode'] = SELINUX_MODE_DICT[mode]
+        (rc, policytype) = selinux.selinux_getpolicytype()
+        if rc == 0:
+            facts['selinux']['type'] = policytype
 
 def get_service_facts(facts):
     get_public_ssh_host_keys(facts)