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 2015/10/07 17:17:56 UTC

[2/2] ambari git commit: AMBARI-13292. Kerberos: Retain KDC admin credentials (rlevas)

AMBARI-13292. Kerberos: Retain KDC admin credentials (rlevas)


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

Branch: refs/heads/trunk
Commit: 44c2646668f29c7e79c8ffb3ff290bed1f53ed0d
Parents: 78e49db
Author: Robert Levas <rl...@hortonworks.com>
Authored: Wed Oct 7 08:17:41 2015 -0700
Committer: Robert Levas <rl...@hortonworks.com>
Committed: Wed Oct 7 08:17:45 2015 -0700

----------------------------------------------------------------------
 .../AmbariManagementControllerImpl.java         |  12 +-
 .../server/controller/KerberosHelper.java       |  33 +-
 .../server/controller/KerberosHelperImpl.java   | 183 +++--------
 .../kerberos/ADKerberosOperationHandler.java    |  28 +-
 .../kerberos/KerberosCredential.java            | 303 -------------------
 .../kerberos/KerberosOperationHandler.java      |  79 +++--
 .../kerberos/KerberosServerAction.java          |   3 +-
 .../kerberos/MITKerberosOperationHandler.java   | 182 +++++------
 .../server/controller/KerberosHelperTest.java   | 196 +++++++-----
 .../ADKerberosOperationHandlerTest.java         |  19 +-
 .../kerberos/KerberosCredentialTest.java        | 103 -------
 .../kerberos/KerberosOperationHandlerTest.java  |  31 +-
 .../kerberos/KerberosServerActionTest.java      |  10 +-
 .../MITKerberosOperationHandlerTest.java        |  25 +-
 14 files changed, 343 insertions(+), 864 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/44c26466/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 436fa3c..de0ae28 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
@@ -114,12 +114,12 @@ import org.apache.ambari.server.security.authorization.AuthorizationHelper;
 import org.apache.ambari.server.security.authorization.Group;
 import org.apache.ambari.server.security.authorization.User;
 import org.apache.ambari.server.security.authorization.Users;
+import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
 import org.apache.ambari.server.security.encryption.CredentialStoreService;
 import org.apache.ambari.server.security.encryption.CredentialStoreType;
 import org.apache.ambari.server.security.ldap.AmbariLdapDataPopulator;
 import org.apache.ambari.server.security.ldap.LdapBatchDto;
 import org.apache.ambari.server.security.ldap.LdapSyncDto;
-import org.apache.ambari.server.serveraction.kerberos.KerberosCredential;
 import org.apache.ambari.server.serveraction.kerberos.KerberosInvalidConfigurationException;
 import org.apache.ambari.server.serveraction.kerberos.KerberosOperationException;
 import org.apache.ambari.server.stageplanner.RoleGraph;
@@ -1266,9 +1266,9 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
 
       Map<String, Object> sessionAttributes = request.getSessionAttributes();
 
-      // TODO: Create REST API entry point to securely set credentials in the CredentialProvider then
-      // TODO: remove this block to _clean_ the session attributes and store any KDC administrator
-      // TODO: credentials in the secure credential provider facility.
+      // TODO: Once the UI uses the Credential Resource API, remove this block to _clean_ the
+      // TODO: session attributes and store any KDC administrator credentials in the secure
+      // TODO: credential provider facility.
       // For now, to keep things backwards compatible, get and remove the KDC administrator credentials
       // from the session attributes and store them in the CredentialsProvider. The KDC administrator
       // credentials are prefixed with kdc_admin/. The following attributes are expected, if setting
@@ -1300,7 +1300,9 @@ public class AmbariManagementControllerImpl implements AmbariManagementControlle
 
         if(principal != null) {
           // The KDC admin principal exists... set the credentials in the credentials store
-          kerberosHelper.setKDCCredentials(new KerberosCredential(principal, password, null));
+          credentialStoreService.setCredential(cluster.getClusterName(),
+              KerberosHelper.KDC_ADMINISTRATOR_CREDENTIAL_ALIAS,
+              new PrincipalKeyCredential(principal, password), CredentialStoreType.TEMPORARY);
         }
 
         sessionAttributes = cleanedSessionAttributes;

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c26466/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
index c39485b..f87fb04 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelper.java
@@ -20,8 +20,8 @@ package org.apache.ambari.server.controller;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.controller.internal.RequestStageContainer;
+import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
 import org.apache.ambari.server.serveraction.kerberos.KerberosAdminAuthenticationException;
-import org.apache.ambari.server.serveraction.kerberos.KerberosCredential;
 import org.apache.ambari.server.serveraction.kerberos.KerberosIdentityDataFileWriter;
 import org.apache.ambari.server.serveraction.kerberos.KerberosInvalidConfigurationException;
 import org.apache.ambari.server.serveraction.kerberos.KerberosMissingAdminCredentialsException;
