diff --git a/.gitignore b/.gitignore
index fbdde0d..daa0815 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1 +1,3 @@
-SOURCES/apache-tomcat-7.0.54-src.tar.gz
+SOURCES/apache-tomcat-7.0.69-src.tar.gz
+SOURCES/tomcat-juli-adapters.jar
+SOURCES/tomcat-juli.jar
diff --git a/.tomcat.metadata b/.tomcat.metadata
index 5f4aba0..ef6c8c3 100644
--- a/.tomcat.metadata
+++ b/.tomcat.metadata
@@ -1 +1,3 @@
-70253e53572005adca147414a3d0eea4dbcc1ae0 SOURCES/apache-tomcat-7.0.54-src.tar.gz
+0be9ee73295f0125b391db17ec58053cead73f09 SOURCES/apache-tomcat-7.0.69-src.tar.gz
+b5aad5a5c8e358e014b3865aaa899e0deb3fa31a SOURCES/tomcat-juli-adapters.jar
+da220d83c3aceea91e55b26bf4ca07ad6a8b5b29 SOURCES/tomcat-juli.jar
diff --git a/SOURCES/tomcat-7.0-catalina-policy.patch b/SOURCES/tomcat-7.0-catalina-policy.patch
new file mode 100644
index 0000000..8aaf93e
--- /dev/null
+++ b/SOURCES/tomcat-7.0-catalina-policy.patch
@@ -0,0 +1,39 @@
+--- conf/catalina.policy~ 2016-06-17 10:20:17.649171968 -0400
++++ conf/catalina.policy 2016-06-17 10:23:35.358309244 -0400
+@@ -50,6 +50,36 @@ grant codeBase "file:${java.home}/lib/ex
+ permission java.security.AllPermission;
+ };
+
++// ========== RHEL SPECIFIC CODE PERMISSIONS =======================================
++
++// Allowing everything in /usr/share/java allows too many unknowns to be permitted
++// Specifying the individual jars that tomcat needs to function with the security manager
++// is the safest way forward.
++grant codeBase "file:/usr/share/java/tomcat-servlet-3.0-api.jar" {
++ permission java.security.AllPermission;
++};
++grant codeBase "file:/usr/share/java/omcat-jsp-2.2-api.jar" {
++ permission java.security.AllPermission;
++};
++grant codeBase "file:/usr/share/java/tomcat-el-2.2-api.jar" {
++ permission java.security.AllPermission;
++};
++grant codeBase "file:/usr/share/java/log4j.jar" {
++ permission java.security.AllPermission;
++};
++grant codeBase "file:/usr/share/java/ecj.jar" {
++ permission java.security.AllPermission;
++};
++grant codeBase "file:/usr/share/java/apache-commons-pool.jar" {
++ permission java.security.AllPermission;
++};
++grant codeBase "file:/usr/share/java/apache-commons-dbcp.jar" {
++ permission java.security.AllPermission;
++};
++grant codeBase "file:/usr/share/java/apache-commons-collections.jar" {
++ permission java.security.AllPermission;
++};
++
+
+ // ========== CATALINA CODE PERMISSIONS =======================================
+
diff --git a/SOURCES/tomcat-7.0-digest.script b/SOURCES/tomcat-7.0-digest.script
index 2ff7e64..86f05ec 100644
--- a/SOURCES/tomcat-7.0-digest.script
+++ b/SOURCES/tomcat-7.0-digest.script
@@ -34,7 +34,7 @@ export CLASSPATH
MAIN_CLASS="org.apache.catalina.startup.Tool"
BASE_FLAGS="-Dcatalina.home=\"$CATALINA_HOME\""
BASE_OPTIONS=""
-BASE_JARS="commons-daemon tomcat/catalina servlet"
+BASE_JARS="commons-daemon tomcat/catalina servlet tomcat/tomcat-util tomcat/tomcat-coyote"
# Set parameters
set_classpath $BASE_JARS
diff --git a/SOURCES/tomcat-7.0-jsvc.service b/SOURCES/tomcat-7.0-jsvc.service
index 3792cef..f480324 100644
--- a/SOURCES/tomcat-7.0-jsvc.service
+++ b/SOURCES/tomcat-7.0-jsvc.service
@@ -11,9 +11,12 @@ Description=Apache Tomcat Web Application Container JSVC wrapper
After=syslog.target network.target
[Service]
-Type=forking
-ExecStart=/usr/sbin/tomcat-jsvc-sysd start
-ExecStop=/usr/sbin/tomcat-jsvc-sysd stop
+Type=simple
+EnvironmentFile=/etc/tomcat/tomcat.conf
+Environment="NAME=" "USE_JSVC=true"
+EnvironmentFile=-/etc/sysconfig/tomcat
+ExecStart=/usr/libexec/tomcat/server start
+ExecStop=/usr/libexec/tomcat/server stop
[Install]
WantedBy=multi-user.target
diff --git a/SOURCES/tomcat-7.0-tomcat-users-webapp.patch b/SOURCES/tomcat-7.0-tomcat-users-webapp.patch
index 9f05e37..5304bad 100644
--- a/SOURCES/tomcat-7.0-tomcat-users-webapp.patch
+++ b/SOURCES/tomcat-7.0-tomcat-users-webapp.patch
@@ -1,8 +1,8 @@
---- conf/tomcat-users.xml~ 2008-01-28 17:41:06.000000000 -0500
-+++ conf/tomcat-users.xml 2008-03-07 19:40:07.000000000 -0500
-@@ -23,4 +23,14 @@
-
-
+--- conf/tomcat-users.xml 2016-04-11 04:02:30.000000000 -0400
++++ conf/tomcat-users.xml 2016-06-06 16:39:12.751217530 -0400
+@@ -38,4 +38,14 @@
+
+
-->
+
+
diff --git a/SOURCES/tomcat-7.0.54-CVE-2014-0227.patch b/SOURCES/tomcat-7.0.54-CVE-2014-0227.patch
deleted file mode 100755
index 3d07cc4..0000000
--- a/SOURCES/tomcat-7.0.54-CVE-2014-0227.patch
+++ /dev/null
@@ -1,410 +0,0 @@
---- java/org/apache/coyote/http11/filters/ChunkedInputFilter.java.orig 2015-03-24 16:32:02.657913000 -0400
-+++ java/org/apache/coyote/http11/filters/ChunkedInputFilter.java 2015-03-24 18:21:47.397617000 -0400
-@@ -14,7 +14,6 @@
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
--
- package org.apache.coyote.http11.filters;
-
- import java.io.EOFException;
-@@ -29,6 +28,7 @@
- import org.apache.tomcat.util.buf.HexUtils;
- import org.apache.tomcat.util.buf.MessageBytes;
- import org.apache.tomcat.util.http.MimeHeaders;
-+import org.apache.tomcat.util.res.StringManager;
-
- /**
- * Chunked input filter. Parses chunked data according to
-@@ -39,9 +39,11 @@
- */
- public class ChunkedInputFilter implements InputFilter {
-
-+ private static final StringManager sm = StringManager.getManager(
-+ ChunkedInputFilter.class.getPackage().getName());
-
-- // -------------------------------------------------------------- Constants
-
-+ // -------------------------------------------------------------- Constants
-
- protected static final String ENCODING_NAME = "chunked";
- protected static final ByteChunk ENCODING = new ByteChunk();
-@@ -49,7 +51,6 @@
-
- // ----------------------------------------------------- Static Initializer
-
--
- static {
- ENCODING.setBytes(ENCODING_NAME.getBytes(Charset.defaultCharset()), 0,
- ENCODING_NAME.length());
-@@ -58,7 +59,6 @@
-
- // ----------------------------------------------------- Instance Variables
-
--
- /**
- * Next buffer in the pipeline.
- */
-@@ -106,6 +106,7 @@
- */
- protected ByteChunk trailingHeaders = new ByteChunk();
-
-+
- /**
- * Flag set to true if the next call to doRead() must parse a CRLF pair
- * before doing anything else.
-@@ -130,21 +131,29 @@
- */
- private final int maxTrailerSize;
-
-+
- /**
- * Size of extensions processed for this request.
- */
- private long extensionSize;
-
-
-+ /**
-+ * Flag that indicates if an error has occurred.
-+ */
-+ private boolean error;
-+
-+
- // ----------------------------------------------------------- Constructors
-+
- public ChunkedInputFilter(int maxTrailerSize, int maxExtensionSize) {
- this.trailingHeaders.setLimit(maxTrailerSize);
- this.maxExtensionSize = maxExtensionSize;
- this.maxTrailerSize = maxTrailerSize;
- }
-
-- // ---------------------------------------------------- InputBuffer Methods
-
-+ // ---------------------------------------------------- InputBuffer Methods
-
- /**
- * Read bytes.
-@@ -156,11 +165,12 @@
- * control, the returned value should be -1.
- */
- @Override
-- public int doRead(ByteChunk chunk, Request req)
-- throws IOException {
--
-- if (endChunk)
-+ public int doRead(ByteChunk chunk, Request req) throws IOException {
-+ if (endChunk) {
- return -1;
-+ }
-+
-+ checkError();
-
- if(needCRLFParse) {
- needCRLFParse = false;
-@@ -169,7 +179,7 @@
-
- if (remaining <= 0) {
- if (!parseChunkHeader()) {
-- throw new IOException("Invalid chunk header");
-+ throwIOException(sm.getString("chunkedInputFilter.invalidHeader"));
- }
- if (endChunk) {
- parseEndChunk();
-@@ -181,8 +191,7 @@
-
- if (pos >= lastValid) {
- if (readBytes() < 0) {
-- throw new IOException(
-- "Unexpected end of stream whilst reading request body");
-+ throwIOException(sm.getString("chunkedInputFilter.eos"));
- }
- }
-
-@@ -207,13 +216,11 @@
- }
-
- return result;
--
- }
-
-
- // ---------------------------------------------------- InputFilter Methods
-
--
- /**
- * Read the content length from the request.
- */
-@@ -227,17 +234,13 @@
- * End the current request.
- */
- @Override
-- public long end()
-- throws IOException {
--
-- // Consume extra bytes : parse the stream until the end chunk is found
-+ public long end() throws IOException {
- while (doRead(readChunk, null) >= 0) {
-- // NOOP: Just consume the input
-+ // NOOP: just consume the input
- }
-
- // Return the number of extra bytes which were consumed
-- return (lastValid - pos);
--
-+ return lastValid - pos;
- }
-
-
-@@ -246,7 +249,7 @@
- */
- @Override
- public int available() {
-- return (lastValid - pos);
-+ return lastValid - pos;
- }
-
-
-@@ -272,6 +275,7 @@
- trailingHeaders.recycle();
- trailingHeaders.setLimit(maxTrailerSize);
- extensionSize = 0;
-+ error = false;
- }
-
-
-@@ -287,12 +291,10 @@
-
- // ------------------------------------------------------ Protected Methods
-
--
- /**
- * Read bytes from the previous buffer.
- */
-- protected int readBytes()
-- throws IOException {
-+ protected int readBytes() throws IOException {
-
- int nRead = buffer.doRead(readChunk, null);
- pos = readChunk.getStart();
-@@ -300,7 +302,6 @@
- buf = readChunk.getBytes();
-
- return nRead;
--
- }
-
-
-@@ -315,8 +316,7 @@
- * digits. We should not parse F23IAMGONNAMESSTHISUP34CRLF as a valid
- * header according to the spec.
- */
-- protected boolean parseChunkHeader()
-- throws IOException {
-+ protected boolean parseChunkHeader() throws IOException {
-
- int result = 0;
- boolean eol = false;
-@@ -356,7 +356,7 @@
- // validated. Currently it is simply ignored.
- extensionSize++;
- if (maxExtensionSize > -1 && extensionSize > maxExtensionSize) {
-- throw new IOException("maxExtensionSize exceeded");
-+ throwIOException(sm.getString("chunkedInputFilter.maxExtension"));
- }
- }
-
-@@ -364,21 +364,22 @@
- if (!eol) {
- pos++;
- }
--
- }
-
-- if (readDigit == 0 || result < 0)
-+ if (readDigit == 0 || result < 0) {
- return false;
-+ }
-
-- if (result == 0)
-+ if (result == 0) {
- endChunk = true;
-+ }
-
- remaining = result;
-- if (remaining < 0)
-+ if (remaining < 0) {
- return false;
-+ }
-
- return true;
--
- }
-
-
-@@ -405,26 +406,27 @@
- boolean crfound = false;
-
- while (!eol) {
--
- if (pos >= lastValid) {
-- if (readBytes() <= 0)
-- throw new IOException("Invalid CRLF");
-+ if (readBytes() <= 0) {
-+ throwIOException(sm.getString("chunkedInputFilter.invalidCrlfNoData"));
-+ }
- }
-
- if (buf[pos] == Constants.CR) {
-- if (crfound) throw new IOException("Invalid CRLF, two CR characters encountered.");
-+ if (crfound) {
-+ throwIOException(sm.getString("chunkedInputFilter.invalidCrlfCRCR"));
-+ }
- crfound = true;
- } else if (buf[pos] == Constants.LF) {
- if (!tolerant && !crfound) {
-- throw new IOException("Invalid CRLF, no CR character encountered.");
-+ throwIOException(sm.getString("chunkedInputFilter.invalidCrlfNoCR"));
- }
- eol = true;
- } else {
-- throw new IOException("Invalid CRLF");
-+ throwIOException(sm.getString("chunkedInputFilter.invalidCrlf"));
- }
-
- pos++;
--
- }
- }
-
-@@ -433,7 +435,6 @@
- * Parse end chunk data.
- */
- protected void parseEndChunk() throws IOException {
--
- // Handle optional trailer headers
- while (parseHeader()) {
- // Loop until we run out of headers
-@@ -449,8 +450,9 @@
-
- // Read new bytes if needed
- if (pos >= lastValid) {
-- if (readBytes() <0)
-- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request");
-+ if (readBytes() <0) {
-+ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer"));
-+ }
- }
-
- chr = buf[pos];
-@@ -474,8 +476,9 @@
-
- // Read new bytes if needed
- if (pos >= lastValid) {
-- if (readBytes() <0)
-- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request");
-+ if (readBytes() <0) {
-+ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer"));
-+ }
- }
-
- chr = buf[pos];
-@@ -515,8 +518,9 @@
-
- // Read new bytes if needed
- if (pos >= lastValid) {
-- if (readBytes() <0)
-- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request");
-+ if (readBytes() <0) {
-+ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer"));
-+ }
- }
-
- chr = buf[pos];
-@@ -526,7 +530,7 @@
- // limit placed on trailing header size
- int newlimit = trailingHeaders.getLimit() -1;
- if (trailingHeaders.getEnd() > newlimit) {
-- throw new IOException("Exceeded maxTrailerSize");
-+ throwIOException(sm.getString("chunkedInputFilter.maxTrailer"));
- }
- trailingHeaders.setLimit(newlimit);
- } else {
-@@ -540,8 +544,9 @@
-
- // Read new bytes if needed
- if (pos >= lastValid) {
-- if (readBytes() <0)
-- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request");
-+ if (readBytes() <0) {
-+ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer"));
-+ }
- }
-
- chr = buf[pos];
-@@ -565,8 +570,9 @@
-
- // Read new bytes if needed
- if (pos >= lastValid) {
-- if (readBytes() <0)
-- throw new EOFException("Unexpected end of stream whilst reading trailer headers for chunked request");
-+ if (readBytes() <0) {
-+ throwEOFException(sm.getString("chunkedInputFilter.eosTrailer"));
-+ }
- }
-
- chr = buf[pos];
-@@ -587,4 +593,23 @@
-
- return true;
- }
-+
-+
-+ private void throwIOException(String msg) throws IOException {
-+ error = true;
-+ throw new IOException(msg);
-+ }
-+
-+
-+ private void throwEOFException(String msg) throws IOException {
-+ error = true;
-+ throw new EOFException(msg);
-+ }
-+
-+
-+ private void checkError() throws IOException {
-+ if (error) {
-+ throw new IOException(sm.getString("chunkedInputFilter.error"));
-+ }
-+ }
- }
---- java/org/apache/coyote/http11/filters/LocalStrings.properties.orig 2015-03-24 16:32:02.662909000 -0400
-+++ java/org/apache/coyote/http11/filters/LocalStrings.properties 2015-03-24 16:39:31.017419000 -0400
-@@ -0,0 +1,27 @@
-+# Licensed to the Apache Software Foundation (ASF) under one or more
-+# contributor license agreements. See the NOTICE file distributed with
-+# this work for additional information regarding copyright ownership.
-+# The ASF licenses this file to You under the Apache License, Version 2.0
-+# (the "License"); you may not use this file except in compliance with
-+# the License. You may obtain a copy of the License at
-+#
-+# http://www.apache.org/licenses/LICENSE-2.0
-+#
-+# Unless required by applicable law or agreed to in writing, software
-+# distributed under the License is distributed on an "AS IS" BASIS,
-+# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
-+# See the License for the specific language governing permissions and
-+# limitations under the License.
-+
-+chunkedInputFilter.error=No data available due to previous error
-+chunkedInputFilter.eos=Unexpected end of stream while reading request body
-+chunkedInputFilter.eosTrailer=Unexpected end of stream while reading trailer headers
-+chunkedInputFilter.invalidCrlf=Invalid end of line sequence (character other than CR or LF found)
-+chunkedInputFilter.invalidCrlfCRCR=Invalid end of line sequence (CRCR)
-+chunkedInputFilter.invalidCrlfNoCR=Invalid end of line sequence (No CR before LF)
-+chunkedInputFilter.invalidCrlfNoData=Invalid end of line sequence (no data available to read)
-+chunkedInputFilter.invalidHeader=Invalid chunk header
-+chunkedInputFilter.maxExtension=maxExtensionSize exceeded
-+chunkedInputFilter.maxTrailer=maxTrailerSize exceeded
-+
-+inputFilter.maxSwallow=maxSwallowSize exceeded
-\ No newline at end of file
diff --git a/SOURCES/tomcat-7.0.54-CVE-2014-7810.patch b/SOURCES/tomcat-7.0.54-CVE-2014-7810.patch
deleted file mode 100644
index 32ca660..0000000
--- a/SOURCES/tomcat-7.0.54-CVE-2014-7810.patch
+++ /dev/null
@@ -1,120 +0,0 @@
---- java/javax/el/BeanELResolver.java.orig 2016-06-02 09:46:15.019196027 -0400
-+++ java/javax/el/BeanELResolver.java 2016-06-02 09:46:15.025196055 -0400
-@@ -251,15 +251,39 @@
- try {
- BeanInfo info = Introspector.getBeanInfo(this.type);
- PropertyDescriptor[] pds = info.getPropertyDescriptors();
-- for (int i = 0; i < pds.length; i++) {
-- this.properties.put(pds[i].getName(), new BeanProperty(
-- type, pds[i]));
-+ for (PropertyDescriptor pd: pds) {
-+ this.properties.put(pd.getName(), new BeanProperty(type, pd));
-+ }
-+ if (System.getSecurityManager() != null) {
-+ // When running with SecurityManager, some classes may be
-+ // not accessible, but have accessible interfaces.
-+ populateFromInterfaces(type);
- }
- } catch (IntrospectionException ie) {
- throw new ELException(ie);
- }
- }
-
-+ private void populateFromInterfaces(Class> aClass) throws IntrospectionException {
-+ Class> interfaces[] = aClass.getInterfaces();
-+ if (interfaces.length > 0) {
-+ for (Class> ifs : interfaces) {
-+ BeanInfo info = Introspector.getBeanInfo(ifs);
-+ PropertyDescriptor[] pds = info.getPropertyDescriptors();
-+ for (PropertyDescriptor pd : pds) {
-+ if (!this.properties.containsKey(pd.getName())) {
-+ this.properties.put(pd.getName(), new BeanProperty(
-+ this.type, pd));
-+ }
-+ }
-+ }
-+ }
-+ Class> superclass = aClass.getSuperclass();
-+ if (superclass != null) {
-+ populateFromInterfaces(superclass);
-+ }
-+ }
-+
- private BeanProperty get(ELContext ctx, String name) {
- BeanProperty property = this.properties.get(name);
- if (property == null) {
---- java/org/apache/jasper/runtime/PageContextImpl.java.orig 2016-06-02 09:46:15.020196032 -0400
-+++ java/org/apache/jasper/runtime/PageContextImpl.java 2016-06-02 09:46:15.026196060 -0400
-@@ -937,37 +937,11 @@
- final Class> expectedType, final PageContext pageContext,
- final ProtectedFunctionMapper functionMap, final boolean escape)
- throws ELException {
-- Object retValue;
- final ExpressionFactory exprFactory = jspf.getJspApplicationContext(pageContext.getServletContext()).getExpressionFactory();
-- if (SecurityUtil.isPackageProtectionEnabled()) {
-- try {
-- retValue = AccessController
-- .doPrivileged(new PrivilegedExceptionAction