On 07/30/2009 05:24 PM, Pradeep Kilambi wrote:


Also few suggestions looking through the behaviour after fixing that one
line:

* If we set an invalid content for a file,  setfilecon will return a -1
and leave the default context. I would check if the return code of
setfilecon is -1 and log that info so user knows that the context dint
apply in failure case.

* Secondly in the fileDetails.do page, below the selinux Content entry
area, I would add a tip to help users know the format of the input that
field takes.

Thanks,
~ Prad


Hello,

Thanks for taking a look at this! Suggestions applied. Attached are two patches - the full one from master, and an 'update' diff from the previously sent patch.

Thanks again,

Joshua Roys
diff --git a/backend/server/action/configfiles.py 
b/backend/server/action/configfiles.py
index 746a194..db91ca7 100644
--- a/backend/server/action/configfiles.py
+++ b/backend/server/action/configfiles.py
@@ -122,7 +122,8 @@ _query_get_files = rhnSQL.Statement("""
            ci.username,
            ci.groupname,
            ci.filemode,
-          cft.label
+          cft.label,
+          ci.selinux_ctx
       from 
            rhnConfigFileState cfs,
            rhnConfigContent ccont,
diff --git a/backend/server/configFilesHandler.py 
b/backend/server/configFilesHandler.py
index 2ac83b8..996d221 100644
--- a/backend/server/configFilesHandler.py
+++ b/backend/server/configFilesHandler.py
@@ -499,4 +499,5 @@ def format_file_results(row, server=None):
         'filemode'      : row['filemode'],
         'encoding'      : encoding,
         'filetype'      : row['label'],
+        'selinux_ctx'   : row['selinux_ctx'] or '',
     }
diff --git a/backend/server/handlers/config/rhn_config_management.py 
b/backend/server/handlers/config/rhn_config_management.py
index 4b16fa9..47834bd 100644
--- a/backend/server/handlers/config/rhn_config_management.py
+++ b/backend/server/handlers/config/rhn_config_management.py
@@ -169,7 +169,8 @@ class 
ConfigManagement(configFilesHandler.ConfigFilesHandler):
                ci.groupname,
                ci.filemode,
               cft.label,
-              cct.priority
+              cct.priority,
+              ci.selinux_ctx
           from rhnConfigChannel cc,
                rhnConfigInfo ci,
                rhnConfigRevision cr,
diff --git a/backend/server/handlers/config_mgmt/rhn_config_management.py 
b/backend/server/handlers/config_mgmt/rhn_config_management.py
index ff2046f..90a9983 100644
--- a/backend/server/handlers/config_mgmt/rhn_config_management.py
+++ b/backend/server/handlers/config_mgmt/rhn_config_management.py
@@ -260,7 +260,8 @@ class 
ConfigManagement(configFilesHandler.ConfigFilesHandler):
                ci.username,
                ci.groupname,
                ci.filemode,
-              cft.label
+              cft.label,
+              ci.selinux_ctx
           from rhnConfigChannel cc,
                rhnConfigInfo ci,
                rhnConfigRevision cr,
@@ -289,7 +290,8 @@ class 
ConfigManagement(configFilesHandler.ConfigFilesHandler):
                ci.username,
                ci.groupname,
                ci.filemode,
-              cft.label
+              cft.label,
+              ci.selinux_ctx
           from rhnConfigChannel cc,
                rhnConfigInfo ci,
                rhnConfigRevision cr,
diff --git a/client/tools/rhncfg/config_common/transactions.py 
b/client/tools/rhncfg/config_common/transactions.py
index 9f87700..cdd7ac0 100644
--- a/client/tools/rhncfg/config_common/transactions.py
+++ b/client/tools/rhncfg/config_common/transactions.py
@@ -25,6 +25,7 @@ import string
 
 from config_common import file_utils, utils, cfg_exceptions
 from config_common.rhn_log import log_debug
+from selinux import setfilecon
 
 class TargetNotFile(Exception): pass
 class DuplicateDeployment(Exception): pass
@@ -102,7 +103,7 @@ class DeployTransaction:
     def deploy_callback(self, cb):
         self.deployment_cb = cb
 
-    def _chown_chmod(self, temp_file_path, dest_path, file_info, 
strict_ownership=1):
+    def _chown_chmod_chcon(self, temp_file_path, dest_path, file_info, 
strict_ownership=1):
         uid = file_info.get('uid')
         if uid is None:
             if file_info.has_key('username'):            
@@ -142,6 +143,13 @@ class DeployTransaction:
            mode = string.atoi(str(mode), 8)
             os.chmod(temp_file_path, mode)
 
+            if file_info.has_key('selinux_ctx'):
+                sectx = file_info.get('selinux_ctx')
+                if sectx is not None:
+                    log_debug(1, "selinux context: " + sectx);
+                    if setfilecon(temp_file_path, sectx) < 0:
+                        raise Exception("failed to set selinux context on %s" 
% dest_path)
+
         except OSError, e:
             if e.errno == errno.EPERM and not strict_ownership:
                 sys.stderr.write("cannonical file ownership and permissions 
lost on %s\n" % dest_path)
@@ -170,7 +178,7 @@ class DeployTransaction:
        if file_info.get('filetype') == 'directory':
                self.dirs.append(file_info)
        else:
-               self._chown_chmod(processed_file_path, dest_path, file_info, 
strict_ownership=strict_ownership)
+               self._chown_chmod_chcon(processed_file_path, dest_path, 
file_info, strict_ownership=strict_ownership)
 
                if self.newtemp_by_path.has_key(dest_path):
                    raise DuplicateDeployment("Error:  %s already added to 
transaction" % dest_path)
@@ -221,7 +229,7 @@ class DeployTransaction:
        #revert the owner/perms of any directories that we changed
         for d, val in self.changed_dir_info.items():
             log_debug(6, "reverting owner and perms of %s" % d)
-            self._chown_chmod(d, d, val)
+            self._chown_chmod_chcon(d, d, val)
             log_debug(9, "directory reverted")
 
        #remove any directories created by either mkdir_p or in the deploy
@@ -271,12 +279,12 @@ class DeployTransaction:
                         entry["gid"] = s[5]
                         self.changed_dir_info[dirname] = entry
                         log_debug(3, "directory found, chowning and chmoding 
to %s as needed: %s" % (dirmode, dirname))
-                        self._chown_chmod(dirname, dirname, directory)
+                        self._chown_chmod_chcon(dirname, dirname, directory)
                     else:
                         log_debug(3, "directory not found, creating: %s" % 
dirname)
                        dirs_created = utils.mkdir_p(dirname)
                         self.new_dirs.extend(dirs_created)
-                        self._chown_chmod(dirname, dirname, directory)
+                        self._chown_chmod_chcon(dirname, dirname, directory)
                     if self.deployment_cb:
                         self.deployment_cb(dirname)
 
@@ -315,7 +323,7 @@ class DeployTransaction:
                 self.new_dirs.extend(temp_new_dirs or [])
                 
                 # properly chown and chmod it
-                self._chown_chmod(self.newtemp_by_path[path], path, dep_file)
+                self._chown_chmod_chcon(self.newtemp_by_path[path], path, 
dep_file)
                 log_debug(9, "tempfile written:  %s" % 
self.newtemp_by_path[path])
 
 
diff --git a/client/tools/rhncfg/rhncfg.spec b/client/tools/rhncfg/rhncfg.spec
index 8fd9b84..c1162ea 100644
--- a/client/tools/rhncfg/rhncfg.spec
+++ b/client/tools/rhncfg/rhncfg.spec
@@ -14,6 +14,7 @@ BuildRoot: 
%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildArch: noarch
 BuildRequires: docbook-utils
 BuildRequires: python
+Requires: libselinux-python
 Requires: python
 Requires: rhnlib
 Provides: rhn-config-action = %{version}
diff --git 
a/java/code/src/com/redhat/rhn/common/db/datasource/xml/config_queries.xml 
b/java/code/src/com/redhat/rhn/common/db/datasource/xml/config_queries.xml
index 84f43dc..dc5c208 100644
--- a/java/code/src/com/redhat/rhn/common/db/datasource/xml/config_queries.xml
+++ b/java/code/src/com/redhat/rhn/common/db/datasource/xml/config_queries.xml
@@ -991,8 +991,8 @@ ORDER BY CCon.modified DESC
 </mode>
 
 <callable-mode name="lookup_config_info">
-  <query params="username_in, groupname_in, filemode_in">
-      {:info_id = call lookup_config_info( :username_in, :groupname_in, 
:filemode_in )}
+  <query params="username_in, groupname_in, filemode_in, selinuxCtx_in">
+      {:info_id = call lookup_config_info( :username_in, :groupname_in, 
:filemode_in, :selinuxCtx_in )}
   </query>
 </callable-mode>
 
diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.hbm.xml 
b/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.hbm.xml
index 9aaa100..8895581 100644
--- a/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.hbm.xml
+++ b/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.hbm.xml
@@ -17,6 +17,7 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                <property name="filemode" column="filemode" type="long" />
                <property name="created" column="created" type="timestamp" />
                <property name="modified" column="modified" type="timestamp" />
+               <property name="selinuxCtx" column="selinux_ctx" type="string" 
length="64" />
        </class>
        
        <query name="ConfigInfo.findWithoutId">
diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.java 
b/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.java
index fcef54f..ca12cfb 100644
--- a/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.java
+++ b/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.java
@@ -26,6 +26,7 @@ public class ConfigInfo extends BaseDomainHelper {
     private String username;
     private String groupname;
     private Long filemode;
+    private String selinuxCtx;
     
     /**
      * protected constructor
@@ -98,4 +99,20 @@ public class ConfigInfo extends BaseDomainHelper {
     public void setFilemode(Long filemodeIn) {
         this.filemode = filemodeIn;
     }
+
+    /**
+     * Getter for selinux context
+     * @return String to get
+    */
+    public String getSelinuxCtx() {
+        return this.selinuxCtx;
+    }
+
+    /**
+     * Setter for selinux context
+     * @param ctxIn to set
+    */
+    public void setSelinuxCtx(String ctxIn) {
+        this.selinuxCtx = ctxIn;
+    }
 }
diff --git 
a/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java 
b/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java
index 4eabe31..c20a891 100644
--- a/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java
+++ b/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java
@@ -294,13 +294,14 @@ public class ConfigurationFactory extends 
HibernateFactory {
             commit(file);
         }
         else {
-            //ConfigInfos have a unique constraint for their three data fields.
+            //ConfigInfos have a unique constraint for their four data fields.
             //The config info object associated with this revision may have 
been
             //changed, so we need to carefully not update the database record.
             ConfigInfo info = lookupOrInsertConfigInfo(
                     revision.getConfigInfo().getUsername(),
                     revision.getConfigInfo().getGroupname(),
-                    revision.getConfigInfo().getFilemode());
+                    revision.getConfigInfo().getFilemode(),
+                    revision.getConfigInfo().getSelinuxCtx());
             //if the object did not change, we now have two hibernate objects
             //with the same identifier.  Evict one so that hibernate doesn't 
get mad.
             getSession().evict(revision.getConfigInfo());
@@ -456,8 +457,8 @@ public class ConfigurationFactory extends HibernateFactory {
     }
 
     /**
-     * Return a <code>ConfigInfo</code> for the username, groupname, and
-     * file mode given. If no corresponding entry exists yet in the database, 
one will be
+     * Return a <code>ConfigInfo</code> from the username, groupname, file 
mode, and
+     * selinux context. If no corresponding entry exists yet in the database, 
one will be
      * created.
      * 
      * Uses the stored procedure <code>lookup_config_info</code> to get the id 
of the
@@ -475,11 +476,12 @@ public class ConfigurationFactory extends 
HibernateFactory {
      * @param username The linux username associated with a file
      * @param groupname The linux groupname associated with a file
      * @param filemode The three digit file mode (ex: 655)
+     * @param selinuxCtx The SELinux context
      * @return The ConfigInfo found or inserted.
      */
     public static ConfigInfo lookupOrInsertConfigInfo(String username,
-            String groupname, Long filemode) {
-        Long id = lookupConfigInfo(username, groupname, filemode);
+            String groupname, Long filemode, String selinuxCtx) {
+        Long id = lookupConfigInfo(username, groupname, filemode, selinuxCtx);
         return lookupConfigInfoById(id);
     }
     
@@ -489,9 +491,11 @@ public class ConfigurationFactory extends HibernateFactory 
{
      * @param user The linux username associated with a file
      * @param group The linux groupname associated with a file
      * @param filemode The three digit file mode (ex: 655)
+     * @param selinuxCtx The SELinux context
      * @return The id of the found config info
      */
-    private static Long lookupConfigInfo(String user, String group, Long 
filemode) {
+    private static Long lookupConfigInfo(String user, String group,
+            Long filemode, String selinuxCtx) {
         CallableMode m = ModeFactory.getCallableMode("config_queries",
             "lookup_config_info");
 
@@ -501,6 +505,7 @@ public class ConfigurationFactory extends HibernateFactory {
         inParams.put("username_in", user);
         inParams.put("groupname_in", group);
         inParams.put("filemode_in", filemode);
+        inParams.put("selinuxCtx_in", selinuxCtx);
         outParams.put("info_id", new Integer(Types.NUMERIC));
 
         Map out = m.execute(inParams, outParams);
diff --git 
a/java/code/src/com/redhat/rhn/domain/config/test/ConfigurationFactoryTest.java 
b/java/code/src/com/redhat/rhn/domain/config/test/ConfigurationFactoryTest.java
index 3f35c2b..1afdefe 100644
--- 
a/java/code/src/com/redhat/rhn/domain/config/test/ConfigurationFactoryTest.java
+++ 
b/java/code/src/com/redhat/rhn/domain/config/test/ConfigurationFactoryTest.java
@@ -151,9 +151,9 @@ public class ConfigurationFactoryTest extends 
RhnBaseTestCase {
         //one problem is that looking up the same thing must be done in such a 
way that
         //hibernate doesn't yell about it.
         ConfigInfo info1 = 
ConfigurationFactory.lookupOrInsertConfigInfo("testman",
-                "testgroup", new Long(665));
+                "testgroup", new Long(665), "");
         ConfigInfo info2 = 
ConfigurationFactory.lookupOrInsertConfigInfo("testman",
-                "testgroup", new Long(665));
+                "testgroup", new Long(665), "");
         assertNotNull(info1.getId());
         assertNotNull(info2.getId());
         assertEquals(info1.getId(), info2.getId());
diff --git 
a/java/code/src/com/redhat/rhn/frontend/action/configuration/ConfigFileForm.java
 
b/java/code/src/com/redhat/rhn/frontend/action/configuration/ConfigFileForm.java
index 22440ab..d716da4 100644
--- 
a/java/code/src/com/redhat/rhn/frontend/action/configuration/ConfigFileForm.java
+++ 
b/java/code/src/com/redhat/rhn/frontend/action/configuration/ConfigFileForm.java
@@ -57,6 +57,7 @@ public class ConfigFileForm extends ScrubbingDynaActionForm {
     public static final String REV_UID          = "cffUid";
     public static final String REV_GID          = "cffGid";
     public static final String REV_PERMS        = "cffPermissions";
+    public static final String REV_SELINUX_CTX  = "cffSELinuxCtx";
     public static final String REV_MACROSTART   = "cffMacroStart";
     public static final String REV_MACROEND     = "cffMacroEnd";
     public static final String REV_CONTENTS     = "contents"; //cffContent
@@ -158,6 +159,7 @@ public class ConfigFileForm extends ScrubbingDynaActionForm 
{
         Long mode = cr.getConfigInfo().getFilemode();
         String modeStr = new DecimalFormat("000").format(mode.longValue());
         set(ConfigFileForm.REV_PERMS, modeStr);
+        set(ConfigFileForm.REV_SELINUX_CTX, 
cr.getConfigInfo().getSelinuxCtx());
         set(ConfigFileForm.REV_UID, cr.getConfigInfo().getUsername());
         set(ConfigFileForm.REV_GID, cr.getConfigInfo().getGroupname());
         set(ConfigFileForm.REV_BINARY, new 
Boolean(cr.getConfigContent().isBinary()));
@@ -310,6 +312,7 @@ public class ConfigFileForm extends ScrubbingDynaActionForm 
{
         data.setGroup(getString(REV_GID));
         data.setOwner(getString(REV_UID));
         data.setPermissions(getString(REV_PERMS));
+        data.setSelinuxCtx(getString(REV_SELINUX_CTX));
         data.setType(extractFileType());
         return data;
     }
diff --git 
a/java/code/src/com/redhat/rhn/frontend/action/configuration/validation/configFileForm.xsd
 
b/java/code/src/com/redhat/rhn/frontend/action/configuration/validation/configFileForm.xsd
index 3732ee8..c2c6eba 100644
--- 
a/java/code/src/com/redhat/rhn/frontend/action/configuration/validation/configFileForm.xsd
+++ 
b/java/code/src/com/redhat/rhn/frontend/action/configuration/validation/configFileForm.xsd
@@ -20,6 +20,12 @@
                        <maxLength value="4" />
                </simpleType>
        </attribute>
+       <attribute name="cffSELinuxCtx">
+               <simpleType baseType="string">
+                       <minLength value="0" />
+                       <maxLength value="64" />
+               </simpleType>
+       </attribute>
        <attribute name="cffMacroStart">
                <simpleType baseType="string">
                        <minLength value="1" />
diff --git 
a/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml 
b/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml
index af98b30..4fe49b1 100644
--- a/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml
+++ b/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml
@@ -13921,7 +13921,12 @@ centrally-managed configuration channel, {2}; below is 
a list of systems you may
                <context 
context-type="sourcefile">/rhn/configuration/FileDetails.do</context>
        </context-group>
        </trans-unit>
-
+       <trans-unit id="filedetails.jsp.tip.selinux">
+<source>&lt;strong&gt;Tip:&lt;/strong&gt; Enter SELinux context like: 
user_u:role_r:type_t:s0-s15:c0.c1024 (Note: you don't have to enter all 
parts)</source>
+       <context-group name="ctx">
+               <context 
context-type="sourcefile">/rhn/configuration/FileDetails.do</context>
+       </context-group>
+       </trans-unit>
                <!-- form error messages -->
        <trans-unit id="config-file-form.error.user-invalid">
 <source>User must be a valid Linux user name or user id, of 32 characters or 
less.</source>
diff --git 
a/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/ConfigChannelHandler.java
 
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/ConfigChannelHandler.java
index df4416e..2ac091e 100644
--- 
a/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/ConfigChannelHandler.java
+++ 
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/ConfigChannelHandler.java
@@ -265,6 +265,7 @@ public class ConfigChannelHandler extends BaseHandler {
         validKeys.add("owner");
         validKeys.add("group");
         validKeys.add("permissions");
+        validKeys.add("selinux_ctx");
         validKeys.add("macro-start-delimiter");
         validKeys.add("macro-end-delimiter");
         validateMap(validKeys, data);
diff --git 
a/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/XmlRpcConfigChannelHelper.java
 
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/XmlRpcConfigChannelHelper.java
index 4604b2d..df3d61c 100644
--- 
a/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/XmlRpcConfigChannelHelper.java
+++ 
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/XmlRpcConfigChannelHelper.java
@@ -139,6 +139,7 @@ public class XmlRpcConfigChannelHelper {
         form.setOwner((String)data.get(ConfigRevisionSerializer.OWNER));
         form.setGroup((String)data.get(ConfigRevisionSerializer.GROUP));
         
form.setPermissions((String)data.get(ConfigRevisionSerializer.PERMISSIONS));
+        
form.setSelinuxCtx((String)data.get(ConfigRevisionSerializer.SELINUX_CTX));
 
         ConfigFileBuilder helper = ConfigFileBuilder.getInstance();
         try {
diff --git 
a/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/ConfigRevisionSerializer.java
 
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/ConfigRevisionSerializer.java
index 4786027..d8b755e 100644
--- 
a/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/ConfigRevisionSerializer.java
+++ 
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/ConfigRevisionSerializer.java
@@ -62,6 +62,7 @@ public class ConfigRevisionSerializer implements 
XmlRpcCustomSerializer {
     public static final String PATH = "path";
     public static final String OWNER = "owner";
     public static final String GROUP = "group";
+    public static final String SELINUX_CTX = "selinux_ctx";
     public static final String PERMISSIONS = "permissions";
     public static final String PERMISSIONS_MODE = "permissions_mode";
     public static final String MACRO_START = "macro-start-delimiter";
@@ -101,6 +102,7 @@ public class ConfigRevisionSerializer implements 
XmlRpcCustomSerializer {
         helper.add("revision", rev.getRevision());
         helper.add("creation", rev.getCreated());
         helper.add("modified", rev.getModified());
+        helper.add(SELINUX_CTX, rev.getConfigInfo().getSelinuxCtx());
         helper.add(OWNER, rev.getConfigInfo().getUsername());
         helper.add(GROUP, rev.getConfigInfo().getGroupname());
         helper.add(PERMISSIONS, rev.getConfigInfo().getFilemode());
diff --git 
a/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/config/ServerConfigHandler.java
 
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/config/ServerConfigHandler.java
index 364dc09..b5dcab0 100644
--- 
a/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/config/ServerConfigHandler.java
+++ 
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/system/config/ServerConfigHandler.java
@@ -165,6 +165,7 @@ public class ServerConfigHandler extends BaseHandler {
         validKeys.add("owner");
         validKeys.add("group");
         validKeys.add("permissions");
+        validKeys.add("selinux_ctx");
         validKeys.add("macro-start-delimiter");
         validKeys.add("macro-end-delimiter");
         validateMap(validKeys, data);
diff --git 
a/java/code/src/com/redhat/rhn/manager/configuration/file/ConfigFileData.java 
b/java/code/src/com/redhat/rhn/manager/configuration/file/ConfigFileData.java
index 102e986..d414f1e 100644
--- 
a/java/code/src/com/redhat/rhn/manager/configuration/file/ConfigFileData.java
+++ 
b/java/code/src/com/redhat/rhn/manager/configuration/file/ConfigFileData.java
@@ -49,6 +49,7 @@ public abstract class ConfigFileData {
     private String owner;
     private String group;
     private String permissions;
+    private String selinuxCtx;
     private String macroStart;
     private String macroEnd;
     
@@ -71,6 +72,7 @@ public abstract class ConfigFileData {
         setPermissions("644");
         setOwner("root");
         setGroup("root");
+        setSelinuxCtx("");
         setType(ConfigFileType.file());
         setMacroStart(DEFAULT_MACRO_START);
         setMacroEnd(DEFAULT_MACRO_END);
@@ -131,6 +133,20 @@ public abstract class ConfigFileData {
     public void setPermissions(String perms) {
         this.permissions = perms;
     }
+
+    /**
+     * @return the SELinux context
+     */
+    public String getSelinuxCtx() {
+        return selinuxCtx;
+    }
+
+    /**
+     * @param context the SELinux context to set
+     */
+    public void setSelinuxCtx(String context) {
+        this.selinuxCtx = context;
+    }
     
     /**
      * @return the macroStart
@@ -188,7 +204,8 @@ public abstract class ConfigFileData {
     public ConfigInfo extractInfo() {
         ConfigInfo info = ConfigurationFactory.lookupOrInsertConfigInfo(
                             getOwner(), getGroup(), 
-                            Long.valueOf(getPermissions()));
+                            Long.valueOf(getPermissions()),
+                            getSelinuxCtx());
         return info;
     }    
     
@@ -232,6 +249,17 @@ public abstract class ConfigFileData {
         if (!getPermissions().matches("^[0-7][0-7][0-7][0-7]?$")) {
             msgs.addError(error("mode-invalid"));
         }
+
+        // Validate selinux context
+        if (!getSelinuxCtx().matches(
+                 // \\w is [a-zA-Z_0-9], or [_[:alnum:]]
+                 "^\\w*" + // user
+                "(:\\w*" + // role
+                "(:\\w*" + // type
+                "(:\\w*(\\-\\w+)?" + // sensitivity
+                "(:\\w*(\\.\\w+))?)?)?)?$")) { // category
+            msgs.addError(new ValidatorError("Invalid SELinux context"));
+        }
         
         if (!StringUtils.isBlank(getMacroStart())) {
             // Validate macro-start
@@ -327,6 +355,7 @@ public abstract class ConfigFileData {
         map.put(ConfigFileForm.REV_UID, getOwner());
         map.put(ConfigFileForm.REV_GID, getGroup());
         map.put(ConfigFileForm.REV_PERMS, getPermissions());
+        map.put(ConfigFileForm.REV_SELINUX_CTX, getSelinuxCtx());
         map.put(ConfigFileForm.REV_MACROSTART, getMacroStart());
         map.put(ConfigFileForm.REV_MACROEND, getMacroEnd());
         return map;
@@ -363,6 +392,7 @@ public abstract class ConfigFileData {
                 append("Owner", getOwner()).
                 append("Group", getGroup()).
                 append("Permissions", getPermissions()).
+                append("SELinux Context", getSelinuxCtx()).
                 append("Type", getType()).
                 append("Macro Start", getMacroStart()).
                 append("Macro End", getMacroEnd()).
diff --git a/java/code/src/com/redhat/rhn/testing/ConfigTestUtils.java 
b/java/code/src/com/redhat/rhn/testing/ConfigTestUtils.java
index a28cd2f..f547dd8 100644
--- a/java/code/src/com/redhat/rhn/testing/ConfigTestUtils.java
+++ b/java/code/src/com/redhat/rhn/testing/ConfigTestUtils.java
@@ -307,7 +307,7 @@ public class ConfigTestUtils extends Assert {
      * @return The newly created ConfigInfo.
      */
     public static ConfigInfo createConfigInfo(String user, String group, Long 
fileMode) {
-        return ConfigurationFactory.lookupOrInsertConfigInfo(user, group, 
fileMode);
+        return ConfigurationFactory.lookupOrInsertConfigInfo(user, group, 
fileMode, "");
     }
     
     /**
diff --git 
a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/create.jspf
 
b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/create.jspf
index 2eeddbe..0bbaad9 100644
--- 
a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/create.jspf
+++ 
b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/create.jspf
@@ -43,6 +43,11 @@
                                key="filedetails.jsp.tip.permissions" 
/></span></td>
                </tr>
                <tr>
+                       <th>SELinux context</th>
+                       <td><html:text property="cffSELinuxCtx" size="30" /><br 
/>
+                       <span class="small-text"><bean:message 
key="filedetails.jsp.tip.selinux" /></span></td>
+               </tr>
+               <tr>
                        <th><bean:message 
key="filedetails.add_details.jspf.macro" /></th>
                        <td nowrap="nowrap">
                          <bean:message 
key="filedetails.add_details.jspf.macro.start" />
diff --git 
a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/upload.jspf
 
b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/upload.jspf
index 13a20c7..e01f323 100644
--- 
a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/upload.jspf
+++ 
b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/upload.jspf
@@ -48,6 +48,11 @@
                                key="filedetails.jsp.tip.permissions" 
/></span></td>
                </tr>
                <tr>
+                       <th>SELinux context</th>
+                       <td><html:text property="cffSELinuxCtx" size="30" /><br 
/>
+                       <span class="small-text"><bean:message 
key="filedetails.jsp.tip.selinux" /></span></td>
+               </tr>
+               <tr>
                        <th><bean:message 
key="filedetails.add_details.jspf.macro" /></th>
                        <td nowrap="nowrap">
               <bean:message key="filedetails.add_details.jspf.macro.start" />
diff --git 
a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/properties.jspf
 
b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/properties.jspf
index 054aadc..cce3995 100644
--- 
a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/properties.jspf
+++ 
b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/properties.jspf
@@ -53,4 +53,19 @@
     <span class="small-text"><bean:message 
key="filedetails.jsp.tip.permissions" /></span>
   </td>
 </tr>
+<tr>
+  <th>SELinux context</th>
+  <td>
+    <rhn:require acl="config_channel_editable(${channel.id})"
+                 mixins="com.redhat.rhn.common.security.acl.ConfigAclHandler">
+      <html:text property="cffSELinuxCtx" size="24" />
+    </rhn:require>
+    <rhn:require acl="not config_channel_editable(${channel.id})"
+                 mixins="com.redhat.rhn.common.security.acl.ConfigAclHandler">
+      ${form.map.cffSELinuxCtx}
+    </rhn:require>
+    <br />
+    <span class="small-text"><bean:message key="filedetails.jsp.tip.selinux" 
/></span>
+  </td>
+</tr>
 </table>
diff --git a/java/code/webapp/WEB-INF/struts-config.xml 
b/java/code/webapp/WEB-INF/struts-config.xml
index daa9e20..efaff77 100644
--- a/java/code/webapp/WEB-INF/struts-config.xml
+++ b/java/code/webapp/WEB-INF/struts-config.xml
@@ -867,6 +867,7 @@
       <form-property name="cffPath"        type="java.lang.String"/>
       <form-property name="cffUid"         type="java.lang.String"/>
       <form-property name="cffGid"         type="java.lang.String"/>
+      <form-property name="cffSELinuxCtx"  type="java.lang.String"/>
          <form-property name="cffPermissions" type="java.lang.String"/>
          <form-property name="cffMacroStart"  type="java.lang.String"/>
          <form-property name="cffMacroEnd"    type="java.lang.String"/>
diff --git a/schema/spacewalk/common/tables/rhnConfigInfo.sql 
b/schema/spacewalk/common/tables/rhnConfigInfo.sql
index 17786c4..bb62b09 100644
--- a/schema/spacewalk/common/tables/rhnConfigInfo.sql
+++ b/schema/spacewalk/common/tables/rhnConfigInfo.sql
@@ -16,22 +16,23 @@
 
 CREATE TABLE rhnConfigInfo
 (
-    id         NUMBER NOT NULL
-                   CONSTRAINT rhn_confinfo_id_pk PRIMARY KEY
-                   USING INDEX TABLESPACE [[2m_tbs]],
-    username   VARCHAR2(32) NOT NULL,
-    groupname  VARCHAR2(32) NOT NULL,
-    filemode   NUMBER NOT NULL,
-    created    DATE
-                   DEFAULT (sysdate) NOT NULL,
-    modified   DATE
-                   DEFAULT (sysdate) NOT NULL
+    id           NUMBER NOT NULL
+                     CONSTRAINT rhn_confinfo_id_pk PRIMARY KEY
+                     USING INDEX TABLESPACE [[2m_tbs]],
+    username     VARCHAR2(32) NOT NULL,
+    groupname    VARCHAR2(32) NOT NULL,
+    filemode     NUMBER NOT NULL,
+    created      DATE
+                     DEFAULT (sysdate) NOT NULL,
+    modified     DATE
+                     DEFAULT (sysdate) NOT NULL,
+    selinux_ctx  VARCHAR2(64)
 )
 ENABLE ROW MOVEMENT
 ;
 
 CREATE UNIQUE INDEX rhn_confinfo_ugf_uq
-    ON rhnConfigInfo (username, groupname, filemode)
+    ON rhnConfigInfo (username, groupname, filemode, selinux_ctx)
     TABLESPACE [[4m_tbs]];
 
 CREATE SEQUENCE rhn_confinfo_id_seq;
diff --git a/schema/spacewalk/oracle/procs/lookup_config_info.sql 
b/schema/spacewalk/oracle/procs/lookup_config_info.sql
index 9255b89..65e238b 100644
--- a/schema/spacewalk/oracle/procs/lookup_config_info.sql
+++ b/schema/spacewalk/oracle/procs/lookup_config_info.sql
@@ -20,7 +20,8 @@ create or replace function
 lookup_config_info (
     username_in     in varchar2,
     groupname_in    in varchar2,
-    filemode_in     in varchar2
+    filemode_in     in varchar2,
+    selinux_ctx_in  in varchar2
 ) return number
 deterministic
 is
@@ -32,7 +33,8 @@ is
          where 1=1
            and username = username_in
            and groupname = groupname_in
-           and filemode = filemode_in;
+           and filemode = filemode_in
+           and selinux_ctx = selinux_ctx_in;
 begin
     for r in lookup_cursor loop
         return r.id;
@@ -41,8 +43,8 @@ begin
     select rhn_confinfo_id_seq.nextval
       into v_id
       from dual;
-    insert into rhnConfigInfo (id, username, groupname, filemode)
-    values (v_id, username_in, groupname_in, filemode_in);
+    insert into rhnConfigInfo (id, username, groupname, filemode, selinux_ctx)
+    values (v_id, username_in, groupname_in, filemode_in, selinux_ctx_in);
     commit;
     return v_id;
 end lookup_config_info;
diff --git a/schema/spacewalk/postgres/procs/lookup_config_info.sql 
b/schema/spacewalk/postgres/procs/lookup_config_info.sql
index 605c502..d307d74 100644
--- a/schema/spacewalk/postgres/procs/lookup_config_info.sql
+++ b/schema/spacewalk/postgres/procs/lookup_config_info.sql
@@ -18,7 +18,8 @@ lookup_config_info
 (
     username_in     in varchar,
     groupname_in    in varchar,
-    filemode_in     in numeric
+    filemode_in     in numeric,
+    selinux_ctx_in  in varchar
 )
 returns numeric
 as
@@ -31,7 +32,8 @@ declare
           from rhnConfigInfo
          where username = username_in
            and groupname = groupname_in
-           and filemode = filemode_in;
+           and filemode = filemode_in
+           and selinux_ctx = selinux_ctx_in;
 begin
     for r in lookup_cursor loop
         return r.id;
@@ -39,8 +41,8 @@ begin
     -- If we got here, we don't have the id
     select nextval('rhn_confinfo_id_seq') into v_id;
     insert into rhnConfigInfo
-        (id, username, groupname, filemode)
-    values (v_id, username_in, groupname_in, filemode_in);
+        (id, username, groupname, filemode, selinux_ctx)
+    values (v_id, username_in, groupname_in, filemode_in, selinux_ctx_in);
     return v_id;
 end;
 $$ language plpgsql;
diff --git 
a/schema/spacewalk/upgrade/spacewalk-schema-0.5-to-spacewalk-schema-0.6/150-rhnConfigInfo_selinux.sql
 
b/schema/spacewalk/upgrade/spacewalk-schema-0.5-to-spacewalk-schema-0.6/150-rhnConfigInfo_selinux.sql
new file mode 100644
index 0000000..f348e11
--- /dev/null
+++ 
b/schema/spacewalk/upgrade/spacewalk-schema-0.5-to-spacewalk-schema-0.6/150-rhnConfigInfo_selinux.sql
@@ -0,0 +1,48 @@
+--
+-- Add in a column for selinux context
+--
+
+ALTER TABLE rhnConfigInfo
+  ADD selinux_ctx VARCHAR(64);
+
+DROP INDEX RHN_CONFINFO_UGF_UQ;
+
+CREATE UNIQUE INDEX rhn_confinfo_ugf_uq
+    ON rhnConfigInfo( username, groupname, filemode, selinux_ctx )
+    tablespace [[4m_tbs]]
+  ;
+
+CREATE OR REPLACE FUNCTION
+lookup_config_info (
+    username_in     IN VARCHAR2,
+    groupname_in    IN VARCHAR2,
+    filemode_in     IN VARCHAR2,
+    selinux_ctx_in  IN VARCHAR2
+) RETURN NUMBER
+DETERMINISTIC
+IS
+    PRAGMA AUTONOMOUS_TRANSACTION;
+    v_id    NUMBER;
+    CURSOR lookup_cursor IS
+        SELECT id
+          FROM rhnConfigInfo
+         WHERE 1=1
+           AND username = username_in
+           AND groupname = groupname_in
+           AND filemode = filemode_in
+           AND selinux_ctx = selinux_ctx_in;
+BEGIN
+    FOR r IN lookup_cursor LOOP
+        RETURN r.id;
+    END LOOP;
+    -- If we got here, we don't have the id
+    SELECT rhn_confinfo_id_seq.nextval
+      INTO v_id
+      FROM dual;
+    INSERT INTO rhnConfigInfo (id, username, groupname, filemode, selinux_ctx)
+    VALUES (v_id, username_in, groupname_in, filemode_in, selinux_ctx_in);
+    COMMIT;
+    RETURN v_id;
+END lookup_config_info;
+/
+show errors
diff --git a/client/tools/rhncfg/config_common/transactions.py 
b/client/tools/rhncfg/config_common/transactions.py
index 2458f9a..cdd7ac0 100644
--- a/client/tools/rhncfg/config_common/transactions.py
+++ b/client/tools/rhncfg/config_common/transactions.py
@@ -25,6 +25,7 @@ import string
 
 from config_common import file_utils, utils, cfg_exceptions
 from config_common.rhn_log import log_debug
+from selinux import setfilecon
 
 class TargetNotFile(Exception): pass
 class DuplicateDeployment(Exception): pass
@@ -146,7 +147,8 @@ class DeployTransaction:
                 sectx = file_info.get('selinux_ctx')
                 if sectx is not None:
                     log_debug(1, "selinux context: " + sectx);
-                    setfilecon(temp_file_path, sectx);
+                    if setfilecon(temp_file_path, sectx) < 0:
+                        raise Exception("failed to set selinux context on %s" 
% dest_path)
 
         except OSError, e:
             if e.errno == errno.EPERM and not strict_ownership:
diff --git a/client/tools/rhncfg/rhncfg.spec b/client/tools/rhncfg/rhncfg.spec
index 8fd9b84..c1162ea 100644
--- a/client/tools/rhncfg/rhncfg.spec
+++ b/client/tools/rhncfg/rhncfg.spec
@@ -14,6 +14,7 @@ BuildRoot: 
%{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildArch: noarch
 BuildRequires: docbook-utils
 BuildRequires: python
+Requires: libselinux-python
 Requires: python
 Requires: rhnlib
 Provides: rhn-config-action = %{version}
diff --git 
a/java/code/src/com/redhat/rhn/common/db/datasource/xml/config_queries.xml 
b/java/code/src/com/redhat/rhn/common/db/datasource/xml/config_queries.xml
index c072f15..dc5c208 100644
--- a/java/code/src/com/redhat/rhn/common/db/datasource/xml/config_queries.xml
+++ b/java/code/src/com/redhat/rhn/common/db/datasource/xml/config_queries.xml
@@ -991,8 +991,8 @@ ORDER BY CCon.modified DESC
 </mode>
 
 <callable-mode name="lookup_config_info">
-  <query params="username_in, groupname_in, filemode_in, selinux_ctx_in">
-      {:info_id = call lookup_config_info( :username_in, :groupname_in, 
:filemode_in, :selinux_ctx_in )}
+  <query params="username_in, groupname_in, filemode_in, selinuxCtx_in">
+      {:info_id = call lookup_config_info( :username_in, :groupname_in, 
:filemode_in, :selinuxCtx_in )}
   </query>
 </callable-mode>
 
diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.hbm.xml 
b/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.hbm.xml
index 232379b..8895581 100644
--- a/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.hbm.xml
+++ b/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.hbm.xml
@@ -17,7 +17,7 @@ PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
                <property name="filemode" column="filemode" type="long" />
                <property name="created" column="created" type="timestamp" />
                <property name="modified" column="modified" type="timestamp" />
-               <property name="selinux_ctx" column="selinux_ctx" type="string" 
length="64" />
+               <property name="selinuxCtx" column="selinux_ctx" type="string" 
length="64" />
        </class>
        
        <query name="ConfigInfo.findWithoutId">
diff --git a/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.java 
b/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.java
index d0aa2c5..ca12cfb 100644
--- a/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.java
+++ b/java/code/src/com/redhat/rhn/domain/config/ConfigInfo.java
@@ -26,7 +26,7 @@ public class ConfigInfo extends BaseDomainHelper {
     private String username;
     private String groupname;
     private Long filemode;
-    private String selinux_ctx;
+    private String selinuxCtx;
     
     /**
      * protected constructor
@@ -104,15 +104,15 @@ public class ConfigInfo extends BaseDomainHelper {
      * Getter for selinux context
      * @return String to get
     */
-    public String getSelinux_ctx() {
-        return this.selinux_ctx;
+    public String getSelinuxCtx() {
+        return this.selinuxCtx;
     }
 
     /**
      * Setter for selinux context
      * @param ctxIn to set
     */
-    public void setSelinux_ctx(String ctxIn) {
-        this.selinux_ctx = ctxIn;
+    public void setSelinuxCtx(String ctxIn) {
+        this.selinuxCtx = ctxIn;
     }
 }
diff --git 
a/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java 
b/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java
index 1f12892..c20a891 100644
--- a/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java
+++ b/java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java
@@ -301,7 +301,7 @@ public class ConfigurationFactory extends HibernateFactory {
                     revision.getConfigInfo().getUsername(),
                     revision.getConfigInfo().getGroupname(),
                     revision.getConfigInfo().getFilemode(),
-                    revision.getConfigInfo().getSelinux_ctx());
+                    revision.getConfigInfo().getSelinuxCtx());
             //if the object did not change, we now have two hibernate objects
             //with the same identifier.  Evict one so that hibernate doesn't 
get mad.
             getSession().evict(revision.getConfigInfo());
@@ -476,12 +476,12 @@ public class ConfigurationFactory extends 
HibernateFactory {
      * @param username The linux username associated with a file
      * @param groupname The linux groupname associated with a file
      * @param filemode The three digit file mode (ex: 655)
-     * @param selinux_ctx The SELinux context
+     * @param selinuxCtx The SELinux context
      * @return The ConfigInfo found or inserted.
      */
     public static ConfigInfo lookupOrInsertConfigInfo(String username,
-            String groupname, Long filemode, String selinux_ctx) {
-        Long id = lookupConfigInfo(username, groupname, filemode, selinux_ctx);
+            String groupname, Long filemode, String selinuxCtx) {
+        Long id = lookupConfigInfo(username, groupname, filemode, selinuxCtx);
         return lookupConfigInfoById(id);
     }
     
@@ -491,11 +491,11 @@ public class ConfigurationFactory extends 
HibernateFactory {
      * @param user The linux username associated with a file
      * @param group The linux groupname associated with a file
      * @param filemode The three digit file mode (ex: 655)
-     * @param selinux_ctx The SELinux context
+     * @param selinuxCtx The SELinux context
      * @return The id of the found config info
      */
     private static Long lookupConfigInfo(String user, String group,
-            Long filemode, String selinux_ctx) {
+            Long filemode, String selinuxCtx) {
         CallableMode m = ModeFactory.getCallableMode("config_queries",
             "lookup_config_info");
 
@@ -505,7 +505,7 @@ public class ConfigurationFactory extends HibernateFactory {
         inParams.put("username_in", user);
         inParams.put("groupname_in", group);
         inParams.put("filemode_in", filemode);
-        inParams.put("selinux_ctx_in", selinux_ctx);
+        inParams.put("selinuxCtx_in", selinuxCtx);
         outParams.put("info_id", new Integer(Types.NUMERIC));
 
         Map out = m.execute(inParams, outParams);
diff --git 
a/java/code/src/com/redhat/rhn/domain/config/test/ConfigurationFactoryTest.java 
b/java/code/src/com/redhat/rhn/domain/config/test/ConfigurationFactoryTest.java
index 3f35c2b..1afdefe 100644
--- 
a/java/code/src/com/redhat/rhn/domain/config/test/ConfigurationFactoryTest.java
+++ 
b/java/code/src/com/redhat/rhn/domain/config/test/ConfigurationFactoryTest.java
@@ -151,9 +151,9 @@ public class ConfigurationFactoryTest extends 
RhnBaseTestCase {
         //one problem is that looking up the same thing must be done in such a 
way that
         //hibernate doesn't yell about it.
         ConfigInfo info1 = 
ConfigurationFactory.lookupOrInsertConfigInfo("testman",
-                "testgroup", new Long(665));
+                "testgroup", new Long(665), "");
         ConfigInfo info2 = 
ConfigurationFactory.lookupOrInsertConfigInfo("testman",
-                "testgroup", new Long(665));
+                "testgroup", new Long(665), "");
         assertNotNull(info1.getId());
         assertNotNull(info2.getId());
         assertEquals(info1.getId(), info2.getId());
diff --git 
a/java/code/src/com/redhat/rhn/frontend/action/configuration/ConfigFileForm.java
 
b/java/code/src/com/redhat/rhn/frontend/action/configuration/ConfigFileForm.java
index ac89b65..d716da4 100644
--- 
a/java/code/src/com/redhat/rhn/frontend/action/configuration/ConfigFileForm.java
+++ 
b/java/code/src/com/redhat/rhn/frontend/action/configuration/ConfigFileForm.java
@@ -159,7 +159,7 @@ public class ConfigFileForm extends ScrubbingDynaActionForm 
{
         Long mode = cr.getConfigInfo().getFilemode();
         String modeStr = new DecimalFormat("000").format(mode.longValue());
         set(ConfigFileForm.REV_PERMS, modeStr);
-        set(ConfigFileForm.REV_SELINUX_CTX, 
cr.getConfigInfo().getSelinux_ctx());
+        set(ConfigFileForm.REV_SELINUX_CTX, 
cr.getConfigInfo().getSelinuxCtx());
         set(ConfigFileForm.REV_UID, cr.getConfigInfo().getUsername());
         set(ConfigFileForm.REV_GID, cr.getConfigInfo().getGroupname());
         set(ConfigFileForm.REV_BINARY, new 
Boolean(cr.getConfigContent().isBinary()));
@@ -312,7 +312,7 @@ public class ConfigFileForm extends ScrubbingDynaActionForm 
{
         data.setGroup(getString(REV_GID));
         data.setOwner(getString(REV_UID));
         data.setPermissions(getString(REV_PERMS));
-        data.setSelinux_ctx(getString(REV_SELINUX_CTX));
+        data.setSelinuxCtx(getString(REV_SELINUX_CTX));
         data.setType(extractFileType());
         return data;
     }
diff --git 
a/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml 
b/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml
index af98b30..4fe49b1 100644
--- a/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml
+++ b/java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml
@@ -13921,7 +13921,12 @@ centrally-managed configuration channel, {2}; below is 
a list of systems you may
                <context 
context-type="sourcefile">/rhn/configuration/FileDetails.do</context>
        </context-group>
        </trans-unit>
-
+       <trans-unit id="filedetails.jsp.tip.selinux">
+<source>&lt;strong&gt;Tip:&lt;/strong&gt; Enter SELinux context like: 
user_u:role_r:type_t:s0-s15:c0.c1024 (Note: you don't have to enter all 
parts)</source>
+       <context-group name="ctx">
+               <context 
context-type="sourcefile">/rhn/configuration/FileDetails.do</context>
+       </context-group>
+       </trans-unit>
                <!-- form error messages -->
        <trans-unit id="config-file-form.error.user-invalid">
 <source>User must be a valid Linux user name or user id, of 32 characters or 
less.</source>
diff --git 
a/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/XmlRpcConfigChannelHelper.java
 
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/XmlRpcConfigChannelHelper.java
index c5a3ab5..df3d61c 100644
--- 
a/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/XmlRpcConfigChannelHelper.java
+++ 
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/XmlRpcConfigChannelHelper.java
@@ -139,7 +139,7 @@ public class XmlRpcConfigChannelHelper {
         form.setOwner((String)data.get(ConfigRevisionSerializer.OWNER));
         form.setGroup((String)data.get(ConfigRevisionSerializer.GROUP));
         
form.setPermissions((String)data.get(ConfigRevisionSerializer.PERMISSIONS));
-        
form.setSelinux_ctx((String)data.get(ConfigRevisionSerializer.SELINUX_CTX));
+        
form.setSelinuxCtx((String)data.get(ConfigRevisionSerializer.SELINUX_CTX));
 
         ConfigFileBuilder helper = ConfigFileBuilder.getInstance();
         try {
diff --git 
a/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/ConfigRevisionSerializer.java
 
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/ConfigRevisionSerializer.java
index da2765b..d8b755e 100644
--- 
a/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/ConfigRevisionSerializer.java
+++ 
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/ConfigRevisionSerializer.java
@@ -102,7 +102,7 @@ public class ConfigRevisionSerializer implements 
XmlRpcCustomSerializer {
         helper.add("revision", rev.getRevision());
         helper.add("creation", rev.getCreated());
         helper.add("modified", rev.getModified());
-        helper.add(SELINUX_CTX, rev.getConfigInfo().getSelinux_ctx());
+        helper.add(SELINUX_CTX, rev.getConfigInfo().getSelinuxCtx());
         helper.add(OWNER, rev.getConfigInfo().getUsername());
         helper.add(GROUP, rev.getConfigInfo().getGroupname());
         helper.add(PERMISSIONS, rev.getConfigInfo().getFilemode());
diff --git 
a/java/code/src/com/redhat/rhn/manager/configuration/file/ConfigFileData.java 
b/java/code/src/com/redhat/rhn/manager/configuration/file/ConfigFileData.java
index 6cf10da..d414f1e 100644
--- 
a/java/code/src/com/redhat/rhn/manager/configuration/file/ConfigFileData.java
+++ 
b/java/code/src/com/redhat/rhn/manager/configuration/file/ConfigFileData.java
@@ -49,7 +49,7 @@ public abstract class ConfigFileData {
     private String owner;
     private String group;
     private String permissions;
-    private String selinux_ctx;
+    private String selinuxCtx;
     private String macroStart;
     private String macroEnd;
     
@@ -72,7 +72,7 @@ public abstract class ConfigFileData {
         setPermissions("644");
         setOwner("root");
         setGroup("root");
-        setSelinux_ctx("");
+        setSelinuxCtx("");
         setType(ConfigFileType.file());
         setMacroStart(DEFAULT_MACRO_START);
         setMacroEnd(DEFAULT_MACRO_END);
@@ -137,15 +137,15 @@ public abstract class ConfigFileData {
     /**
      * @return the SELinux context
      */
-    public String getSelinux_ctx() {
-        return selinux_ctx;
+    public String getSelinuxCtx() {
+        return selinuxCtx;
     }
 
     /**
      * @param context the SELinux context to set
      */
-    public void setSelinux_ctx(String context) {
-        this.selinux_ctx = context;
+    public void setSelinuxCtx(String context) {
+        this.selinuxCtx = context;
     }
     
     /**
@@ -205,7 +205,7 @@ public abstract class ConfigFileData {
         ConfigInfo info = ConfigurationFactory.lookupOrInsertConfigInfo(
                             getOwner(), getGroup(), 
                             Long.valueOf(getPermissions()),
-                            getSelinux_ctx());
+                            getSelinuxCtx());
         return info;
     }    
     
@@ -251,11 +251,13 @@ public abstract class ConfigFileData {
         }
 
         // Validate selinux context
-        if (!getSelinux_ctx().matches( // \\w is [a-zA-Z_0-9], or [_[:alnum:]]
+        if (!getSelinuxCtx().matches(
+                 // \\w is [a-zA-Z_0-9], or [_[:alnum:]]
                  "^\\w*" + // user
                 "(:\\w*" + // role
                 "(:\\w*" + // type
-                "(:\\w*)?)?)?$")) { // range
+                "(:\\w*(\\-\\w+)?" + // sensitivity
+                "(:\\w*(\\.\\w+))?)?)?)?$")) { // category
             msgs.addError(new ValidatorError("Invalid SELinux context"));
         }
         
@@ -353,7 +355,7 @@ public abstract class ConfigFileData {
         map.put(ConfigFileForm.REV_UID, getOwner());
         map.put(ConfigFileForm.REV_GID, getGroup());
         map.put(ConfigFileForm.REV_PERMS, getPermissions());
-        map.put(ConfigFileForm.REV_SELINUX_CTX, getSelinux_ctx());
+        map.put(ConfigFileForm.REV_SELINUX_CTX, getSelinuxCtx());
         map.put(ConfigFileForm.REV_MACROSTART, getMacroStart());
         map.put(ConfigFileForm.REV_MACROEND, getMacroEnd());
         return map;
@@ -390,7 +392,7 @@ public abstract class ConfigFileData {
                 append("Owner", getOwner()).
                 append("Group", getGroup()).
                 append("Permissions", getPermissions()).
-                append("SELinux Context", getSelinux_ctx()).
+                append("SELinux Context", getSelinuxCtx()).
                 append("Type", getType()).
                 append("Macro Start", getMacroStart()).
                 append("Macro End", getMacroEnd()).
diff --git a/java/code/src/com/redhat/rhn/testing/ConfigTestUtils.java 
b/java/code/src/com/redhat/rhn/testing/ConfigTestUtils.java
index a28cd2f..f547dd8 100644
--- a/java/code/src/com/redhat/rhn/testing/ConfigTestUtils.java
+++ b/java/code/src/com/redhat/rhn/testing/ConfigTestUtils.java
@@ -307,7 +307,7 @@ public class ConfigTestUtils extends Assert {
      * @return The newly created ConfigInfo.
      */
     public static ConfigInfo createConfigInfo(String user, String group, Long 
fileMode) {
-        return ConfigurationFactory.lookupOrInsertConfigInfo(user, group, 
fileMode);
+        return ConfigurationFactory.lookupOrInsertConfigInfo(user, group, 
fileMode, "");
     }
     
     /**
diff --git 
a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/create.jspf
 
b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/create.jspf
index c58b15d..0bbaad9 100644
--- 
a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/create.jspf
+++ 
b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/create.jspf
@@ -44,7 +44,8 @@
                </tr>
                <tr>
                        <th>SELinux context</th>
-                       <td><html:text property="cffSELinuxCtx" size="30" 
/></td>
+                       <td><html:text property="cffSELinuxCtx" size="30" /><br 
/>
+                       <span class="small-text"><bean:message 
key="filedetails.jsp.tip.selinux" /></span></td>
                </tr>
                <tr>
                        <th><bean:message 
key="filedetails.add_details.jspf.macro" /></th>
diff --git 
a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/upload.jspf
 
b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/upload.jspf
index 4804861..e01f323 100644
--- 
a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/upload.jspf
+++ 
b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/upload.jspf
@@ -49,7 +49,8 @@
                </tr>
                <tr>
                        <th>SELinux context</th>
-                       <td><html:text property="cffSELinuxCtx" size="30" 
/></td>
+                       <td><html:text property="cffSELinuxCtx" size="30" /><br 
/>
+                       <span class="small-text"><bean:message 
key="filedetails.jsp.tip.selinux" /></span></td>
                </tr>
                <tr>
                        <th><bean:message 
key="filedetails.add_details.jspf.macro" /></th>
diff --git 
a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/properties.jspf
 
b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/properties.jspf
index f14d2ff..cce3995 100644
--- 
a/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/properties.jspf
+++ 
b/java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/properties.jspf
@@ -64,6 +64,8 @@
                  mixins="com.redhat.rhn.common.security.acl.ConfigAclHandler">
       ${form.map.cffSELinuxCtx}
     </rhn:require>
+    <br />
+    <span class="small-text"><bean:message key="filedetails.jsp.tip.selinux" 
/></span>
   </td>
 </tr>
 </table>
_______________________________________________
Spacewalk-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/spacewalk-devel

Reply via email to