Hello all,

Attached is a patch to add the ability to specify a SELinux context in the Configuration management part of Spacewalk. It works for me, but I would appreciate your expert review. Also attached is a sql schema upgrade.

Thanks,

Joshua Roys
--
-- 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/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 f2f3fe9..a602baf 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..2458f9a 100644
--- a/client/tools/rhncfg/config_common/transactions.py
+++ b/client/tools/rhncfg/config_common/transactions.py
@@ -102,7 +102,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 +142,12 @@ 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);
+                    setfilecon(temp_file_path, sectx);
+
         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 +176,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 +227,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 +277,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 +321,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/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..c072f15 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, selinux_ctx_in">
+      {:info_id = call lookup_config_info( :username_in, :groupname_in, 
:filemode_in, :selinux_ctx_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..232379b 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="selinux_ctx" 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..d0aa2c5 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 selinux_ctx;
     
     /**
      * 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 getSelinux_ctx() {
+        return this.selinux_ctx;
+    }
+
+    /**
+     * Setter for selinux context
+     * @param ctxIn to set
+    */
+    public void setSelinux_ctx(String ctxIn) {
+        this.selinux_ctx = 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..1f12892 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().getSelinux_ctx());
             //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 selinux_ctx 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 selinux_ctx) {
+        Long id = lookupConfigInfo(username, groupname, filemode, selinux_ctx);
         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 selinux_ctx 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 selinux_ctx) {
         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("selinux_ctx_in", selinux_ctx);
         outParams.put("info_id", new Integer(Types.NUMERIC));
 
         Map out = m.execute(inParams, outParams);
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 bb49df8..10f0fe8 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().getSelinux_ctx());
         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.setSelinux_ctx(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/xmlrpc/configchannel/ConfigChannelHandler.java
 
b/java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/ConfigChannelHandler.java
index 4ff4f32..80916cf 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..c5a3ab5 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.setSelinux_ctx((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..da2765b 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().getSelinux_ctx());
         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 cc738de..f1b18ce 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 a78adb9..8f830aa 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
@@ -48,6 +48,7 @@ public abstract class ConfigFileData {
     private String owner;
     private String group;
     private String permissions;
+    private String selinux_ctx;
     private String macroStart;
     private String macroEnd;
     
@@ -70,6 +71,7 @@ public abstract class ConfigFileData {
         setPermissions("644");
         setOwner("root");
         setGroup("root");
+        setSelinux_ctx("");
         setType(ConfigFileType.file());
         setMacroStart(DEFAULT_MACRO_START);
         setMacroEnd(DEFAULT_MACRO_END);
@@ -130,6 +132,20 @@ public abstract class ConfigFileData {
     public void setPermissions(String perms) {
         this.permissions = perms;
     }
+
+    /**
+     * @return the SELinux context
+     */
+    public String getSelinux_ctx() {
+        return selinux_ctx;
+    }
+
+    /**
+     * @param context the SELinux context to set
+     */
+    public void setSelinux_ctx(String context) {
+        this.selinux_ctx = context;
+    }
     
     /**
      * @return the macroStart
@@ -187,7 +203,8 @@ public abstract class ConfigFileData {
     public ConfigInfo extractInfo() {
         ConfigInfo info = ConfigurationFactory.lookupOrInsertConfigInfo(
                             getOwner(), getGroup(), 
-                            Long.valueOf(getPermissions()));
+                            Long.valueOf(getPermissions()),
+                            getSelinux_ctx());
         return info;
     }    
     
@@ -231,6 +248,15 @@ public abstract class ConfigFileData {
         if (!getPermissions().matches("^[0-7][0-7][0-7][0-7]?$")) {
             msgs.addError(error("mode-invalid"));
         }
+
+        // Validate selinux context
+        if (!getSelinux_ctx().matches( // \\w is [a-zA-Z_0-9], or [_[:alnum:]]
+                 "^\\w*" + // user
+                "(:\\w*" + // role
+                "(:\\w*" + // type
+                "(:\\w*)?)?)?$")) { // range
+            msgs.addError(new ValidatorError("Invalid SELinux context"));
+        }
         
         if (!StringUtils.isBlank(getMacroStart())) {
             // Validate macro-start
@@ -326,6 +352,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_MACROSTART, getMacroStart());
         map.put(ConfigFileForm.REV_MACROEND, getMacroEnd());
         return map;
@@ -362,6 +389,7 @@ public abstract class ConfigFileData {
                 append("Owner", getOwner()).
                 append("Group", getGroup()).
                 append("Permissions", getPermissions()).
+                append("SELinux Context", getSelinux_ctx()).
                 append("Type", getType()).
                 append("Macro Start", getMacroStart()).
                 append("Macro End", getMacroEnd()).
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..c58b15d 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,10 @@
                                key="filedetails.jsp.tip.permissions" 
/></span></td>
                </tr>
                <tr>
+                       <th>SELinux context</th>
+                       <td><html:text property="cffSELinuxCtx" size="30" 
/></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..4804861 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,10 @@
                                key="filedetails.jsp.tip.permissions" 
/></span></td>
                </tr>
                <tr>
+                       <th>SELinux context</th>
+                       <td><html:text property="cffSELinuxCtx" size="30" 
/></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..f14d2ff 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,17 @@
     <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>
+  </td>
+</tr>
 </table>
diff --git a/java/code/webapp/WEB-INF/struts-config.xml 
b/java/code/webapp/WEB-INF/struts-config.xml
index 6199d78..375f8b8 100644
--- a/java/code/webapp/WEB-INF/struts-config.xml
+++ b/java/code/webapp/WEB-INF/struts-config.xml
@@ -891,6 +891,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/rhnsat/tables/rhnConfigInfo.sql 
b/schema/spacewalk/rhnsat/tables/rhnConfigInfo.sql
index a6bc5eb..fea9f4e 100644
--- a/schema/spacewalk/rhnsat/tables/rhnConfigInfo.sql
+++ b/schema/spacewalk/rhnsat/tables/rhnConfigInfo.sql
@@ -35,12 +35,13 @@ rhnConfigInfo
                                constraint rhn_confinfo_creat_nn not null,
        modified                date default(sysdate)
                                constraint rhn_confinfo_mod_nn 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]]
   ;
 
_______________________________________________
Spacewalk-devel mailing list
[email protected]
https://www.redhat.com/mailman/listinfo/spacewalk-devel

Reply via email to