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