From 41fed6ef0ce0916d67a295c2801e3237d4b52417 Mon Sep 17 00:00:00 2001
From: Stephen Fromm <sfromm@gmail.com>
Date: Wed, 25 Apr 2012 09:39:11 -0700
Subject: [PATCH] Fix for issue #227

Older versions of selinux, such as that deployed on rhel5, only return a
context of user:role:type instead of user:role:type:level.  This detects
whether the tuple has three elements (old-style) or four.  If the
old-style, it keeps the secontext list at three elements.
---
 file | 40 +++++++++++++++++++++++++---------------
 1 file changed, 25 insertions(+), 15 deletions(-)

diff --git a/file b/file
index 402b79ba46a..91afb4b7469 100755
--- a/file
+++ b/file
@@ -87,6 +87,28 @@ def selinux_default_context(path, mode=0):
     debug("got default secontext=%s" % ret[1])
     return context
 
+def selinux_context(path):
+    context = [None, None, None, None]
+    if not HAVE_SELINUX:
+        return context
+    try:
+        ret = selinux.lgetfilecon(path)
+    except:
+        fail_json(path=path, msg='failed to retrieve selinux context')
+    if ret[0] == -1:
+        return context
+    context = ret[1].split(':')
+    debug("got current secontext=%s" % ret[1])
+    return context
+
+# Detect whether using selinux that is selevel-aware
+# FWIW, rhel5 is not selevel-aware.
+def selinux_has_selevel(path):
+    r = True
+    if len(selinux_context(path)) == 3:
+        r = False
+    return r
+
 # ===========================================
 
 argfile = sys.argv[1]
@@ -123,7 +145,9 @@ serole    = params.get('serole', None)
 setype    = params.get('setype', None)
 selevel   = params.get('serange', 's0')
 context   = params.get('context', None)
-secontext = [seuser, serole, setype, selevel]
+secontext = [seuser, serole, setype]
+if selinux_has_selevel(path):
+    secontext.append(selevel)
 
 if context is not None:
     if context != 'default':
@@ -157,20 +181,6 @@ def user_and_group(filename):
     debug("got user=%s and group=%s" % (user, group))
     return (user, group)
 
-def selinux_context(path):
-    context = [None, None, None, None]
-    if not HAVE_SELINUX:
-        return context
-    try:
-        ret = selinux.lgetfilecon(path)
-    except:
-        fail_json(path=path, msg='failed to retrieve selinux context')
-    if ret[0] == -1:
-        return context
-    context = ret[1].split(':')
-    debug("got current secontext=%s" % ret[1])
-    return context
-
 def set_context_if_different(path, context, changed):
     if not HAVE_SELINUX:
         return changed