You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ambari.apache.org by rl...@apache.org on 2017/02/27 19:52:00 UTC

ambari git commit: AMBARI-20196. Ambari should install the unlimited key JCE policy based on service requirements even if cluster is not Kerberized (rlevas)

Repository: ambari
Updated Branches:
  refs/heads/trunk 236ae87a1 -> 9112148e5


AMBARI-20196. Ambari should install the unlimited key JCE policy based on service requirements even if cluster is not Kerberized (rlevas)


Project: http://git-wip-us.apache.org/repos/asf/ambari/repo
Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/9112148e
Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/9112148e
Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/9112148e

Branch: refs/heads/trunk
Commit: 9112148e597baedaab1dea15c8da299dee6f63c7
Parents: 236ae87
Author: Robert Levas <rl...@hortonworks.com>
Authored: Mon Feb 27 14:51:46 2017 -0500
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Mon Feb 27 14:51:54 2017 -0500

----------------------------------------------------------------------
 ambari-agent/pom.xml                            |  16 ++
 .../apache/ambari/tools/jce/JcePolicyInfo.java  | 145 +++++++++++++++++++
 .../core/resources/jcepolicyinfo.py             |  47 ++++++
 .../ambari/server/agent/ExecutionCommand.java   |   1 +
 .../AmbariManagementControllerImpl.java         |  22 +++
 .../ambari/server/stack/ComponentModule.java    |   4 +
 .../ambari/server/state/ComponentInfo.java      |  16 +-
 .../state/UnlimitedKeyJCERequirement.java       |  42 ++++++
 .../package/scripts/kerberos_client.py          |   6 -
 .../package/scripts/kerberos_common.py          |  35 +----
 .../HDP/2.0.6/configuration/cluster-env.xml     |  11 ++
 .../2.0.6/hooks/before-START/scripts/hook.py    |   3 +-
 .../2.0.6/hooks/before-START/scripts/params.py  |  27 +++-
 .../scripts/shared_initialization.py            |  64 ++++++++
 .../HDP/3.0/configuration/cluster-env.xml       |  11 ++
 .../HDP/3.0/hooks/before-START/scripts/hook.py  |   3 +-
 .../3.0/hooks/before-START/scripts/params.py    |  27 +++-
 .../scripts/shared_initialization.py            |  64 ++++++++
 .../KERBEROS/package/scripts/kerberos_client.py |   3 -
 .../server/stack/ComponentModuleTest.java       |  35 +++++
 .../2.0.6/configs/secured_no_jce_name.json      |  16 +-
 .../hooks/before-START/test_before_start.py     |  26 ++--
 .../stacks/2.2/KERBEROS/test_kerberos_client.py |  21 ---
 23 files changed, 554 insertions(+), 91 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-agent/pom.xml
----------------------------------------------------------------------
diff --git a/ambari-agent/pom.xml b/ambari-agent/pom.xml
index 074e051..7633b95 100644
--- a/ambari-agent/pom.xml
+++ b/ambari-agent/pom.xml
@@ -157,6 +157,7 @@
         <version>2.3</version>
         <executions>
           <execution>
+            <id>shade-zkmigrator</id>
             <phase>package</phase>
             <goals>
               <goal>shade</goal>
@@ -170,6 +171,21 @@
               <outputFile>${project.build.directory}${dirsep}${project.artifactId}-${project.version}/var/lib/ambari-agent/tools/zkmigrator.jar</outputFile>
             </configuration>
           </execution>