@@ -52,6 +52,10 @@ public interface KerberosHelper {
    * name of property which states whether kerberos is enabled
    */
   String SECURITY_ENABLED_PROPERTY_NAME = "security_enabled";
+  /**
+   * The alias to assign to the KDC administrator credential Keystore item
+   */
+  String KDC_ADMINISTRATOR_CREDENTIAL_ALIAS = "kdc.admin.credential";
 
   /**
    * Toggles Kerberos security to enable it or remove it depending on the state of the cluster.
@@ -417,33 +421,14 @@ public interface KerberosHelper {
       throws AmbariException;
 
   /**
-   * Sets the KDC administrator credentials.
-   * <p/>
-   * It is up to the implementation to determine how to store
-   * these credentials and for how long.
-   *
-   * @param credentials the KDC administrator credentials
-   * @throws AmbariException if an error occurs while storing the credentials
-   */
-  void setKDCCredentials(KerberosCredential credentials) throws AmbariException;
-
-  /**
-   * Removes the previously set KDC administrator credentials.
-   *
-   * @throws AmbariException if an error occurs while removing the credentials
-   * @see KerberosHelper#setKDCCredentials(KerberosCredential)
-   */
-  void removeKDCCredentials() throws AmbariException;
-
-  /**
-   * Gets the previously stored KDC administrator credentials.
+   * Sets the previously stored KDC administrator credentials.
    *
-   * @return a KerberosCredential or null, if the KDC administrator credentials have not be set or
+   * @return a PrincipalKeyCredential or null, if the KDC administrator credentials have not be set or
    * have been removed
    * @throws AmbariException if an error occurs while retrieving the credentials
-   * @see KerberosHelper#setKDCCredentials(KerberosCredential)
+   * @param clusterName
    */
-  KerberosCredential getKDCCredentials() throws AmbariException;
+  PrincipalKeyCredential getKDCAdministratorCredentials(String clusterName) throws AmbariException;
 
   /**
    * Command to invoke against the Ambari backend.

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c26466/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
index d428174..dbb59bd 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/controller/KerberosHelperImpl.java
@@ -31,7 +31,6 @@ import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.concurrent.TimeUnit;
 import java.util.regex.Matcher;
 import java.util.regex.Pattern;
 
@@ -63,8 +62,7 @@ import org.apache.ambari.server.metadata.RoleCommandOrder;
 import org.apache.ambari.server.security.SecurePasswordHelper;
 import org.apache.ambari.server.security.credential.Credential;
 import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
-import org.apache.ambari.server.security.encryption.InMemoryCredentialStore;
-import org.apache.ambari.server.security.encryption.MasterKeyServiceImpl;
+import org.apache.ambari.server.security.encryption.CredentialStoreService;
 import org.apache.ambari.server.serveraction.ServerAction;
 import org.apache.ambari.server.serveraction.kerberos.CleanupServerAction;
 import org.apache.ambari.server.serveraction.kerberos.CreateKeytabFilesServerAction;
@@ -73,7 +71,6 @@ import org.apache.ambari.server.serveraction.kerberos.DestroyPrincipalsServerAct
 import org.apache.ambari.server.serveraction.kerberos.FinalizeKerberosServerAction;
 import org.apache.ambari.server.serveraction.kerberos.KDCType;
 import org.apache.ambari.server.serveraction.kerberos.KerberosAdminAuthenticationException;
-import org.apache.ambari.server.serveraction.kerberos.KerberosCredential;
 import org.apache.ambari.server.serveraction.kerberos.KerberosIdentityDataFileWriter;
 import org.apache.ambari.server.serveraction.kerberos.KerberosIdentityDataFileWriterFactory;
 import org.apache.ambari.server.serveraction.kerberos.KerberosInvalidConfigurationException;
@@ -131,17 +128,6 @@ public class KerberosHelperImpl implements KerberosHelper {
   private static final Logger LOG = LoggerFactory.getLogger(KerberosHelperImpl.class);
 
   /**
-   * The alias to assign to the KDC administrator credential Keystore item
-   */
-  public static final String KDC_ADMINISTRATOR_CREDENTIAL_ALIAS = "kdc_admin";
-
-  /**
-   * The default length of time (in minutes) to store the KDC administrator credentials before
-   * automatically removing them.
-   */
-  private static final long DEFAULT_KDC_ADMINISTRATOR_CREDENTIALS_RETENTION_MINUTES = 90;
-
-  /**
    * Regular expression pattern used to parse auth_to_local property specifications into the following
    * parts:
    * <ul>
@@ -198,24 +184,17 @@ public class KerberosHelperImpl implements KerberosHelper {
   private SecurePasswordHelper securePasswordHelper;
 
   /**
-   * Used to get kerberos descriptors associated with the cluster or stack.
-   * Currently not available via injection.
+   * The secure storage facility to use to store KDC administrator credential.
    */
-  private static ClusterController clusterController = null;
+  @Inject
+  private CredentialStoreService credentialStoreService;
 
   /**
-   * The secure storage facility to use to store KDC administrator credentials. This implementation
-   * is uses an InMemoryCredentialStore to keep the credentials in memory rather than
-   * storing them on disk.
+   * Used to get kerberos descriptors associated with the cluster or stack.
+   * Currently not available via injection.
    */
-  private final InMemoryCredentialStore kdcCredentialStoreService;
+  private static ClusterController clusterController = null;
 
-  /**
-   * Default KerberosHelperImpl constructor
-   */
-  public KerberosHelperImpl() {
-    kdcCredentialStoreService = new InMemoryCredentialStore(DEFAULT_KDC_ADMINISTRATOR_CREDENTIALS_RETENTION_MINUTES, TimeUnit.MINUTES, true);
-  }
 
   @Override
   public RequestStageContainer toggleKerberos(Cluster cluster, SecurityType securityType,
@@ -442,12 +421,12 @@ public class KerberosHelperImpl implements KerberosHelper {
         for (String authToLocalProperty : authToLocalPropertiesToSet) {
           Matcher m = AUTH_TO_LOCAL_PROPERTY_SPECIFICATION_PATTERN.matcher(authToLocalProperty);
 
-          if(m.matches()) {
+          if (m.matches()) {
             AuthToLocalBuilder builder = authToLocalBuilder.copy();
             String configType = m.group(1);
             String propertyName = m.group(2);
 
-            if(configType == null) {
+            if (configType == null) {
               configType = "";
             }
 
@@ -916,62 +895,23 @@ public class KerberosHelperImpl implements KerberosHelper {
   }
 
   /**
-   * Sets the KDC administrator credentials.
-   * <p/>
-   * This implementation stores the credentials in a secure CredentialStoreService implementation and
-   * sets a timer to remove the stored credentials after the retention period expires.
-   * <p/>
-   * If existing credentials are stored when setting new credentials, the previously stored data will
-   * be cleared out. Each time credentials are set, a new master key is generated and used to encrypt
-   * the data.
-   *
-   * @param credentials the KDC administrator credentials
-   * @throws AmbariException if an error occurs while storing the credentials
-   */
-  @Override
-  public void setKDCCredentials(KerberosCredential credentials) throws AmbariException {
-    kdcCredentialStoreService.removeCredential(KDC_ADMINISTRATOR_CREDENTIAL_ALIAS);
-
-    if (credentials != null) {
-      kdcCredentialStoreService.setMasterKeyService(new MasterKeyServiceImpl(securePasswordHelper.createSecurePassword()));
-      kdcCredentialStoreService.addCredential(KDC_ADMINISTRATOR_CREDENTIAL_ALIAS, new PrincipalKeyCredential(credentials.getPrincipal(), credentials.getPassword()));
-    }
-  }
-
-  /**
-   * Removes the previously set KDC administrator credentials.
-   * <p/>
-   * This implementation clears the secure CredentialsStoreService instance, removing the previously
-   * generated master key and credentials data.  The configured timer to enforce retention time is
-   * cleared and set to null.
-   *
-   * @throws AmbariException if an error occurs while removing the credentials
-   * @see KerberosHelper#setKDCCredentials(KerberosCredential)
-   */
-  @Override
-  public void removeKDCCredentials() throws AmbariException {
-    kdcCredentialStoreService.removeCredential(KDC_ADMINISTRATOR_CREDENTIAL_ALIAS);
-  }
-
-  /**
-   * Gets the previously stored KDC administrator credentials.
+   * Sets the previously stored KDC administrator credential.
    * <p/>
    * This implementation accesses the secure CredentialStoreService instance to get the data.
    *
-   * @return a KerberosCredential or null, if the KDC administrator credentials have not be set or
-   * have been removed
+   * @param clusterName the name of the relevant cluster
+   * @return a PrincipalKeyCredential or null, if the KDC administrator credential is not available
    * @throws AmbariException if an error occurs while retrieving the credentials
-   * @see KerberosHelper#setKDCCredentials(KerberosCredential)
    */
   @Override
-  public KerberosCredential getKDCCredentials() throws AmbariException {
-    Credential credentials = kdcCredentialStoreService.getCredential(KDC_ADMINISTRATOR_CREDENTIAL_ALIAS);
+  public PrincipalKeyCredential getKDCAdministratorCredentials(String clusterName) throws AmbariException {
+    Credential credentials = credentialStoreService.getCredential(clusterName, KDC_ADMINISTRATOR_CREDENTIAL_ALIAS);
 
     if (credentials instanceof PrincipalKeyCredential) {
-      PrincipalKeyCredential principalKeyCredential = (PrincipalKeyCredential) credentials;
-      return new KerberosCredential(principalKeyCredential.getPrincipal(), principalKeyCredential.getKey(), null);
-    } else
+      return (PrincipalKeyCredential) credentials;
+    } else {
       return null;
+    }
   }
 
   /**
@@ -993,15 +933,15 @@ public class KerberosHelperImpl implements KerberosHelper {
     }
 
     if (kerberosDetails.manageIdentities()) {
-      KerberosCredential kerberosCredentials = getKDCCredentials();
-      if (kerberosCredentials == null) {
+      PrincipalKeyCredential credentials = getKDCAdministratorCredentials(cluster.getClusterName());
+      if (credentials == null) {
         throw new KerberosMissingAdminCredentialsException(
             "Missing KDC administrator credentials.\n" +
-                "The KDC administrator credentials must be set in session by updating the relevant Cluster resource." +
-                "This may be done by issuing a PUT to the api/v1/clusters/(cluster name) API entry point with the following payload:\n" +
+                "The KDC administrator credentials must be set as a persisted or temporary credential resource." +
+                "This may be done by issuing a POST to the /api/v1/clusters/:clusterName/credentials/kdc.admin.credential API entry point with the following payload:\n" +
                 "{\n" +
-                "  \"session_attributes\" : {\n" +
-                "    \"kerberos_admin\" : {\"principal\" : \"(PRINCIPAL)\", \"password\" : \"(PASSWORD)\"}\n" +
+                "  \"Credential\" : {\n" +
+                "    \"principal\" : \"(PRINCIPAL)\", \"key\" : \"(PASSWORD)\", \"type\" : \"(persisted|temporary)\"}\n" +
                 "  }\n" +
                 "}"
         );
@@ -1013,17 +953,17 @@ public class KerberosHelperImpl implements KerberosHelper {
         } else {
           boolean missingCredentials = false;
           try {
-            operationHandler.open(kerberosCredentials, kerberosDetails.getDefaultRealm(), kerberosDetails.getKerberosEnvProperties());
+            operationHandler.open(credentials, kerberosDetails.getDefaultRealm(), kerberosDetails.getKerberosEnvProperties());
             // todo: this is really odd that open doesn't throw an exception if the credentials are missing
             missingCredentials = !operationHandler.testAdministratorCredentials();
           } catch (KerberosAdminAuthenticationException e) {
             throw new KerberosAdminAuthenticationException(
                 "Invalid KDC administrator credentials.\n" +
-                    "The KDC administrator credentials must be set in session by updating the relevant Cluster resource." +
-                    "This may be done by issuing a PUT to the api/v1/clusters/(cluster name) API entry point with the following payload:\n" +
+                    "The KDC administrator credentials must be set as a persisted or temporary credential resource." +
+                    "This may be done by issuing a POST (or PUT for updating) to the /api/v1/clusters/:clusterName/credentials/kdc.admin.credential API entry point with the following payload:\n" +
                     "{\n" +
-                    "  \"session_attributes\" : {\n" +
-                    "    \"kerberos_admin\" : {\"principal\" : \"(PRINCIPAL)\", \"password\" : \"(PASSWORD)\"}\n" +
+                    "  \"Credential\" : {\n" +
+                    "    \"principal\" : \"(PRINCIPAL)\", \"key\" : \"(PASSWORD)\", \"type\" : \"(persisted|temporary)\"}\n" +
                     "  }\n" +
                     "}", e);
           } catch (KerberosKDCConnectionException e) {
@@ -1055,11 +995,11 @@ public class KerberosHelperImpl implements KerberosHelper {
           if (missingCredentials) {
             throw new KerberosMissingAdminCredentialsException(
                 "Invalid KDC administrator credentials.\n" +
-                    "The KDC administrator credentials must be set in session by updating the relevant Cluster resource." +
-                    "This may be done by issuing a PUT to the api/v1/clusters/(cluster name) API entry point with the following payload:\n" +
+                    "The KDC administrator credentials must be set as a persisted or temporary credential resource." +
+                    "This may be done by issuing a POST to the /api/v1/clusters/:clusterName/credentials/kdc.admin.credential API entry point with the following payload:\n" +
                     "{\n" +
-                    "  \"session_attributes\" : {\n" +
-                    "    \"kerberos_admin\" : {\"principal\" : \"(PRINCIPAL)\", \"password\" : \"(PASSWORD)\"}\n" +
+                    "  \"Credential\" : {\n" +
+                    "    \"principal\" : \"(PRINCIPAL)\", \"key\" : \"(PASSWORD)\", \"type\" : \"(persisted|temporary)\"}\n" +
                     "  }\n" +
                     "}"
             );
@@ -1220,25 +1160,6 @@ public class KerberosHelperImpl implements KerberosHelper {
     return requestStageContainer;
   }
 
-  private int filteredIdentitiesCount(List<KerberosIdentityDescriptor> identities, Collection<String> identityFilter) {
-
-    if ((identities == null) || identities.isEmpty()) {
-      return 0;
-    } else if (identityFilter == null) {
-      return identities.size();
-    } else {
-      int count = 0;
-
-      for (KerberosIdentityDescriptor identity : identities) {
-        if (identityFilter.contains(identity.getName())) {
-          count++;
-        }
-      }
-
-      return count;
-    }
-  }
-
 
   /**
    * Performs operations needed to process Kerberos related tasks to manage a (unique) test identity
@@ -1399,7 +1320,7 @@ public class KerberosHelperImpl implements KerberosHelper {
             }
           }
 
-          // If there are ServiceComponentHosts to process, make sure the administrator credentials
+          // If there are ServiceComponentHosts to process, make sure the administrator credential
           // are available
           if (!serviceComponentHostsToProcess.isEmpty()) {
             try {
@@ -1743,40 +1664,6 @@ public class KerberosHelperImpl implements KerberosHelper {
   }
 
   /**
-   * Using the session data from the relevant Cluster object, creates a KerberosCredential,
-   * serializes, and than encrypts it.
-   * <p/>
-   * Since the relevant data is stored in the HTTPSession (which relies on ThreadLocalStorage),
-   * it needs to be retrieved now and placed in the action's command parameters so it will be
-   * available when needed.  Because command parameters are stored in plaintext in the Ambari database,
-   * this (sensitive) data needs to be encrypted, however it needs to be done using a key the can be
-   * recreated sometime later when the data needs to be access. Since it is expected that the Cluster
-   * object will be able now and later, the hashcode of this object is used to build the key - it
-   * is expected that the same instance will be retrieved from the Clusters instance, thus yielding
-   * the same hashcode value.
-   * <p/>
-   * If the Ambari server architecture changes, this will need to be revisited.
-   *
-   * @param cluster the relevant Cluster
-   * @return a serialized and encrypted KerberosCredential, or null if administrator data is not found
-   * @throws AmbariException
-   */
-  private String getEncryptedAdministratorCredentials(Cluster cluster) throws AmbariException {
-    String encryptedAdministratorCredentials = null;
-
-    Map<String, Object> sessionAttributes = cluster.getSessionAttributes();
-    if (sessionAttributes != null) {
-      KerberosCredential credential = KerberosCredential.fromMap(sessionAttributes, "kerberos_admin/");
-      if (credential != null) {
-        byte[] key = Integer.toHexString(cluster.hashCode()).getBytes();
-        encryptedAdministratorCredentials = credential.encrypt(key);
-      }
-    }
-
-    return encryptedAdministratorCredentials;
-  }
-
-  /**
    * Given a Collection of ServiceComponentHosts generates a unique list of hosts.
    *
    * @param serviceComponentHosts a Collection of ServiceComponentHosts from which to to retrieve host names
@@ -2690,7 +2577,7 @@ public class KerberosHelperImpl implements KerberosHelper {
 
       commandParameters.put(KerberosServerAction.REGENERATE_ALL, (regenerateAllKeytabs) ? "true" : "false");
 
-      if(updateConfigurations) {
+      if (updateConfigurations) {
         commandParameters.put(KerberosServerAction.UPDATE_CONFIGURATION_NOTE, "Updated Kerberos-related configurations");
         commandParameters.put(KerberosServerAction.UPDATE_CONFIGURATIONS, "true");
       }
@@ -2719,7 +2606,7 @@ public class KerberosHelperImpl implements KerberosHelper {
             hostParamsJson, commandParameters, roleCommandOrder, requestStageContainer, hostsWithValidKerberosClient);
       }
 
-      if(updateConfigurations) {
+      if (updateConfigurations) {
         // *****************************************************************
         // Create stage to update configurations of services
         addUpdateConfigurationsStage(cluster, clusterHostInfoJson, hostParamsJson, event, commandParameters,

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c26466/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java
index fb21883..a1e1544 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/ADKerberosOperationHandler.java
@@ -21,7 +21,9 @@ package org.apache.ambari.server.serveraction.kerberos;
 
 import com.google.common.reflect.TypeToken;
 import com.google.gson.Gson;
+import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
 import org.apache.commons.codec.digest.DigestUtils;
+import org.apache.commons.lang.StringUtils;
 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory;
 import org.apache.velocity.VelocityContext;
@@ -116,25 +118,25 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
    * <li>container_dn - DN of the container in ldap back end where principals would be created</li>
    * </il>
    *
-   * @param administratorCredentials a KerberosCredential containing the administrative credentials
-   *                                 for the relevant KDC
-   * @param realm                    a String declaring the default Kerberos realm (or domain)
-   * @param kerberosConfiguration    a Map of key/value pairs containing data from the kerberos-env configuration set
+   * @param administratorCredential a PrincipalKeyCredential containing the administrative credential
+   *                                for the relevant KDC
+   * @param realm                   a String declaring the default Kerberos realm (or domain)
+   * @param kerberosConfiguration   a Map of key/value pairs containing data from the kerberos-env configuration set
    * @throws KerberosKDCConnectionException       if a connection to the KDC cannot be made
    * @throws KerberosAdminAuthenticationException if the administrator credentials fail to authenticate
    * @throws KerberosRealmException               if the realm does not map to a KDC
    * @throws KerberosOperationException           if an unexpected error occurred
    */
   @Override
-  public void open(KerberosCredential administratorCredentials, String realm,
+  public void open(PrincipalKeyCredential administratorCredential, String realm,
                    Map<String, String> kerberosConfiguration) throws KerberosOperationException {
 
     if (isOpen()) {
       close();
     }
 
-    if (administratorCredentials == null) {
-      throw new KerberosAdminAuthenticationException("administrator credentials not provided");
+    if (administratorCredential == null) {
+      throw new KerberosAdminAuthenticationException("administrator credential not provided");
     }
     if (realm == null) {
       throw new KerberosRealmException("realm not provided");
@@ -159,7 +161,7 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
       throw new KerberosLDAPContainerException("principalContainerDn is not a valid LDAP name", e);
     }
 
-    setAdministratorCredentials(administratorCredentials);
+    setAdministratorCredential(administratorCredential);
     setDefaultRealm(realm);
     setKeyEncryptionTypes(translateEncryptionTypes(kerberosConfiguration.get(KERBEROS_ENV_ENCRYPTION_TYPES), "\\s+"));
 
@@ -422,13 +424,13 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
    * @throws KerberosOperationException           if an unexpected error occurred
    */
   protected LdapContext createLdapContext() throws KerberosOperationException {
-    KerberosCredential administratorCredentials = getAdministratorCredentials();
+    PrincipalKeyCredential administratorCredential = getAdministratorCredential();
 
     Properties properties = new Properties();
     properties.put(Context.INITIAL_CONTEXT_FACTORY, LDAP_CONTEXT_FACTORY_CLASS);
     properties.put(Context.PROVIDER_URL, ldapUrl);
-    properties.put(Context.SECURITY_PRINCIPAL, administratorCredentials.getPrincipal());
-    properties.put(Context.SECURITY_CREDENTIALS, administratorCredentials.getPassword());
+    properties.put(Context.SECURITY_PRINCIPAL, administratorCredential.getPrincipal());
+    properties.put(Context.SECURITY_CREDENTIALS, String.valueOf(administratorCredential.getKey()));
     properties.put(Context.SECURITY_AUTHENTICATION, "simple");
     properties.put(Context.REFERRAL, "follow");
     properties.put("java.naming.ldap.factory.socket", TrustingSSLSocketFactory.class.getName());
@@ -446,7 +448,7 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
     } catch (NamingException e) {
       String error = e.getMessage();
 
-      if ((error != null) && !error.isEmpty()) {
+      if (StringUtils.isEmpty(error)) {
         String message = String.format("Failed to communicate with the Active Directory at %s: %s", ldapUrl, e.getMessage());
         LOG.warn(message, e);
 
@@ -511,7 +513,7 @@ public class ADKerberosOperationHandler extends KerberosOperationHandler {
     String template;
     StringWriter stringWriter = new StringWriter();
 
-    if ((createTemplate == null) || createTemplate.isEmpty()) {
+    if (StringUtils.isEmpty(createTemplate)) {
       template = "{" +
           "\"objectClass\": [\"top\", \"person\", \"organizationalPerson\", \"user\"]," +
           "\"cn\": \"$principal_name\"," +

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c26466/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosCredential.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosCredential.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosCredential.java
deleted file mode 100644
index a173e08..0000000
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosCredential.java
+++ /dev/null
@@ -1,303 +0,0 @@
-/**
- * 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.serveraction.kerberos;
-
-import com.google.gson.Gson;
-import com.google.gson.JsonSyntaxException;
-import org.apache.ambari.server.AmbariException;
-import org.apache.commons.codec.binary.Base64;
-
-import javax.crypto.BadPaddingException;
-import javax.crypto.Cipher;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
-import javax.crypto.spec.SecretKeySpec;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.util.Arrays;
-import java.util.Map;
-
-/**
- * KerberosCredential encapsulates data needed to authenticate an identity to a KDC.
- * <p/>
- * This class has the ability to encrypt and decrypt itself using the AES encryption algorithm.
- */
-public class KerberosCredential {
-
-  /**
-   * A property name used to hold the KDC administrator's principal value.
-   */
-  public static final String KEY_NAME_PRINCIPAL = "principal";
-  /**
-   * A property name used to hold the KDC administrator's password value.
-   */
-  public static final String KEY_NAME_PASSWORD = "password";
-  /**
-   * A property name used to hold the KDC administrator's (base64-encoded) keytab
-   * value.
-   */
-  public static final String KEY_NAME_KEYTAB = "keytab";
-
-  /**
-   * This principal value
-   */
-  private String principal = null;
-
-  /**
-   * The plaintext password value
-   */
-  private char[] password = null;
-
-  /**
-   * A base64-encoded keytab
-   */
-  private String keytab = null;
-
-  /**
-   * Given a Map of attributes, attempts to safely retrieve the data needed to create a
-   * KerberosCredential representing a KDC administrator.
-   * <p/>
-   * It is expected that the following properties exist in the Map:
-   * <ul>
-   * <li>principal</li>
-   * <li>password (optional)</li>
-   * <li>keytab (optional)</li>
-   * </ul>
-   * <p/>
-   * Each of these properties may be prefixed with some prefix value to generate a relevant key value.
-   * If prefix was "kerberos_admin/", then the key representing the principal would be computed
-   * to be "kerberos_admin/principal".
-   *
-   * @param map    a Map of attributes containing the values needed to create a new KerberosCredential
-   * @param prefix a String containing the prefix to used along with the base key name (principal, etc...)
-   *               to create the relevant key name ([prefix]base_key. etc...)
-   * @return a KerberosCredential or null if commandParameters is null
-   */
-  public static KerberosCredential fromMap(Map<String, Object> map, String prefix) {
-    KerberosCredential credential = null;
-
-    if (map != null) {
-      Object attribute;
-      String principal;
-      char[] password;
-      String keytab;
-
-      if (prefix == null) {
-        prefix = "";
-      }
-
-      attribute = map.get(prefix + KEY_NAME_PRINCIPAL);
-      principal = (attribute == null) ? null : attribute.toString();
-
-      attribute = map.get(prefix + KEY_NAME_PASSWORD);
-      if (attribute instanceof char[]) {
-        password = (char[]) attribute;
-      } else if (attribute instanceof String) {
-        password = ((String) attribute).toCharArray();
-      } else {
-        password = null;
-      }
-
-      attribute = map.get(prefix + KEY_NAME_KEYTAB);
-      keytab = (attribute == null) ? null : attribute.toString();
-
-      if (((principal != null) && !principal.isEmpty()) ||
-          ((password != null) && (password.length > 0)) ||
-          ((keytab != null) && !keytab.isEmpty())) {
-        credential = new KerberosCredential(principal, password, keytab);
-      }
-    }
-
-    return credential;
-  }
-
-  /**
-   * Decrypts a String containing base64-encoded encrypted data into a new KerberosCredential.
-   * <p/>
-   * Given a key and a base64-encoded set of bytes containing encrypted data (ideally obtained from
-   * {@link #encrypt(KerberosCredential, byte[])} or {@link #encrypt(byte[])}, decodes and decrypts
-   * into a new KerberosCredential.
-   *
-   * @param cipherText a String containing base64-encoded encrypted data
-   * @param key        an array of bytes used to decrypt the encrypted data
-   * @return a new KerberosCredential
-   * @throws AmbariException if an error occurs while decrypting the data
-   */
-  public static KerberosCredential decrypt(String cipherText, byte[] key) throws AmbariException {
-    if (cipherText == null) {
-      return null;
-    } else {
-      try {
-        SecretKeySpec secretKey = new SecretKeySpec(Arrays.copyOf(key, 16), "AES");
-        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
-        cipher.init(Cipher.DECRYPT_MODE, secretKey);
-        byte[] plaintext = cipher.doFinal(Base64.decodeBase64(cipherText));
-        return fromJSON(new String(plaintext));
-      } catch (NoSuchAlgorithmException e) {
-        throw new AmbariException("Failed to decrypt cipher text due to invalid encryption algorithm", e);
-      } catch (NoSuchPaddingException e) {
-        throw new AmbariException("Failed to decrypt cipher text due to invalid padding scheme algorithm", e);
-      } catch (IllegalBlockSizeException e) {
-        throw new AmbariException("Failed to decrypt cipher text due to invalid block size", e);
-      } catch (BadPaddingException e) {
-        throw new AmbariException("Failed to decrypt cipher text due to invalid padding", e);
-      } catch (InvalidKeyException e) {
-        throw new AmbariException("Failed to decrypt cipher text due to invalid key", e);
-      } catch (JsonSyntaxException e) {
-        throw new AmbariException("Failed to decrypt cipher, cannot parse data into a KerberosCredential", e);
-      }
-    }
-  }
-
-  /**
-   * Encrypts a KerberosCredential into a base64-encoded set of bytes.
-   * <p/>
-   * Given a KerberosCredential and a key, serializes the data into a JSON-formatted string and
-   * encrypts it.
-   *
-   * @param kerberosCredential the KerberosCredential to encrypt
-   * @param key                an array of bytes used to decrypt the encrypted data
-   * @return a String containing base64-encoded encrypted data
-   * @throws AmbariException if an error occurs while encrypting the KerberosCredential
-   */
-  public static String encrypt(KerberosCredential kerberosCredential, byte[] key) throws AmbariException {
-    if (kerberosCredential == null) {
-      return null;
-    } else {
-      try {
-        SecretKeySpec secretKey = new SecretKeySpec(Arrays.copyOf(key, 16), "AES");
-        Cipher cipher = Cipher.getInstance("AES/ECB/PKCS5Padding");
-        cipher.init(Cipher.ENCRYPT_MODE, secretKey);
-        String plaintext = new Gson().toJson(kerberosCredential);
-        return Base64.encodeBase64String(cipher.doFinal(plaintext.getBytes()));
-      } catch (NoSuchAlgorithmException e) {
-        throw new AmbariException("Failed to encrypt plaintext due to invalid encryption algorithm", e);
-      } catch (NoSuchPaddingException e) {
-        throw new AmbariException("Failed to encrypt plaintext due to invalid padding scheme algorithm", e);
-      } catch (IllegalBlockSizeException e) {
-        throw new AmbariException("The encryption algorithm is unable to process the input data provided.", e);
-      } catch (BadPaddingException e) {
-        throw new AmbariException("Failed to encrypt plaintext due to unexpected reasons", e);
-      } catch (InvalidKeyException e) {
-        throw new AmbariException("Failed to encrypt plaintext due to invalid key", e);
-      }
-    }
-  }
-
-  /**
-   * Creates an empty KerberosCredential
-   */
-  public KerberosCredential() {
-    principal = null;
-    password = null;
-    keytab = null;
-  }
-
-  /**
-   * Creates a new KerberosCredential
-   *
-   * @param principal a String containing the principal name for this Kerberos credential
-   * @param password  a char array containing the password for this Kerberos credential
-   * @param keytab    a String containing the base64 encoded keytab for this Kerberos credential
-   */
-  public KerberosCredential(String principal, char[] password, String keytab) {
-    this.principal = principal;
-    this.password = password;
-    this.keytab = keytab;
-  }
-
-  /**
-   * @return a String containing the principal name for this Kerberos credential
-   */
-  public String getPrincipal() {
-    return principal;
-  }
-
-  /**
-   * @param principal a String containing the principal name for this Kerberos credential
-   */
-  public void setPrincipal(String principal) {
-    this.principal = principal;
-  }
-
-  /**
-   * @return a char array containing the password for this Kerberos credential
-   */
-  public char[] getPassword() {
-    return password;
-  }
-
-  /**
-   * @param password a char array containing the password for this Kerberos credential
-   */
-  public void setPassword(char[] password) {
-    this.password = password;
-  }
-
-  /**
-   * @return a String containing the base64 encoded keytab for this Kerberos credential
-   */
-  public String getKeytab() {
-    return keytab;
-  }
-
-  /**
-   * @param keytab a String containing the base64 encoded keytab for this Kerberos credential
-   */
-  public void setKeytab(String keytab) {
-    this.keytab = keytab;
-  }
-
-  /**
-   * Encrypts this KerberosCredential into a base64-encoded set of bytes.
-   * <p/>
-   * Serializes this KerberosCredential into a JSON-formatted string and
-   * encrypts it using the supplied key.
-   *
-   * @param key an array of bytes used to decrypt the encrypted data
-   * @return a String containing base64-encoded encrypted data
-   * @throws AmbariException if an error occurs while encrypting the KerberosCredential
-   */
-  public String encrypt(byte[] key) throws AmbariException {
-    return encrypt(this, key);
-  }
-
-  /**
-   * Returns a JSON representation of this KerberosCredential
-   *
-   * @return a String containing the JSON representation of this KerberosCredential
-   */
-  public String toJSON() {
-    return new Gson().toJson(this);
-  }
-
-  /**
-   * Renders a new KerberosCredential from its JSON representation
-   *
-   * @param json a string containing a JSON representation of a KerberosCredential
-   * @return a new KerberosCredential or null if a new KerberosCredential cannot be created
-   */
-  public static KerberosCredential fromJSON(String json) {
-    try {
-      return ((json == null) || json.isEmpty()) ? null : new Gson().fromJson(json, KerberosCredential.class);
-    }
-    catch(JsonSyntaxException e) {
-      return null;
-    }
-  }
-}

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c26466/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
index c8b8ca6..4cd050e 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosOperationHandler.java
@@ -18,8 +18,11 @@
 
 package org.apache.ambari.server.serveraction.kerberos;
 
+import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
 import org.apache.ambari.server.utils.ShellCommandUtil;
 import org.apache.commons.codec.binary.Base64;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
 import org.apache.directory.server.kerberos.shared.crypto.encryption.KerberosKeyFactory;
 import org.apache.directory.server.kerberos.shared.keytab.Keytab;
 import org.apache.directory.server.kerberos.shared.keytab.KeytabEntry;
@@ -188,7 +191,7 @@ public abstract class KerberosOperationHandler {
         add(EncryptionType.AES256_CTS_HMAC_SHA1_96);
       }});
 
-  private KerberosCredential administratorCredentials = null;
+  private PrincipalKeyCredential administratorCredential = null;
   private String defaultRealm = null;
   private Set<EncryptionType> keyEncryptionTypes = new HashSet<EncryptionType>(DEFAULT_CIPHERS);
   private boolean open = false;
@@ -202,18 +205,15 @@ public abstract class KerberosOperationHandler {
 
   /**
    * Prepares and creates resources to be used by this KerberosOperationHandler.
-   * Implementation in this class is ignoring parameters ldapUrl and principalContainerDn and delegate to
-   * <code>open(KerberosCredential administratorCredentials, String defaultRealm)</code>
-   * Subclasses that want to use these parameters need to override this method.
    * <p/>
    * It is expected that this KerberosOperationHandler will not be used before this call.
    *
-   * @param administratorCredentials a KerberosCredential containing the administrative credentials
-   *                                 for the relevant KDC
-   * @param defaultRealm             a String declaring the default Kerberos realm (or domain)
-   * @param kerberosConfiguration    a Map of key/value pairs containing data from the kerberos-env configuration set
+   * @param administratorCredential a PrincipalKeyCredential containing the administrative credential
+   *                                for the relevant KDC
+   * @param defaultRealm            a String declaring the default Kerberos realm (or domain)
+   * @param kerberosConfiguration   a Map of key/value pairs containing data from the kerberos-env configuration set
    */
-  public abstract void open(KerberosCredential administratorCredentials, String defaultRealm, Map<String, String> kerberosConfiguration)
+  public abstract void open(PrincipalKeyCredential administratorCredential, String defaultRealm, Map<String, String> kerberosConfiguration)
       throws KerberosOperationException;
 
   /**
@@ -288,11 +288,11 @@ public abstract class KerberosOperationHandler {
       throw new KerberosOperationException("This operation handler has not been opened");
     }
 
-    KerberosCredential credentials = getAdministratorCredentials();
-    if (credentials == null) {
-      throw new KerberosOperationException("Missing KDC administrator credentials");
+    PrincipalKeyCredential credential = getAdministratorCredential();
+    if (credential == null) {
+      throw new KerberosOperationException("Missing KDC administrator credential");
     } else {
-      return principalExists(credentials.getPrincipal());
+      return principalExists(credential.getPrincipal());
     }
   }
 
@@ -308,7 +308,7 @@ public abstract class KerberosOperationHandler {
   protected Keytab createKeytab(String principal, String password, Integer keyNumber)
       throws KerberosOperationException {
 
-    if ((principal == null) || principal.isEmpty()) {
+    if (StringUtils.isEmpty(principal)) {
       throw new KerberosOperationException("Failed to create keytab file, missing principal");
     }
 
@@ -478,48 +478,47 @@ public abstract class KerberosOperationHandler {
     return keytab;
   }
 
-  public KerberosCredential getAdministratorCredentials() {
-    return administratorCredentials;
+  /**
+   * Sets the KDC administrator credential.
+   *
+   * @return a credential
+   */
+  public PrincipalKeyCredential getAdministratorCredential() {
+    return administratorCredential;
   }
 
   /**
    * Sets the administrator credentials for this KerberosOperationHandler.
    * <p/>
-   * If the supplied {@link KerberosCredential} is not <code>null</code>, validates that the administrator
-   * principal is not <code>null</code> or empty and that either the password or the keytab value
-   * is not <code>null</code> or empty. If the credential value does not validate, then a
-   * {@link KerberosAdminAuthenticationException} will be thrown.
+   * If the supplied {@link PrincipalKeyCredential} is not <code>null</code>, validates that the administrator
+   * principal and values are not <code>null</code> or empty. If the credential value does not
+   * validate, then a {@link KerberosAdminAuthenticationException} will be thrown.
    *
-   * @param administratorCredentials the relevant KerberosCredential
-   * @throws KerberosAdminAuthenticationException if the non-null KerberosCredential fails contain
-   *                                              a non-empty principal and a non-empty password or
-   *                                              keytab value.
+   * @param administratorCredential the KDC administrator credential
+   * @throws KerberosAdminAuthenticationException if the non-null Credential fails to contain
+   *                                              a non-empty principal and password values.
    */
-  public void setAdministratorCredentials(KerberosCredential administratorCredentials)
+  public void setAdministratorCredential(PrincipalKeyCredential administratorCredential)
       throws KerberosAdminAuthenticationException {
 
-    // Ensure the KerberosCredential is not null
-    if (administratorCredentials == null) {
+    // Ensure the credential is not null
+    if (administratorCredential == null) {
       throw new KerberosAdminAuthenticationException("The administrator credential must not be null");
     }
 
     // Ensure the principal is not null or empty
-    String principal = administratorCredentials.getPrincipal();
-    if ((principal == null) || principal.isEmpty()) {
+    String principal = administratorCredential.getPrincipal();
+    if (StringUtils.isEmpty(principal)) {
       throw new KerberosAdminAuthenticationException("Must specify a principal but it is null or empty");
     }
 
     // Ensure either the password or the keytab value is not null or empty
-    char[] password  = administratorCredentials.getPassword();
-    if ((password == null) || (password.length == 0)) {
-      String keytab  = administratorCredentials.getKeytab();
-
-      if ((keytab == null) || keytab.isEmpty()) {
-        throw new KerberosAdminAuthenticationException("Must specify either a password or a keytab but both are null or empty");
-      }
+    char[] password = administratorCredential.getKey();
+    if (ArrayUtils.isEmpty(password)) {
+      throw new KerberosAdminAuthenticationException("Must specify a password but it is null or empty");
     }
 
-    this.administratorCredentials = administratorCredentials;
+    this.administratorCredential = administratorCredential;
   }
 
   public String getDefaultRealm() {
@@ -749,7 +748,7 @@ public abstract class KerberosOperationHandler {
   protected Set<EncryptionType> translateEncryptionType(String name) {
     Set<EncryptionType> encryptionTypes = null;
 
-    if ((name != null) && !name.isEmpty()) {
+    if (!StringUtils.isEmpty(name)) {
       encryptionTypes = ENCRYPTION_TYPE_TRANSLATION_MAP.get(name.toLowerCase());
     }
 
@@ -767,7 +766,7 @@ public abstract class KerberosOperationHandler {
   protected Set<EncryptionType> translateEncryptionTypes(String names, String delimiter) {
     Set<EncryptionType> encryptionTypes = new HashSet<EncryptionType>();
 
-    if ((names != null) && !names.isEmpty()) {
+    if (!StringUtils.isEmpty(names)) {
       for (String name : names.split((delimiter == null) ? "\\s+" : delimiter)) {
         encryptionTypes.addAll(translateEncryptionType(name.trim()));
       }
@@ -785,7 +784,7 @@ public abstract class KerberosOperationHandler {
    * @return the string with escaped characters
    */
   protected String escapeCharacters(String string, Set<Character> charactersToEscape, Character escapeCharacter) {
-    if ((string == null) || string.isEmpty() || (charactersToEscape == null) || charactersToEscape.isEmpty()) {
+    if (StringUtils.isEmpty(string) || (charactersToEscape == null) || charactersToEscape.isEmpty()) {
       return string;
     } else {
       StringBuilder builder = new StringBuilder();

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c26466/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java
index c861b45..901a80f 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/KerberosServerAction.java
@@ -24,6 +24,7 @@ import org.apache.ambari.server.actionmanager.HostRoleStatus;
 import org.apache.ambari.server.agent.CommandReport;
 import org.apache.ambari.server.agent.ExecutionCommand;
 import org.apache.ambari.server.controller.KerberosHelper;
+import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
 import org.apache.ambari.server.serveraction.AbstractServerAction;
 import org.apache.ambari.server.state.Cluster;
 import org.apache.ambari.server.state.Clusters;
@@ -341,7 +342,7 @@ public abstract class KerberosServerAction extends AbstractServerAction {
 
     if (commandParameters != null) {
       // Grab the relevant data from this action's command parameters map
-      KerberosCredential administratorCredential = kerberosHelper.getKDCCredentials();
+      PrincipalKeyCredential administratorCredential = kerberosHelper.getKDCAdministratorCredentials(getClusterName());
       String defaultRealm = getDefaultRealm(commandParameters);
       KDCType kdcType = getKDCType(commandParameters);
       String dataDirectoryPath = getDataDirectoryPath(commandParameters);

http://git-wip-us.apache.org/repos/asf/ambari/blob/44c26466/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
index 6f36bf5..90858fb 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/MITKerberosOperationHandler.java
@@ -18,11 +18,13 @@
 
 package org.apache.ambari.server.serveraction.kerberos;
 
+import org.apache.ambari.server.security.credential.PrincipalKeyCredential;
 import org.apache.ambari.server.utils.ShellCommandUtil;
+import org.apache.commons.lang.ArrayUtils;
+import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
-import java.io.File;
 import java.text.NumberFormat;
 import java.text.ParseException;
 import java.util.ArrayList;
@@ -73,7 +75,7 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
    * <p/>
    * The kerberosConfiguration Map is not being used.
    *
-   * @param administratorCredentials a KerberosCredential containing the administrative credentials
+   * @param administratorCredentials a PrincipalKeyCredential containing the administrative credential
    *                                 for the relevant KDC
    * @param realm                    a String declaring the default Kerberos realm (or domain)
    * @param kerberosConfiguration    a Map of key/value pairs containing data from the kerberos-env configuration set
@@ -83,11 +85,11 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
    * @throws KerberosOperationException           if an unexpected error occurred
    */
   @Override
-  public void open(KerberosCredential administratorCredentials, String realm,
+  public void open(PrincipalKeyCredential administratorCredentials, String realm,
                    Map<String, String> kerberosConfiguration)
       throws KerberosOperationException {
 
-    setAdministratorCredentials(administratorCredentials);
+    setAdministratorCredential(administratorCredentials);
     setDefaultRealm(realm);
 
     if (kerberosConfiguration != null) {
@@ -176,9 +178,9 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
       throw new KerberosOperationException("This operation handler has not been opened");
     }
 
-    if ((principal == null) || principal.isEmpty()) {
+    if (StringUtils.isEmpty(principal)) {
       throw new KerberosOperationException("Failed to create new principal - no principal specified");
-    } else if ((password == null) || password.isEmpty()) {
+    } else if (StringUtils.isEmpty(password)) {
       throw new KerberosOperationException("Failed to create new principal - no password specified");
     } else {
       String createAttributes = getCreateAttributes();
@@ -220,9 +222,9 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
       throw new KerberosOperationException("This operation handler has not been opened");
     }
 
-    if ((principal == null) || principal.isEmpty()) {
+    if (StringUtils.isEmpty(principal)) {
       throw new KerberosOperationException("Failed to set password - no principal specified");
-    } else if ((password == null) || password.isEmpty()) {
+    } else if (StringUtils.isEmpty(password)) {
       throw new KerberosOperationException("Failed to set password - no password specified");
     } else {
       // Create the kdamin query:  change_password <-randkey|-pw <password>> <principal>
@@ -250,7 +252,7 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
       throw new KerberosOperationException("This operation handler has not been opened");
     }
 
-    if ((principal == null) || principal.isEmpty()) {
+    if (StringUtils.isEmpty(principal)) {
       throw new KerberosOperationException("Failed to remove new principal - no principal specified");
     } else {
       ShellCommandUtil.Result result = invokeKAdmin(String.format("delete_principal -force %s", principal));
@@ -313,7 +315,7 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
       throw new KerberosOperationException("This operation handler has not been opened");
     }
 
-    if ((principal == null) || principal.isEmpty()) {
+    if (StringUtils.isEmpty(principal)) {
       throw new KerberosOperationException("Failed to get key number for principal  - no principal specified");
     } else {
       // Create the kdamin query:  get_principal <principal>
@@ -363,115 +365,95 @@ public class MITKerberosOperationHandler extends KerberosOperationHandler {
    */
   protected ShellCommandUtil.Result invokeKAdmin(String query)
       throws KerberosOperationException {
-    ShellCommandUtil.Result result = null;
-
-    if ((query == null) || query.isEmpty()) {
+    if (StringUtils.isEmpty(query)) {
       throw new KerberosOperationException("Missing kadmin query");
     }
-    KerberosCredential administratorCredentials = getAdministratorCredentials();
+
+    ShellCommandUtil.Result result;
+    PrincipalKeyCredential administratorCredential = getAdministratorCredential();
     String defaultRealm = getDefaultRealm();
 
     List<String> command = new ArrayList<String>();
-    File tempKeytabFile = null;
-
-    try {
-      String adminPrincipal = (administratorCredentials == null)
-          ? null
-          : administratorCredentials.getPrincipal();
 
-      if ((adminPrincipal == null) || adminPrincipal.isEmpty()) {
-        // Set the kdamin interface to be kadmin.local
-        if((executableKadminLocal == null) || executableKadminLocal.isEmpty()) {
-          throw new KerberosOperationException("No path for kadmin.local is available - this KerberosOperationHandler may not have been opened.");
-        }
+    String adminPrincipal = (administratorCredential == null)
+        ? null
+        : administratorCredential.getPrincipal();
 
-        command.add(executableKadminLocal);
-      } else {
-        if((executableKadmin == null) || executableKadmin.isEmpty()) {
-          throw new KerberosOperationException("No path for kadmin is available - this KerberosOperationHandler may not have been opened.");
-        }
-        char[] adminPassword = administratorCredentials.getPassword();
-        String adminKeyTab = administratorCredentials.getKeytab();
+    if (StringUtils.isEmpty(adminPrincipal)) {
+      // Set the kdamin interface to be kadmin.local
+      if (StringUtils.isEmpty(executableKadminLocal)) {
+        throw new KerberosOperationException("No path for kadmin.local is available - this KerberosOperationHandler may not have been opened.");
+      }
 
-        // Set the kdamin interface to be kadmin
-        command.add(executableKadmin);
+      command.add(executableKadminLocal);
+    } else {
+      if (StringUtils.isEmpty(executableKadmin)) {
+        throw new KerberosOperationException("No path for kadmin is available - this KerberosOperationHandler may not have been opened.");
+      }
+      char[] adminPassword = administratorCredential.getKey();
 
-        // Add explicit KDC admin host, if available
-        if (getAdminServerHost() != null) {
-          command.add("-s");
-          command.add(getAdminServerHost());
-        }
+      // Set the kdamin interface to be kadmin
+      command.add(executableKadmin);
 
-        // Add the administrative principal
-        command.add("-p");
-        command.add(adminPrincipal);
-
-        if ((adminKeyTab != null) && !adminKeyTab.isEmpty()) {
-          tempKeytabFile = createKeytabFile(adminKeyTab);
-
-          if (tempKeytabFile != null) {
-            // Add keytab file administrative principal
-            command.add("-k");
-            command.add("-t");
-            command.add(tempKeytabFile.getAbsolutePath());
-          }
-        } else if (adminPassword != null) {
-          // Add password for administrative principal
-          command.add("-w");
-          command.add(String.valueOf(adminPassword));
-        }
+      // Add explicit KDC admin host, if available
+      if (getAdminServerHost() != null) {
+        command.add("-s");
+        command.add(getAdminServerHost());
       }
 
-      if ((defaultRealm != null) && !defaultRealm.isEmpty()) {
-        // Add default realm clause
-        command.add("-r");
-        command.add(defaultRealm);
+      // Add the administrative principal
+      command.add("-p");
+      command.add(adminPrincipal);
+
+      if (!ArrayUtils.isEmpty(adminPassword)) {
+        // Add password for administrative principal
+        command.add("-w");
+        command.add(String.valueOf(adminPassword));
       }
+    }
 
-      // Add kadmin query
-      command.add("-q");
-      command.add(query);
+    if (!StringUtils.isEmpty(defaultRealm)) {
+      // Add default realm clause
+      command.add("-r");
+      command.add(defaultRealm);
+    }
 
-      if(LOG.isDebugEnabled()) {
-        LOG.debug(String.format("Executing: %s", createCleanCommand(command)));
-      }
+    // Add kadmin query
+    command.add("-q");
+    command.add(query);
 
-      result = executeCommand(command.toArray(new String[command.size()]));
+    if (LOG.isDebugEnabled()) {
+      LOG.debug(String.format("Executing: %s", createCleanCommand(command)));
+    }
 
-      if (!result.isSuccessful()) {
-        String message = String.format("Failed to execute kadmin:\n\tCommand: %s\n\tExitCode: %s\n\tSTDOUT: %s\n\tSTDERR: %s",
-            createCleanCommand(command), result.getExitCode(), result.getStdout(), result.getStderr());
-        LOG.warn(message);
+    result = executeCommand(command.toArray(new String[command.size()]));
 
-        // Test STDERR to see of any "expected" error conditions were encountered...
-        String stdErr = result.getStderr();
-        // Did admin credentials fail?
-        if (stdErr.contains("Client not found in Kerberos database")) {
-          throw new KerberosAdminAuthenticationException(stdErr);
-        } else if (stdErr.contains("Incorrect password while initializing")) {
-          throw new KerberosAdminAuthenticationException(stdErr);
-        }
-        // Did we fail to connect to the KDC?
-        else if (stdErr.contains("Cannot contact any KDC")) {
-          throw new KerberosKDCConnectionException(stdErr);
-        } else if (stdErr.contains("Cannot resolve network address for admin server in requested realm while initializing kadmin interface")) {
-          throw new KerberosKDCConnectionException(stdErr);
-        }
-        // Was the realm invalid?
-        else if (stdErr.contains("Missing parameters in krb5.conf required for kadmin client")) {
-          throw new KerberosRealmException(stdErr);
-        } else if (stdErr.contains("Cannot find KDC for requested realm while initializing kadmin interface")) {
-          throw new KerberosRealmException(stdErr);
-        } else {
-          throw new KerberosOperationException("Unexpected error condition executing the kadmin command");
-        }
+    if (!result.isSuccessful()) {
+      String message = String.format("Failed to execute kadmin:\n\tCommand: %s\n\tExitCode: %s\n\tSTDOUT: %s\n\tSTDERR: %s",
+          createCleanCommand(command), result.getExitCode(), result.getStdout(), result.getStderr());
+      LOG.warn(message);
+
+      // Test STDERR to see of any "expected" error conditions were encountered...
+      String stdErr = result.getStderr();
+      // Did admin credentials fail?
+      if (stdErr.contains("Client not found in Kerberos database")) {
+        throw new KerberosAdminAuthenticationException(stdErr);
+      } else if (stdErr.contains("Incorrect password while initializing")) {
+        throw new KerberosAdminAuthenticationException(stdErr);
       }
-    } finally {
-      // If a temporary keytab file was created, clean it up.
-      if (tempKeytabFile != null) {
-        if (!tempKeytabFile.delete()) {
-          tempKeytabFile.deleteOnExit();
-        }
+      // Did we fail to connect to the KDC?
+      else if (stdErr.contains("Cannot contact any KDC")) {
+        throw new KerberosKDCConnectionException(stdErr);
+      } else if (stdErr.contains("Cannot resolve network address for admin server in requested realm while initializing kadmin interface")) {
+        throw new KerberosKDCConnectionException(stdErr);
+      }
+      // Was the realm invalid?
+      else if (stdErr.contains("Missing parameters in krb5.conf required for kadmin client")) {
+        throw new KerberosRealmException(stdErr);
+      } else if (stdErr.contains("Cannot find KDC for requested realm while initializing kadmin interface")) {
+        throw new KerberosRealmException(stdErr);
+      } else {
+        throw new KerberosOperationException("Unexpected error condition executing the kadmin command");
       }
     }