backend/server/action/configfiles.py | 3
backend/server/configFilesHandler.py | 1
backend/server/handlers/config/rhn_config_management.py | 3
backend/server/handlers/config_mgmt/rhn_config_management.py | 6 -
client/tools/rhncfg/config_common/transactions.py | 20 ++--
client/tools/rhncfg/rhncfg.spec | 1
java/code/src/com/redhat/rhn/common/db/datasource/xml/config_queries.xml | 4
java/code/src/com/redhat/rhn/domain/config/ConfigInfo.hbm.xml | 1
java/code/src/com/redhat/rhn/domain/config/ConfigInfo.java | 17 +++
java/code/src/com/redhat/rhn/domain/config/ConfigurationFactory.java | 19 ++-
java/code/src/com/redhat/rhn/domain/config/test/ConfigurationFactoryTest.java | 4
java/code/src/com/redhat/rhn/frontend/action/configuration/ConfigFileForm.java | 3
java/code/src/com/redhat/rhn/frontend/action/configuration/validation/configFileForm.xsd | 6 +
java/code/src/com/redhat/rhn/frontend/action/rhnpackage/PackageDetailsAction.java | 11 +-
java/code/src/com/redhat/rhn/frontend/strings/jsp/StringResource_en_US.xml | 7 +
java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/ConfigChannelHandler.java | 1
java/code/src/com/redhat/rhn/frontend/xmlrpc/configchannel/XmlRpcConfigChannelHelper.java | 1
java/code/src/com/redhat/rhn/frontend/xmlrpc/serializer/ConfigRevisionSerializer.java | 2
java/code/src/com/redhat/rhn/frontend/xmlrpc/system/config/ServerConfigHandler.java | 1
java/code/src/com/redhat/rhn/manager/configuration/file/ConfigFileData.java | 32 ++++++
java/code/src/com/redhat/rhn/testing/ConfigTestUtils.java | 2
java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/create.jspf | 5 +
java/code/webapp/WEB-INF/pages/common/fragments/configuration/channel/upload.jspf | 5 +
java/code/webapp/WEB-INF/pages/common/fragments/configuration/files/properties.jspf | 15 +++
java/code/webapp/WEB-INF/struts-config.xml | 1
schema/spacewalk/common/tables/rhnConfigInfo.sql | 23 ++--
schema/spacewalk/oracle/procs/lookup_config_info.sql | 10 +-
schema/spacewalk/postgres/procs/lookup_config_info.sql | 10 +-
schema/spacewalk/upgrade/spacewalk-schema-0.5-to-spacewalk-schema-0.6/150-rhnConfigInfo_selinux.sql | 48 ++++++++++
29 files changed, 217 insertions(+), 45 deletions(-)
New commits:
commit b397990514e0aed7cfcb77d5ea83a60664ea51b9
Merge: c273e9e... 074cca0...
Author: Justin Sherrill <jsherril(a)redhat.com>
Date: Mon Aug 3 14:06:12 2009 -0400
Merge branch 'master' into repo-sync
commit 074cca0508e8d6b4817453f45b2bfada62ed8623
Author: Joshua Roys <joshua.roys(a)gtri.gatech.edu>
Date: Mon Aug 3 13:25:08 2009 -0400
upgrade script for the previous commit. Patch from Joshua Roys
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
commit 40785d998874d7e9b022a79a8322bce09af8ac3f
Author: Joshua Roys <joshua.roys(a)gtri.gatech.edu>
Date: Mon Aug 3 13:21:21 2009 -0400
Patch: Selinux Context support for config files
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 4b67e78..c481649 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
@@ -13928,7 +13928,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><strong>Tip:</strong> 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 7a26013..a4d0c32 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;
commit 3022ae5840f925a031c0200fb9820f3cc9004027
Author: Pradeep Kilambi <pkilambi(a)redhat.com>
Date: Mon Aug 3 13:08:04 2009 -0400
515219 - We can have a channel with null description. In the packagedetailsaction we call replace on description without checking if its a valid string resulting in Null Pointer Exception.
diff --git a/java/code/src/com/redhat/rhn/frontend/action/rhnpackage/PackageDetailsAction.java b/java/code/src/com/redhat/rhn/frontend/action/rhnpackage/PackageDetailsAction.java
index 078fcb2..9bd7cb0 100644
--- a/java/code/src/com/redhat/rhn/frontend/action/rhnpackage/PackageDetailsAction.java
+++ b/java/code/src/com/redhat/rhn/frontend/action/rhnpackage/PackageDetailsAction.java
@@ -100,8 +100,15 @@ public class PackageDetailsAction extends RhnAction {
}
request.setAttribute("pack", pkg);
- request.setAttribute("description",
- pkg.getDescription().replace("\n", "<BR>\n"));
+ // description can be null.
+ if (pkg.getDescription() != null) {
+ request.setAttribute("description",
+ pkg.getDescription().replace("\n", "<BR>\n"));
+ }
+ else {
+ request.setAttribute("description",
+ pkg.getDescription());
+ }
request.setAttribute("packArches",
PackageFactory.findPackagesWithDifferentArch(pkg));
request.setAttribute("pid", pid);