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@redhat.com Date: Mon Aug 3 14:06:12 2009 -0400
Merge branch 'master' into repo-sync
commit 074cca0508e8d6b4817453f45b2bfada62ed8623 Author: Joshua Roys joshua.roys@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@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@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);
spacewalk-commits@lists.fedorahosted.org