+          <execution>
+            <id>shade-jce</id>
+            <phase>package</phase>
+            <goals>
+              <goal>shade</goal>
+            </goals>
+            <configuration>
+              <transformers>
+                <transformer implementation="org.apache.maven.plugins.shade.resource.ManifestResourceTransformer">
+                  <mainClass>org.apache.ambari.tools.jce.JcePolicyInfo</mainClass>
+                </transformer>
+              </transformers>
+              <outputFile>${project.build.directory}${dirsep}${project.artifactId}-${project.version}/var/lib/ambari-agent/tools/jcepolicyinfo.jar</outputFile>
+            </configuration>
+          </execution>
         </executions>
       </plugin>
       <plugin>

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-agent/src/main/java/org/apache/ambari/tools/jce/JcePolicyInfo.java
----------------------------------------------------------------------
diff --git a/ambari-agent/src/main/java/org/apache/ambari/tools/jce/JcePolicyInfo.java b/ambari-agent/src/main/java/org/apache/ambari/tools/jce/JcePolicyInfo.java
new file mode 100644
index 0000000..15936e8
--- /dev/null
+++ b/ambari-agent/src/main/java/org/apache/ambari/tools/jce/JcePolicyInfo.java
@@ -0,0 +1,145 @@
+/*
+ * 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.
+ */
+
+package org.apache.ambari.tools.jce;
+
+import java.security.NoSuchAlgorithmException;
+import java.security.Provider;
+import java.security.Security;
+
+import javax.crypto.Cipher;
+
+import org.apache.commons.cli.CommandLine;
+import org.apache.commons.cli.DefaultParser;
+import org.apache.commons.cli.HelpFormatter;
+import org.apache.commons.cli.Option;
+import org.apache.commons.cli.Options;
+import org.apache.commons.cli.UnrecognizedOptionException;
+
+/**
+ * JcePolicyInfo provides information about the JVM's installed JCE (Java Cryptology Enhancements)
+ * policy.
+ */
+public class JcePolicyInfo {
+
+  public static void main(String[] args) throws Exception {
+    try {
+      boolean showHelp = true;
+      CommandLine cli = new DefaultParser().parse(options(), args);
+      if (cli.hasOption("lc")) {
+        listCiphers();
+        showHelp = false;
+      }
+
+      if (cli.hasOption("tu")) {
+        testUnlimitedKeyJCEPolicy();
+        showHelp = false;
+      }
+
+      if (showHelp) {
+        printHelp(null);
+      }
+    } catch (UnrecognizedOptionException e) {
+      printHelp(e);
+    }
+
+  }
+
+  private static void printHelp(UnrecognizedOptionException exception) {
+    HelpFormatter helpFormatter = new HelpFormatter();
+
+    if (exception == null) {
+      helpFormatter.printHelp("jcepolicyinfo [options]", options());
+    } else {
+      helpFormatter.printHelp("jcepolicyinfo [options]", exception.getLocalizedMessage(), options(), null);
+    }
+
+    System.exit(1);
+  }
+
+  private static Options options() {
+    return new Options()
+        .addOption(Option.builder("h")
+            .longOpt("help")
+            .desc("print help")
+            .build())
+        .addOption(Option.builder("tu")
+            .longOpt("test_unlimited")
+            .desc("Test's the policy for unlimited key encryption")
+            .hasArg(false)
+            .argName("tu")
+            .build())
+        .addOption(Option.builder("lc")
+            .longOpt("list_ciphers")
+            .desc("List the ciphers allowed by the policy")
+            .hasArg(false)
+            .argName("lc")
+            .build());
+  }
+
+  /**
+   * Test if the JCE policy supports unlimited keys
+   */
+  private static void testUnlimitedKeyJCEPolicy() {
+    System.out.print("Unlimited Key JCE Policy: ");
+
+    try {
+      boolean unlimited = Cipher.getMaxAllowedKeyLength("RC5") >= 256;
+      System.out.println(unlimited);
+
+      // If the unlimited key JCE policy is installed exit with a 0 since that indicates a non-error;
+      // If the unlimited key JCE policy is not installed exit with a 1
+      System.exit(unlimited ? 0 : 1);
+    } catch (NoSuchAlgorithmException e) {
+      System.out.println("unknown [error]");
+      System.exit(-1);
+    }
+  }
+
+  /**
+   * Display the list of available ciphers and their maximum suported key lengths.
+   */
+  private static void listCiphers() {
+    System.out.println("Available ciphers:");
+
+    for (Provider provider : Security.getProviders()) {
+      String providerName = provider.getName();
+
+      for (Provider.Service service : provider.getServices()) {
+        String algorithmName = service.getAlgorithm();
+
+        if ("Cipher".equalsIgnoreCase(service.getType())) {
+          try {
+            long keylength = Cipher.getMaxAllowedKeyLength(algorithmName);
+
+            System.out.print('\t');
+            System.out.print(providerName.toLowerCase());
+            System.out.print('.');
+            System.out.print(algorithmName.toLowerCase());
+            System.out.print(": ");
+            System.out.println(keylength);
+          } catch (NoSuchAlgorithmException e) {
+            // This is unlikely since we are getting the algorithm names from the service providers.
+            // In any case, if a bad algorithm is listed it can be skipped since this is only for
+            // informational purposes.
+          }
+        }
+      }
+    }
+  }
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-common/src/main/python/resource_management/core/resources/jcepolicyinfo.py
----------------------------------------------------------------------
diff --git a/ambari-common/src/main/python/resource_management/core/resources/jcepolicyinfo.py b/ambari-common/src/main/python/resource_management/core/resources/jcepolicyinfo.py
new file mode 100644
index 0000000..a4e4f6e
--- /dev/null
+++ b/ambari-common/src/main/python/resource_management/core/resources/jcepolicyinfo.py
@@ -0,0 +1,47 @@
+#!/usr/bin/env python
+"""
+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.
+
+Ambari Agent
+
+"""
+
+from resource_management.core.resources.system import Execute
+from resource_management.core.logger import Logger
+
+
+class JcePolicyInfo:
+  def __init__(self, java_exec, java_home):
+    self.java_exec = java_exec
+    self.java_home = java_home
+    self.jar = "/var/lib/ambari-agent/tools/jcepolicyinfo.jar"
+
+  def is_unlimited_key_jce_policy(self):
+    Logger.info("Testing the JVM's JCE policy to see it if supports an unlimited key length.")
+
+    try:
+      Execute(self._command("-tu"),
+              environment={'JAVA_HOME': self.java_home},
+              logoutput=True
+              )
+      return True
+    except Exception:
+      return False
+
+
+  def _command(self, options):
+    return "{0} -jar {1} {2}".format(self.java_exec, self.jar, options)

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
index c80ebe6..edf1251 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/agent/ExecutionCommand.java
@@ -415,6 +415,7 @@ public class ExecutionCommand extends AgentCommand {
     String JAVA_VERSION = "java_version";
     String JDK_NAME = "jdk_name";
     String JCE_NAME = "jce_name";
+    String UNLIMITED_KEY_JCE_REQUIRED = "unlimited_key_jce_required";
     String MYSQL_JDBC_URL = "mysql_jdbc_url";
     String ORACLE_JDBC_URL = "oracle_jdbc_url";
     String DB_DRIVER_FILENAME = "db_driver_filename";

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
index 7cb7fce..f921fc4 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/AmbariManagementControllerImpl.java
@@ -38,6 +38,7 @@ import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SCRIPT_TYPE;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_PACKAGE_FOLDER;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.SERVICE_REPO_INFO;
+import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.UNLIMITED_KEY_JCE_REQUIRED;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.USER_GROUPS;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.USER_LIST;
 import static org.apache.ambari.server.agent.ExecutionCommand.KeyNames.VERSION;
@@ -183,6 +184,7 @@ import org.apache.ambari.server.state.ServiceOsSpecific;
 import org.apache.ambari.server.state.StackId;
 import org.apache.ambari.server.state.StackInfo;
 import org.apache.ambari.server.state.State;
+import org.apache.ambari.server.state.UnlimitedKeyJCERequirement;
 import org.apache.ambari.server.state.configgroup.ConfigGroupFactory;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinkVisibilityController;
 import org.apache.ambari.server.state.quicklinksprofile.QuickLinkVisibilityControllerFactory;
@@ -2434,6 +2436,26 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
 
     String clientsToUpdateConfigs = gson.toJson(clientsToUpdateConfigsList);
     hostParams.put(CLIENTS_TO_UPDATE_CONFIGS, clientsToUpdateConfigs);
+
+    // If we are starting a component, calculate whether the unlimited key JCE policy is
+    // required for the relevant host.  One of the following indicates that the unlimited
+    // key JCE policy is required:
+    //
+    //   * The component explicitly requires it whether Kerberos is enabled or not (example, SMARTSENSE/HST_SERVER)
+    //   * The component explicitly requires it only when Kerberos is enabled AND Kerberos is enabled (example, most components)
+    //
+    UnlimitedKeyJCERequirement unlimitedKeyJCERequirement = componentInfo.getUnlimitedKeyJCERequired();
+    // Ensure that the unlimited key requirement is set. If null, the default value should be used.
+    if(unlimitedKeyJCERequirement == null) {
+      unlimitedKeyJCERequirement = UnlimitedKeyJCERequirement.DEFAULT;
+    }
+
+    boolean unlimitedKeyJCEPolicyRequired = (UnlimitedKeyJCERequirement.ALWAYS == unlimitedKeyJCERequirement) ||
+        ((UnlimitedKeyJCERequirement.KERBEROS_ENABLED == unlimitedKeyJCERequirement) && (cluster.getSecurityType() == SecurityType.KERBEROS));
+
+    // Set/update the unlimited_key_jce_required value as needed
+    hostParams.put(UNLIMITED_KEY_JCE_REQUIRED, (unlimitedKeyJCEPolicyRequired) ? "true" : "false");
+
     execCmd.setHostLevelParams(hostParams);
 
     Map<String, String> roleParams = new TreeMap<>();

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/java/org/apache/ambari/server/stack/ComponentModule.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/stack/ComponentModule.java b/ambari-server/src/main/java/org/apache/ambari/server/stack/ComponentModule.java
index 51d9847..41b06e1 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/stack/ComponentModule.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/stack/ComponentModule.java
@@ -101,6 +101,10 @@ public class ComponentModule extends BaseModule<ComponentModule, ComponentInfo>
         componentInfo.setDecommissionAllowed(parentInfo.getDecommissionAllowed());
       }
 
+      if (componentInfo.getUnlimitedKeyJCERequired() == null) {
+        componentInfo.setUnlimitedKeyJCERequired(parentInfo.getUnlimitedKeyJCERequired());
+      }
+
       if (componentInfo.getAutoDeploy() == null) {
         componentInfo.setAutoDeploy(parentInfo.getAutoDeploy());
       }

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java b/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
index 409bcae..e038caa 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/ComponentInfo.java
@@ -1,4 +1,4 @@
-/**
+/*
  * 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
@@ -61,6 +61,9 @@ public class ComponentInfo {
   @XmlElements(@XmlElement(name = "decommissionAllowed"))
   private String decommissionAllowed;
 
+  @XmlElement(name="unlimitedKeyJCERequired")
+  private UnlimitedKeyJCERequirement unlimitedKeyJCERequired;
+
   /**
   * Added at schema ver 2
   */
@@ -150,6 +153,7 @@ public class ComponentInfo {
     versionAdvertisedField = prototype.versionAdvertisedField;
     versionAdvertisedInternal = prototype.versionAdvertisedInternal;
     decommissionAllowed = prototype.decommissionAllowed;
+    unlimitedKeyJCERequired = prototype.unlimitedKeyJCERequired;
     clientsToUpdateConfigs = prototype.clientsToUpdateConfigs;
     commandScript = prototype.commandScript;
     logs = prototype.logs;
@@ -368,6 +372,14 @@ public class ComponentInfo {
     this.decommissionAllowed = decommissionAllowed;
   }
 
+  public UnlimitedKeyJCERequirement getUnlimitedKeyJCERequired() {
+    return unlimitedKeyJCERequired;
+  }
+
+  public void setUnlimitedKeyJCERequired(UnlimitedKeyJCERequirement unlimitedKeyJCERequired) {
+    this.unlimitedKeyJCERequired = unlimitedKeyJCERequired;
+  }
+
   public void setRecoveryEnabled(boolean recoveryEnabled) {
     this.recoveryEnabled = recoveryEnabled;
   }
@@ -421,6 +433,7 @@ public class ComponentInfo {
     if (versionAdvertisedField != null ? !versionAdvertisedField.equals(that.versionAdvertisedField) : that.versionAdvertisedField != null) return false;
     if (versionAdvertisedInternal != that.versionAdvertisedInternal) return false;
     if (decommissionAllowed != null ? !decommissionAllowed.equals(that.decommissionAllowed) : that.decommissionAllowed != null) return false;
+    if (unlimitedKeyJCERequired != null ? !unlimitedKeyJCERequired.equals(that.unlimitedKeyJCERequired) : that.unlimitedKeyJCERequired != null) return false;
     if (reassignAllowed != null ? !reassignAllowed.equals(that.reassignAllowed) : that.reassignAllowed != null) return false;
     if (category != null ? !category.equals(that.category) : that.category != null) return false;
     if (clientConfigFiles != null ? !clientConfigFiles.equals(that.clientConfigFiles) : that.clientConfigFiles != null)
@@ -451,6 +464,7 @@ public class ComponentInfo {
     result = 31 * result + (deleted ? 1 : 0);
     result = 31 * result + (cardinality != null ? cardinality.hashCode() : 0);
     result = 31 * result + (decommissionAllowed != null ? decommissionAllowed.hashCode() : 0);
+    result = 31 * result + (unlimitedKeyJCERequired != null ? unlimitedKeyJCERequired.hashCode() : 0);
     result = 31 * result + (reassignAllowed != null ? reassignAllowed.hashCode() : 0);
     result = 31 * result + (commandScript != null ? commandScript.hashCode() : 0);
     result = 31 * result + (logs != null ? logs.hashCode() : 0);

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/java/org/apache/ambari/server/state/UnlimitedKeyJCERequirement.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/state/UnlimitedKeyJCERequirement.java b/ambari-server/src/main/java/org/apache/ambari/server/state/UnlimitedKeyJCERequirement.java
new file mode 100644
index 0000000..371712e
--- /dev/null
+++ b/ambari-server/src/main/java/org/apache/ambari/server/state/UnlimitedKeyJCERequirement.java
@@ -0,0 +1,42 @@
+/*
+ * 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.
+ */
+
+package org.apache.ambari.server.state;
+
+public enum UnlimitedKeyJCERequirement {
+
+  /**
+   * The unlimited key JCE policy is required, unconditionally (even if Kerberos is not enabled)
+   */
+  ALWAYS,
+
+  /**
+   * The unlimited key JCE policy is required if Kerberos is enabled
+   */
+  KERBEROS_ENABLED,
+
+  /**
+   * The unlimited key JCE policy is not required, unconditionally (even if Kerberos is enabled)
+   */
+  NEVER;
+
+  /**
+   * The default value to use if the unlimited key JCE policy requirement is not set.
+   */
+  public static final UnlimitedKeyJCERequirement DEFAULT = KERBEROS_ENABLED;
+}

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_client.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_client.py b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_client.py
index ddc8063..c50c67b 100644
--- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_client.py
+++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_client.py
@@ -40,8 +40,6 @@ class KerberosClient(KerberosScript):
     #delete krb cache to prevent using old krb tickets on fresh kerberos setup
     self.clear_tmp_cache()
 
-    self.setup_jce()
-
   def status(self, env):
     raise ClientComponentHasNoStatus()
 
@@ -72,9 +70,5 @@ class KerberosClient(KerberosScript):
   def remove_keytab(self, env):
     self.delete_keytab_file()
 
-  def download_install_jce(self, env):
-    self.setup_jce()
-
-
 if __name__ == "__main__":
   KerberosClient().execute()

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_common.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_common.py b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_common.py
index 5db62c5..8cb1f0c 100644
--- a/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_common.py
+++ b/ambari-server/src/main/resources/common-services/KERBEROS/1.10.3-10/package/scripts/kerberos_common.py
@@ -446,37 +446,4 @@ class KerberosScript(Script):
 
             curr_content['keytabs'][principal.replace("_HOST", params.hostname)] = '_REMOVED_'
 
-            self.put_structured_out(curr_content)
-
-  def setup_jce(self):
-    import params
-
-    if not params.jdk_name:
-      return
-    jce_curl_target = None
-    if params.jce_policy_zip is not None:
-      jce_curl_target = format("{artifact_dir}/{jce_policy_zip}")
-      Directory(params.artifact_dir,
-                create_parents = True,
-                )
-      File(jce_curl_target,
-           content = DownloadSource(format("{jce_location}/{jce_policy_zip}")),
-           )
-    elif params.security_enabled:
-      # Something weird is happening
-      raise Fail("Security is enabled, but JCE policy zip is not specified.")
-
-    # The extraction will occur only after the security flag is set
-    if params.security_enabled:
-      security_dir = format("{java_home}/jre/lib/security")
-
-      File([format("{security_dir}/US_export_policy.jar"), format("{security_dir}/local_policy.jar")],
-           action = "delete",
-           )
-
-      extract_cmd = ("unzip", "-o", "-j", "-q", jce_curl_target, "-d", security_dir)
-      Execute(extract_cmd,
-              only_if = format("test -e {security_dir} && test -f {jce_curl_target}"),
-              path = ['/bin/','/usr/bin'],
-              sudo = True
-      )
+            self.put_structured_out(curr_content)
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/resources/stacks/HDP/2.0.6/configuration/cluster-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/configuration/cluster-env.xml b/ambari-server/src/main/resources/stacks/HDP/2.0.6/configuration/cluster-env.xml
index 3f74aa7..733b10d 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/configuration/cluster-env.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/configuration/cluster-env.xml
@@ -126,6 +126,17 @@
     <on-ambari-upgrade add="true"/>
   </property>
   <property>
+    <name>sysprep_skip_setup_jce</name>
+    <display-name>Whether to skip setting up the unlimited key JCE policy on sysprepped cluster</display-name>
+    <value>false</value>
+    <description>Whether to skip setting up the unlimited key JCE policy on sysprepped cluster, during both fresh install and upgrades</description>
+    <value-attributes>
+      <overridable>true</overridable>
+      <type>boolean</type>
+    </value-attributes>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
     <name>smokeuser</name>
     <display-name>Smoke User</display-name>
     <value>ambari-qa</value>

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/hook.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/hook.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/hook.py
index f21e4b1..f7705c4 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/hook.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/hook.py
@@ -20,7 +20,7 @@ limitations under the License.
 import sys
 from resource_management import *
 from rack_awareness import create_topology_script_and_mapping
-from shared_initialization import setup_hadoop, setup_configs, create_javahome_symlink
+from shared_initialization import setup_hadoop, setup_configs, create_javahome_symlink, setup_unlimited_key_jce_policy
 
 class BeforeStartHook(Hook):
 
@@ -34,6 +34,7 @@ class BeforeStartHook(Hook):
     setup_configs()
     create_javahome_symlink()
     create_topology_script_and_mapping()
+    setup_unlimited_key_jce_policy()
 
 if __name__ == "__main__":
   BeforeStartHook().execute()

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/params.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/params.py
index 29c88b4..70ebfeb 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/params.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/params.py
@@ -32,10 +32,18 @@ from resource_management.libraries.functions.get_not_managed_resources import ge
 from resource_management.libraries.resources.hdfs_resource import HdfsResource
 
 config = Script.get_config()
+tmp_dir = Script.get_tmp_dir()
+artifact_dir = tmp_dir + "/AMBARI-artifacts"
+
+# Global flag enabling or disabling the sysprep feature
+host_sys_prepped = default("/hostLevelParams/host_sys_prepped", False)
 
 # Whether to skip copying fast-hdfs-resource.jar to /var/lib/ambari-agent/lib/
 # This is required if tarballs are going to be copied to HDFS, so set to False
-sysprep_skip_copy_fast_jar_hdfs = default("/configurations/cluster-env/sysprep_skip_copy_fast_jar_hdfs", False)
+sysprep_skip_copy_fast_jar_hdfs = host_sys_prepped and default("/configurations/cluster-env/sysprep_skip_copy_fast_jar_hdfs", False)
+
+# Whether to skip setting up the unlimited key JCE policy
+sysprep_skip_setup_jce = host_sys_prepped and default("/configurations/cluster-env/sysprep_skip_setup_jce", False)
 
 stack_version_unformatted = config['hostLevelParams']['stack_version']
 stack_version_formatted = format_stack_version(stack_version_unformatted)
@@ -70,6 +78,17 @@ current_service = config['serviceName']
 #security params
 security_enabled = config['configurations']['cluster-env']['security_enabled']
 
+ambari_server_resources_url = default("/hostLevelParams/jdk_location", None)
+if ambari_server_resources_url is not None and ambari_server_resources_url.endswith('/'):
+  ambari_server_resources_url = ambari_server_resources_url[:-1]
+
+# Unlimited key JCE policy params
+jce_policy_zip = default("/hostLevelParams/jce_name", None) # None when jdk is already installed by user
+unlimited_key_jce_required = default("/hostLevelParams/unlimited_key_jce_required", False)
+jdk_name = default("/hostLevelParams/jdk_name", None)
+java_home = default("/hostLevelParams/java_home", None)
+java_exec = "{0}/bin/java".format(java_home) if java_home is not None else "/bin/java"
+
 #users and groups
 has_hadoop_env = 'hadoop-env' in config['configurations']
 mapred_user = config['configurations']['mapred-env']['mapred_user']
@@ -164,9 +183,8 @@ server_db_name = config['hostLevelParams']['db_name']
 db_driver_filename = config['hostLevelParams']['db_driver_filename']
 oracle_driver_url = config['hostLevelParams']['oracle_jdbc_url']
 mysql_driver_url = config['hostLevelParams']['mysql_jdbc_url']
-ambari_server_resources = config['hostLevelParams']['jdk_location']
-oracle_driver_symlink_url = format("{ambari_server_resources}oracle-jdbc-driver.jar")
-mysql_driver_symlink_url = format("{ambari_server_resources}mysql-jdbc-driver.jar")
+oracle_driver_symlink_url = format("{ambari_server_resources_url}/oracle-jdbc-driver.jar")
+mysql_driver_symlink_url = format("{ambari_server_resources_url}/mysql-jdbc-driver.jar")
 
 ambari_db_rca_url = config['hostLevelParams']['ambari_db_rca_url'][0]
 ambari_db_rca_driver = config['hostLevelParams']['ambari_db_rca_driver'][0]
@@ -184,7 +202,6 @@ else:
   rca_prefix = rca_disabled_prefix
 
 #hadoop-env.sh
-java_home = config['hostLevelParams']['java_home']
 
 jsvc_path = "/usr/lib/bigtop-utils"
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/shared_initialization.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/shared_initialization.py b/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/shared_initialization.py
index 9783aa4..3c36962 100644
--- a/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/shared_initialization.py
+++ b/ambari-server/src/main/resources/stacks/HDP/2.0.6/hooks/before-START/scripts/shared_initialization.py
@@ -19,6 +19,7 @@ limitations under the License.
 
 import os
 from resource_management.libraries.providers.hdfs_resource import WebHDFSUtil
+from resource_management.core.resources.jcepolicyinfo import JcePolicyInfo
 
 from resource_management import *
 
@@ -196,3 +197,66 @@ def create_microsoft_r_dir():
     except Exception as exception:
       Logger.warning("Could not check the existence of {0} on DFS while starting {1}, exception: {2}".format(directory, params.current_service, str(exception)))
 
+
+def setup_unlimited_key_jce_policy():
+  """
+  Sets up the unlimited key JCE policy if needed.
+
+  The following criteria must be met:
+
+    * The cluster has not been previously prepared (sys preped) - cluster-env/sysprep_skip_setup_jce = False
+    * Ambari is managing the host's JVM - /hostLevelParams/jdk_name is set
+    * Either security is enabled OR a service requires it - /hostLevelParams/unlimited_key_jce_required = True
+    * The unlimited key JCE policy has not already been installed
+
+  If the conditions are met, the following steps are taken to install the unlimited key JCE policy JARs
+
+    1. The unlimited key JCE policy ZIP file is downloaded from the Ambari server and stored in the
+        Ambari agent's temporary directory
+    2. The existing JCE policy JAR files are deleted
+    3. The downloaded ZIP file is unzipped into the proper JCE policy directory
+
+  :return: None
+  """
+  import params
+
+  if params.sysprep_skip_setup_jce:
+    Logger.info("Skipping unlimited key JCE policy check and setup since the host is sys prepped")
+
+  elif not params.jdk_name:
+    Logger.debug("Skipping unlimited key JCE policy check and setup since the Java VM is not managed by Ambari")
+
+  elif not params.unlimited_key_jce_required:
+    Logger.debug("Skipping unlimited key JCE policy check and setup since it is not required")
+
+  else:
+    jcePolicyInfo = JcePolicyInfo(java_exec=params.java_exec, java_home=params.java_home)
+
+    if jcePolicyInfo.is_unlimited_key_jce_policy():
+      Logger.info("The unlimited key JCE policy is required, and appears to have been installed.")
+
+    elif params.jce_policy_zip is None:
+      raise Fail("The unlimited key JCE policy needs to be installed; however the JCE policy zip is not specified.")
+
+    else:
+      Logger.info("The unlimited key JCE policy is required, and needs to be installed.")
+
+      jce_zip_target = format("{artifact_dir}/{jce_policy_zip}")
+      jce_zip_source = format("{ambari_server_resources_url}/{jce_policy_zip}")
+      java_security_dir = format("{java_home}/jre/lib/security")
+
+      Logger.debug("Downloading the unlimited key JCE policy files from {0} to {1}.".format(jce_zip_source, jce_zip_target))
+      Directory(params.artifact_dir, create_parents=True)
+      File(jce_zip_target, content=DownloadSource(jce_zip_source))
+
+      Logger.debug("Removing existing JCE policy JAR files: {0}.".format(java_security_dir))
+      File(format("{java_security_dir}/US_export_policy.jar"), action="delete")
+      File(format("{java_security_dir}/local_policy.jar"), action="delete")
+
+      Logger.debug("Unzipping the unlimited key JCE policy files from {0} into {1}.".format(jce_zip_target, java_security_dir))
+      extract_cmd = ("unzip", "-o", "-j", "-q", jce_zip_target, "-d", java_security_dir)
+      Execute(extract_cmd,
+              only_if=format("test -e {java_security_dir} && test -f {jce_zip_target}"),
+              path=['/bin/', '/usr/bin'],
+              sudo=True
+              )
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/resources/stacks/HDP/3.0/configuration/cluster-env.xml
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/3.0/configuration/cluster-env.xml b/ambari-server/src/main/resources/stacks/HDP/3.0/configuration/cluster-env.xml
index 3af8f08..a79e904 100644
--- a/ambari-server/src/main/resources/stacks/HDP/3.0/configuration/cluster-env.xml
+++ b/ambari-server/src/main/resources/stacks/HDP/3.0/configuration/cluster-env.xml
@@ -126,6 +126,17 @@
     <on-ambari-upgrade add="true"/>
   </property>
   <property>
+    <name>sysprep_skip_setup_jce</name>
+    <display-name>Whether to skip setting up the unlimited key JCE policy on sysprepped cluster</display-name>
+    <value>false</value>
+    <description>Whether to skip setting up the unlimited key JCE policy on sysprepped cluster, during both fresh install and upgrades</description>
+    <value-attributes>
+      <overridable>true</overridable>
+      <type>boolean</type>
+    </value-attributes>
+    <on-ambari-upgrade add="true"/>
+  </property>
+  <property>
     <name>smokeuser</name>
     <display-name>Smoke User</display-name>
     <value>ambari-qa</value>

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/resources/stacks/HDP/3.0/hooks/before-START/scripts/hook.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/3.0/hooks/before-START/scripts/hook.py b/ambari-server/src/main/resources/stacks/HDP/3.0/hooks/before-START/scripts/hook.py
index f21e4b1..f7705c4 100644
--- a/ambari-server/src/main/resources/stacks/HDP/3.0/hooks/before-START/scripts/hook.py
+++ b/ambari-server/src/main/resources/stacks/HDP/3.0/hooks/before-START/scripts/hook.py
@@ -20,7 +20,7 @@ limitations under the License.
 import sys
 from resource_management import *
 from rack_awareness import create_topology_script_and_mapping
-from shared_initialization import setup_hadoop, setup_configs, create_javahome_symlink
+from shared_initialization import setup_hadoop, setup_configs, create_javahome_symlink, setup_unlimited_key_jce_policy
 
 class BeforeStartHook(Hook):
 
@@ -34,6 +34,7 @@ class BeforeStartHook(Hook):
     setup_configs()
     create_javahome_symlink()
     create_topology_script_and_mapping()
+    setup_unlimited_key_jce_policy()
 
 if __name__ == "__main__":
   BeforeStartHook().execute()

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/resources/stacks/HDP/3.0/hooks/before-START/scripts/params.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/3.0/hooks/before-START/scripts/params.py b/ambari-server/src/main/resources/stacks/HDP/3.0/hooks/before-START/scripts/params.py
index 455710b..5a5361c 100644
--- a/ambari-server/src/main/resources/stacks/HDP/3.0/hooks/before-START/scripts/params.py
+++ b/ambari-server/src/main/resources/stacks/HDP/3.0/hooks/before-START/scripts/params.py
@@ -32,10 +32,18 @@ from resource_management.libraries.functions.get_not_managed_resources import ge
 from resource_management.libraries.resources.hdfs_resource import HdfsResource
 
 config = Script.get_config()
+tmp_dir = Script.get_tmp_dir()
+artifact_dir = tmp_dir + "/AMBARI-artifacts"
+
+# Global flag enabling or disabling the sysprep feature
+host_sys_prepped = default("/hostLevelParams/host_sys_prepped", False)
 
 # Whether to skip copying fast-hdfs-resource.jar to /var/lib/ambari-agent/lib/
 # This is required if tarballs are going to be copied to HDFS, so set to False
-sysprep_skip_copy_fast_jar_hdfs = default("/configurations/cluster-env/sysprep_skip_copy_fast_jar_hdfs", False)
+sysprep_skip_copy_fast_jar_hdfs = host_sys_prepped and default("/configurations/cluster-env/sysprep_skip_copy_fast_jar_hdfs", False)
+
+# Whether to skip setting up the unlimited key JCE policy
+sysprep_skip_setup_jce = host_sys_prepped and default("/configurations/cluster-env/sysprep_skip_setup_jce", False)
 
 stack_version_unformatted = config['hostLevelParams']['stack_version']
 stack_version_formatted = format_stack_version(stack_version_unformatted)
@@ -64,6 +72,17 @@ current_service = config['serviceName']
 #security params
 security_enabled = config['configurations']['cluster-env']['security_enabled']
 
+ambari_server_resources_url = default("/hostLevelParams/jdk_location", None)
+if ambari_server_resources_url is not None and ambari_server_resources_url.endswith('/'):
+  ambari_server_resources_url = ambari_server_resources_url[:-1]
+
+# Unlimited key JCE policy params
+jce_policy_zip = default("/hostLevelParams/jce_name", None) # None when jdk is already installed by user
+unlimited_key_jce_required = default("/hostLevelParams/unlimited_key_jce_required", False)
+jdk_name = default("/hostLevelParams/jdk_name", None)
+java_home = default("/hostLevelParams/java_home", None)
+java_exec = "{0}/bin/java".format(java_home) if java_home is not None else "/bin/java"
+
 #users and groups
 has_hadoop_env = 'hadoop-env' in config['configurations']
 mapred_user = config['configurations']['mapred-env']['mapred_user']
@@ -158,9 +177,8 @@ server_db_name = config['hostLevelParams']['db_name']
 db_driver_filename = config['hostLevelParams']['db_driver_filename']
 oracle_driver_url = config['hostLevelParams']['oracle_jdbc_url']
 mysql_driver_url = config['hostLevelParams']['mysql_jdbc_url']
-ambari_server_resources = config['hostLevelParams']['jdk_location']
-oracle_driver_symlink_url = format("{ambari_server_resources}oracle-jdbc-driver.jar")
-mysql_driver_symlink_url = format("{ambari_server_resources}mysql-jdbc-driver.jar")
+oracle_driver_symlink_url = format("{ambari_server_resources_url}/oracle-jdbc-driver.jar")
+mysql_driver_symlink_url = format("{ambari_server_resources_url}/mysql-jdbc-driver.jar")
 
 ambari_db_rca_url = config['hostLevelParams']['ambari_db_rca_url'][0]
 ambari_db_rca_driver = config['hostLevelParams']['ambari_db_rca_driver'][0]
@@ -178,7 +196,6 @@ else:
   rca_prefix = rca_disabled_prefix
 
 #hadoop-env.sh
-java_home = config['hostLevelParams']['java_home']
 
 jsvc_path = "/usr/lib/bigtop-utils"
 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/resources/stacks/HDP/3.0/hooks/before-START/scripts/shared_initialization.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/HDP/3.0/hooks/before-START/scripts/shared_initialization.py b/ambari-server/src/main/resources/stacks/HDP/3.0/hooks/before-START/scripts/shared_initialization.py
index 5dce8e0..71161e0 100644
--- a/ambari-server/src/main/resources/stacks/HDP/3.0/hooks/before-START/scripts/shared_initialization.py
+++ b/ambari-server/src/main/resources/stacks/HDP/3.0/hooks/before-START/scripts/shared_initialization.py
@@ -19,6 +19,7 @@ limitations under the License.
 
 import os
 from resource_management.libraries.providers.hdfs_resource import WebHDFSUtil
+from resource_management.core.resources.jcepolicyinfo import JcePolicyInfo
 
 from resource_management import *
 
@@ -189,3 +190,66 @@ def create_microsoft_r_dir():
     except Exception as exception:
       Logger.warning("Could not check the existence of {0} on DFS while starting {1}, exception: {2}".format(directory, params.current_service, str(exception)))
 
+
+def setup_unlimited_key_jce_policy():
+  """
+  Sets up the unlimited key JCE policy if needed.
+
+  The following criteria must be met:
+
+    * The cluster has not been previously prepared (sys preped) - cluster-env/sysprep_skip_setup_jce = False
+    * Ambari is managing the host's JVM - /hostLevelParams/jdk_name is set
+    * Either security is enabled OR a service requires it - /hostLevelParams/unlimited_key_jce_required = True
+    * The unlimited key JCE policy has not already been installed
+
+  If the conditions are met, the following steps are taken to install the unlimited key JCE policy JARs
+
+    1. The unlimited key JCE policy ZIP file is downloaded from the Ambari server and stored in the
+        Ambari agent's temporary directory
+    2. The existing JCE policy JAR files are deleted
+    3. The downloaded ZIP file is unzipped into the proper JCE policy directory
+
+  :return: None
+  """
+  import params
+
+  if params.sysprep_skip_setup_jce:
+    Logger.info("Skipping unlimited key JCE policy check and setup since the host is sys prepped")
+
+  elif not params.jdk_name:
+    Logger.debug("Skipping unlimited key JCE policy check and setup since the Java VM is not managed by Ambari")
+
+  elif not params.unlimited_key_jce_required:
+    Logger.debug("Skipping unlimited key JCE policy check and setup since it is not required")
+
+  else:
+    jcePolicyInfo = JcePolicyInfo(java_exec=params.java_exec, java_home=params.java_home)
+
+    if jcePolicyInfo.is_unlimited_key_jce_policy():
+      Logger.info("The unlimited key JCE policy is required, and appears to have been installed.")
+
+    elif params.jce_policy_zip is None:
+      raise Fail("The unlimited key JCE policy needs to be installed; however the JCE policy zip is not specified.")
+
+    else:
+      Logger.info("The unlimited key JCE policy is required, and needs to be installed.")
+
+      jce_zip_target = format("{artifact_dir}/{jce_policy_zip}")
+      jce_zip_source = format("{ambari_server_resources_url}/{jce_policy_zip}")
+      java_security_dir = format("{java_home}/jre/lib/security")
+
+      Logger.debug("Downloading the unlimited key JCE policy files from {0} to {1}.".format(jce_zip_source, jce_zip_target))
+      Directory(params.artifact_dir, create_parents=True)
+      File(jce_zip_target, content=DownloadSource(jce_zip_source))
+
+      Logger.debug("Removing existing JCE policy JAR files: {0}.".format(java_security_dir))
+      File(format("{java_security_dir}/US_export_policy.jar"), action="delete")
+      File(format("{java_security_dir}/local_policy.jar"), action="delete")
+
+      Logger.debug("Unzipping the unlimited key JCE policy files from {0} into {1}.".format(jce_zip_target, java_security_dir))
+      extract_cmd = ("unzip", "-o", "-j", "-q", jce_zip_target, "-d", java_security_dir)
+      Execute(extract_cmd,
+              only_if=format("test -e {java_security_dir} && test -f {jce_zip_target}"),
+              path=['/bin/', '/usr/bin'],
+              sudo=True
+              )
\ No newline at end of file

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/package/scripts/kerberos_client.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/package/scripts/kerberos_client.py b/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/package/scripts/kerberos_client.py
index 2ab700d..1298f1e 100644
--- a/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/package/scripts/kerberos_client.py
+++ b/ambari-server/src/main/resources/stacks/PERF/1.0/services/KERBEROS/package/scripts/kerberos_client.py
@@ -70,9 +70,6 @@ class KerberosClient(KerberosScript):
   def remove_keytab(self, env):
     self.delete_keytab_file()
 
-  def download_install_jce(self, env):
-    pass
-
 
 if __name__ == "__main__":
   KerberosClient().execute()

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/test/java/org/apache/ambari/server/stack/ComponentModuleTest.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/java/org/apache/ambari/server/stack/ComponentModuleTest.java b/ambari-server/src/test/java/org/apache/ambari/server/stack/ComponentModuleTest.java
index 6e37ded..746b974 100644
--- a/ambari-server/src/test/java/org/apache/ambari/server/stack/ComponentModuleTest.java
+++ b/ambari-server/src/test/java/org/apache/ambari/server/stack/ComponentModuleTest.java
@@ -36,6 +36,7 @@ import org.apache.ambari.server.state.CommandScriptDefinition;
 import org.apache.ambari.server.state.ComponentInfo;
 import org.apache.ambari.server.state.CustomCommandDefinition;
 import org.apache.ambari.server.state.DependencyInfo;
+import org.apache.ambari.server.state.UnlimitedKeyJCERequirement;
 import org.junit.Test;
 
 /**
@@ -448,6 +449,40 @@ public class ComponentModuleTest {
   }
 
   @Test
+  public void testResolve_UnlimitedKeyJCERequiredInheritance(){
+    List<ComponentInfo> components = createComponentInfo(2);
+    ComponentInfo info = components.get(0);
+    ComponentInfo parentInfo = components.get(1);
+
+    //parent has it, child doesn't
+    parentInfo.setUnlimitedKeyJCERequired(UnlimitedKeyJCERequirement.ALWAYS);
+    assertSame(UnlimitedKeyJCERequirement.ALWAYS, resolveComponent(info, parentInfo).getModuleInfo().getUnlimitedKeyJCERequired());
+  }
+
+  @Test
+  public void testResolve_UnlimitedKeyJCERequired(){
+    List<ComponentInfo> components = createComponentInfo(2);
+    ComponentInfo info = components.get(0);
+    ComponentInfo parentInfo = components.get(1);
+
+    //parent doesn't have it, child has it
+    info.setUnlimitedKeyJCERequired(UnlimitedKeyJCERequirement.NEVER);
+    assertSame(UnlimitedKeyJCERequirement.NEVER, resolveComponent(info, parentInfo).getModuleInfo().getUnlimitedKeyJCERequired());
+  }
+
+  @Test
+  public void testResolve_UnlimitedKeyJCERequiredOverwrite(){
+    List<ComponentInfo> components = createComponentInfo(2);
+    ComponentInfo info = components.get(0);
+    ComponentInfo parentInfo = components.get(1);
+
+    //parent has it, child overwrites it
+    parentInfo.setUnlimitedKeyJCERequired(UnlimitedKeyJCERequirement.KERBEROS_ENABLED);
+    info.setUnlimitedKeyJCERequired(UnlimitedKeyJCERequirement.ALWAYS);
+    assertSame(UnlimitedKeyJCERequirement.ALWAYS, resolveComponent(info, parentInfo).getModuleInfo().getUnlimitedKeyJCERequired());
+  }
+
+  @Test
   public void testResolve_Reassignable(){
     List<ComponentInfo> components = createComponentInfo(2);
     ComponentInfo info = components.get(0);

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/test/python/stacks/2.0.6/configs/secured_no_jce_name.json
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/configs/secured_no_jce_name.json b/ambari-server/src/test/python/stacks/2.0.6/configs/secured_no_jce_name.json
index fa4cc9d..a0dd539 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/configs/secured_no_jce_name.json
+++ b/ambari-server/src/test/python/stacks/2.0.6/configs/secured_no_jce_name.json
@@ -6,7 +6,8 @@
         "not_managed_hdfs_path_list": "[\"/apps/hive/warehouse\",\"/apps/falcon\",\"/mr-history/done\",\"/app-logs\",\"/tmp\"]",
         "jdk_location": "http://c6401.ambari.apache.org:8080/resources/",
         "ambari_db_rca_password": "mapred", 
-        "ambari_db_rca_url": "jdbc:postgresql://c6401.ambari.apache.org/ambarirca", 
+        "ambari_db_rca_url": "jdbc:postgresql://c6401.ambari.apache.org/ambarirca",
+        "unlimited_key_jce_required" : "true",
         "oracle_jdbc_url": "http://c6401.ambari.apache.org:8080/resources//ojdbc6.jar",
         "repo_info": "[{\"baseUrl\":\"http://public-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.0.6.0\",\"osType\":\"centos6\",\"repoId\":\"HDP-2.0.8\",\"repoName\":\"HDP\",\"defaultBaseUrl\":\"http://public-repo-1.hortonworks.com/HDP/centos6/2.x/updates/2.0.6.0\"}]", 
         "package_list": "[{\"type\":\"rpm\",\"name\":\"hadoop-yarn\"},{\"type\":\"rpm\",\"name\":\"hadoop-yarn-nodemanager\"},{\"type\":\"rpm\",\"name\":\"hadoop-mapreduce\"},{\"type\":\"rpm\",\"name\":\"hadoop-yarn-proxyserver\"},{\"type\":\"rpm\",\"name\":\"hadoop-yarn-resourcemanager\"}]", 
@@ -35,6 +36,19 @@
     "taskId": 186, 
     "public_hostname": "c6401.ambari.apache.org", 
     "configurations": {
+        "cluster-env": {
+            "managed_hdfs_resource_property_names": "",
+            "security_enabled": "true",
+            "ignore_groupsusers_create": "false",
+            "smokeuser": "ambari-qa",
+            "smokeuser_principal_name": "ambari-qa@EXAMPLE.COM",
+            "kerberos_domain": "EXAMPLE.COM",
+            "user_group": "hadoop",
+            "smokeuser_keytab": "/etc/security/keytabs/smokeuser.headless.keytab",
+            "kinit_path_local": "/usr/bin",
+            "manage_dirs_on_root": "true",
+            "ignore_bad_mounts": "false"
+        },
         "mapred-site": {
             "mapreduce.jobhistory.address": "c6402.ambari.apache.org:10020", 
             "mapreduce.jobhistory.webapp.spnego-keytab-file": "/etc/security/keytabs/spnego.service.keytab", 

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/test/python/stacks/2.0.6/hooks/before-START/test_before_start.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.0.6/hooks/before-START/test_before_start.py b/ambari-server/src/test/python/stacks/2.0.6/hooks/before-START/test_before_start.py
index 30561ac..4f62ace 100644
--- a/ambari-server/src/test/python/stacks/2.0.6/hooks/before-START/test_before_start.py
+++ b/ambari-server/src/test/python/stacks/2.0.6/hooks/before-START/test_before_start.py
@@ -21,6 +21,7 @@ limitations under the License.
 from stacks.utils.RMFTestCase import *
 from mock.mock import MagicMock, call, patch
 from resource_management import Hook
+from resource_management.core.exceptions import Fail
 import json
 
 @patch("platform.linux_distribution", new = MagicMock(return_value="Linux"))
@@ -258,10 +259,10 @@ class TestHookBeforeStart(RMFTestCase):
     config_file = "stacks/2.0.6/configs/default.json"
     with open(config_file, "r") as f:
       default_json = json.load(f)
-      
+
     default_json['serviceName'] = 'HDFS'
     default_json['configurations']['core-site']['net.topology.script.file.name'] = '/home/myhadoop/hadoop/conf.hadoop/topology_script.py'
-    
+
     self.executeScript("2.0.6/hooks/before-START/scripts/hook.py",
                        classname="BeforeStartHook",
                        command="hook",
@@ -335,14 +336,13 @@ class TestHookBeforeStart(RMFTestCase):
                               )
     self.assertNoMoreResources()
 
-
-def test_that_jce_is_required_in_secured_cluster(self):
-  try:
-    self.executeScript("2.0.6/hooks/before-START/scripts/hook.py",
-                       classname="BeforeStartHook",
-                       command="hook",
-                       config_file="secured_no_jce_name.json"
-    )
-    self.fail("Should throw an exception")
-  except Fail:
-    pass  # Expected
+  def test_that_jce_is_required_in_secured_cluster(self):
+    try:
+      self.executeScript("2.0.6/hooks/before-START/scripts/hook.py",
+                         classname="BeforeStartHook",
+                         command="hook",
+                         config_file="secured_no_jce_name.json"
+      )
+      self.fail("Should throw an exception")
+    except Fail:
+      pass  # Expected

http://git-wip-us.apache.org/repos/asf/ambari/blob/9112148e/ambari-server/src/test/python/stacks/2.2/KERBEROS/test_kerberos_client.py
----------------------------------------------------------------------
diff --git a/ambari-server/src/test/python/stacks/2.2/KERBEROS/test_kerberos_client.py b/ambari-server/src/test/python/stacks/2.2/KERBEROS/test_kerberos_client.py
index 444fae6..6727b2f 100644
--- a/ambari-server/src/test/python/stacks/2.2/KERBEROS/test_kerberos_client.py
+++ b/ambari-server/src/test/python/stacks/2.2/KERBEROS/test_kerberos_client.py
@@ -83,27 +83,6 @@ class TestKerberosClient(RMFTestCase):
                               group='root',
                               mode=0644)
 
-  def test_configure_unmanaged_kdc_and_krb5conf(self):
-    json_data = use_cases.get_unmanged_krb5conf_use_case()
-
-
-    self.executeScript(self.COMMON_SERVICES_PACKAGE_DIR + "/scripts/kerberos_client.py",
-                       classname="KerberosClient",
-                       command="configure",
-                       config_dict=json_data,
-                       stack_version = self.STACK_VERSION,
-                       target = RMFTestCase.TARGET_COMMON_SERVICES
-    )
-    self.assertResourceCalled('Directory', '/var/lib/ambari-agent/tmp/curl_krb_cache', action=["delete"],
-                              )
-    self.assertResourceCalled('Directory', '/tmp/AMBARI-artifacts/',
-                              create_parents = True,
-                              )
-    self.assertResourceCalled('File', '/tmp/AMBARI-artifacts//UnlimitedJCEPolicyJDK7.zip',
-                            content = DownloadSource('http://c6401.ambari.apache.org:8080/resources//UnlimitedJCEPolicyJDK7.zip'),
-                            )
-    self.assertNoMoreResources()
-
   def test_configure_unmanaged_ad(self):
     json_data = use_cases.get_unmanged_ad_use_case()