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/11/16 19:45:39 UTC

[23/50] [abbrv] ambari git commit: AMBARI-22390. Implement many-to-many relation between keytabs and principals (echekanskiy)

AMBARI-22390. Implement many-to-many relation between keytabs and principals (echekanskiy)


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

Branch: refs/heads/branch-feature-AMBARI-20859
Commit: 18e549034e893aac4ade80e49bda70604d5147f3
Parents: 6e706d4
Author: Eugene Chekanskiy <ec...@hortonworks.com>
Authored: Mon Nov 13 17:01:16 2017 +0200
Committer: Eugene Chekanskiy <ec...@hortonworks.com>
Committed: Mon Nov 13 17:01:29 2017 +0200

----------------------------------------------------------------------
 .../server/controller/KerberosHelperImpl.java   | 59 ++++++++++++++------
 .../AbstractPrepareKerberosServerAction.java    | 23 +++-----
 .../kerberos/CreatePrincipalsServerAction.java  |  6 +-
 .../kerberos/KerberosServerAction.java          | 21 +++++++
 .../stageutils/ResolvedKerberosKeytab.java      | 16 +++---
 5 files changed, 82 insertions(+), 43 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/ambari/blob/18e54903/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 f913831..474c335 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
@@ -1546,19 +1546,21 @@ public class KerberosHelperImpl implements KerberosHelper {
                 keytabFileOwnerAccess,
                 keytabFileGroupName,
                 keytabFileGroupAccess,
-                Sets.newHashSet(Pair.of(hostId, evaluatedPrincipal)),
+                Sets.newHashSet(Pair.of(hostId, Pair.of(evaluatedPrincipal, principalType))),
                 serviceName.equalsIgnoreCase("AMBARI"),
                 componentName.equalsIgnoreCase("AMBARI_SERVER_SELF")
             );
             if (resolvedKeytabs.containsKey(keytabFilePath)) {
               ResolvedKerberosKeytab sameKeytab = resolvedKeytabs.get(keytabFilePath);
               // validating owner and group
-              String warnTemplate = "Keytab '{}' on host '{}' have different {}, originally set to '{}' and '{}:{}' has '{}', using '{}'";
+              boolean differentOwners = false;
+              String warnTemplate = "Keytab '{}' on host '{}' has different {}, originally set to '{}' and '{}:{}' has '{}', using '{}'";
               if (!resolvedKeytab.getOwnerName().equals(sameKeytab.getOwnerName())) {
                 LOG.warn(warnTemplate,
                     keytabFilePath, hostname, "owners", sameKeytab.getOwnerName(),
                     serviceName, componentName, resolvedKeytab.getOwnerName(),
                     sameKeytab.getOwnerName());
+                differentOwners = true;
               }
               if (!resolvedKeytab.getOwnerAccess().equals(sameKeytab.getOwnerAccess())) {
                 LOG.warn(warnTemplate,
@@ -1570,16 +1572,39 @@ public class KerberosHelperImpl implements KerberosHelper {
               // TODO with different owners, so make sure that keytabs are accessible through group acls
               // TODO this includes same group name and group 'r' mode
               if (!resolvedKeytab.getGroupName().equals(sameKeytab.getGroupName())) {
-                LOG.warn(warnTemplate,
-                    keytabFilePath, hostname, "groups", sameKeytab.getGroupName(),
-                    serviceName, componentName, resolvedKeytab.getGroupName(),
-                    sameKeytab.getGroupName());
+                if(differentOwners) {
+                  LOG.error(warnTemplate,
+                      keytabFilePath, hostname, "groups", sameKeytab.getGroupName(),
+                      serviceName, componentName, resolvedKeytab.getGroupName(),
+                      sameKeytab.getGroupName());
+                } else {
+                  LOG.warn(warnTemplate,
+                      keytabFilePath, hostname, "groups", sameKeytab.getGroupName(),
+                      serviceName, componentName, resolvedKeytab.getGroupName(),
+                      sameKeytab.getGroupName());
+                }
               }
               if (!resolvedKeytab.getGroupAccess().equals(sameKeytab.getGroupAccess())) {
-                LOG.warn(warnTemplate,
-                    keytabFilePath, hostname, "group access", sameKeytab.getGroupAccess(),
-                    serviceName, componentName, resolvedKeytab.getGroupAccess(),
-                    sameKeytab.getGroupAccess());
+                if(differentOwners) {
+                  if (!sameKeytab.getGroupAccess().contains("r")) {
+                    LOG.error("Keytab '{}' on host '{}' referenced by multiple identities which have different owners," +
+                        "but 'r' attribute missing for group. Make sure all users (that need this keytab) are in '{}' +" +
+                        "group and keytab can be read by this group",
+                        keytabFilePath,
+                        hostname,
+                        sameKeytab.getGroupName()
+                    );
+                  }
+                  LOG.error(warnTemplate,
+                      keytabFilePath, hostname, "group access", sameKeytab.getGroupAccess(),
+                      serviceName, componentName, resolvedKeytab.getGroupAccess(),
+                      sameKeytab.getGroupAccess());
+                } else {
+                  LOG.warn(warnTemplate,
+                      keytabFilePath, hostname, "group access", sameKeytab.getGroupAccess(),
+                      serviceName, componentName, resolvedKeytab.getGroupAccess(),
+                      sameKeytab.getGroupAccess());
+                }
               }
               // end validating
               // merge principal to keytab
@@ -1877,15 +1902,17 @@ public class KerberosHelperImpl implements KerberosHelper {
     if (kerberosKeytabDAO.find(resolvedKerberosKeytab.getFile()) == null) {
       kerberosKeytabDAO.create(resolvedKerberosKeytab.getFile());
     }
-    for (Pair<Long, String> principalPair : resolvedKerberosKeytab.getMappedPrincipals()) {
-      String principal = principalPair.getRight();
+    for (Pair<Long, Pair<String, String>> principalPair : resolvedKerberosKeytab.getMappedPrincipals()) {
+      Pair<String, String> principal = principalPair.getRight();
+      String principalName = principal.getLeft();
+      String principalType = principal.getRight();
       Long hostId = principalPair.getLeft();
-      if (!kerberosPrincipalDAO.exists(principal)) {
-        kerberosPrincipalDAO.create(principal, false);
+      if (!kerberosPrincipalDAO.exists(principalName)) {
+        kerberosPrincipalDAO.create(principalName, "service".equalsIgnoreCase(principalType));
       }
       if (hostId != null) {
-        if(!kerberosPrincipalHostDAO.exists(principal, hostId, resolvedKerberosKeytab.getFile())) {
-          kerberosPrincipalHostDAO.create(principal, hostId, resolvedKerberosKeytab.getFile());
+        if(!kerberosPrincipalHostDAO.exists(principalName, hostId, resolvedKerberosKeytab.getFile())) {
+          kerberosPrincipalHostDAO.create(principalName, hostId, resolvedKerberosKeytab.getFile());
         }
       }
     }

http://git-wip-us.apache.org/repos/asf/ambari/blob/18e54903/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerAction.java
index 1dc8ca8..4008620 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/AbstractPrepareKerberosServerAction.java
@@ -196,7 +196,7 @@ public abstract class AbstractPrepareKerberosServerAction extends KerberosServer
 
               List<KerberosIdentityDescriptor> componentIdentities = Collections.singletonList(identity);
               kerberosHelper.addIdentities(kerberosIdentityDataFileWriter, componentIdentities,
-                  identityFilter, StageUtils.getHostName(), ambariServerHostID(), "AMBARI",componentName, kerberosConfigurations, currentConfigurations,
+                  identityFilter, StageUtils.getHostName(), ambariServerHostID(), "AMBARI", componentName, kerberosConfigurations, currentConfigurations,
                   resolvedKeytabs, realm);
               propertiesToIgnore = gatherPropertiesToIgnore(componentIdentities, propertiesToIgnore);
             }
@@ -236,19 +236,9 @@ public abstract class AbstractPrepareKerberosServerAction extends KerberosServer
   protected Map<String, ? extends Collection<String>> getServiceComponentFilter() {
     String serializedValue = getCommandParameterValue(SERVICE_COMPONENT_FILTER);
 
-    if(serializedValue != null) {
-      Type type = new TypeToken<Map<String, ? extends Collection<String>>>() {}.getType();
-      return StageUtils.getGson().fromJson(serializedValue, type);
-    } else {
-      return null;
-    }
-  }
-
-  protected Set<String> getHostFilter() {
-    String serializedValue = getCommandParameterValue(HOST_FILTER);
-
-    if(serializedValue != null) {
-      Type type = new TypeToken<Set<String>>() {}.getType();
+    if (serializedValue != null) {
+      Type type = new TypeToken<Map<String, ? extends Collection<String>>>() {
+      }.getType();
       return StageUtils.getGson().fromJson(serializedValue, type);
     } else {
       return null;
@@ -258,8 +248,9 @@ public abstract class AbstractPrepareKerberosServerAction extends KerberosServer
   protected Collection<String> getIdentityFilter() {
     String serializedValue = getCommandParameterValue(IDENTITY_FILTER);
 
-    if(serializedValue != null) {
-      Type type = new TypeToken<Collection<String>>() {}.getType();
+    if (serializedValue != null) {
+      Type type = new TypeToken<Collection<String>>() {
+      }.getType();
       return StageUtils.getGson().fromJson(serializedValue, type);
     } else {
       return null;

http://git-wip-us.apache.org/repos/asf/ambari/blob/18e54903/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
index 59d5327..0c90659 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/CreatePrincipalsServerAction.java
@@ -135,10 +135,11 @@ public class CreatePrincipalsServerAction extends KerberosServerAction {
       KerberosPrincipalEntity kerberosPrincipalEntity = kerberosPrincipalDAO.find(evaluatedPrincipal);
 
       boolean regenerateKeytabs = getOperationType(getCommandParameters()) == OperationType.RECREATE_ALL;
-
+      boolean servicePrincipal = "service".equalsIgnoreCase(identityRecord.get(KerberosIdentityDataFileReader.PRINCIPAL_TYPE));
       if (regenerateKeytabs) {
         // force recreation of principal due to keytab regeneration
-        processPrincipal = true;
+        // regenerate only service principals if request filtered by hosts
+        processPrincipal = !hasHostFilters() || servicePrincipal;
       } else if (kerberosPrincipalEntity == null) {
         // This principal has not been processed before, process it.
         processPrincipal = true;
@@ -156,7 +157,6 @@ public class CreatePrincipalsServerAction extends KerberosServerAction {
         String password = principalPasswordMap.get(evaluatedPrincipal);
 
         if (password == null) {
-          boolean servicePrincipal = "service".equalsIgnoreCase(identityRecord.get(KerberosIdentityDataFileReader.PRINCIPAL_TYPE));
           CreatePrincipalResult result = createPrincipal(evaluatedPrincipal, servicePrincipal, kerberosConfiguration, operationHandler, regenerateKeytabs, actionLog);
           if (result == null) {
             commandReport = createCommandReport(1, HostRoleStatus.FAILED, "{}", actionLog.getStdOut(), actionLog.getStdErr());

http://git-wip-us.apache.org/repos/asf/ambari/blob/18e54903/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 3491f18..ff5f5ce 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
@@ -22,8 +22,10 @@ import static org.apache.ambari.server.serveraction.kerberos.KerberosIdentityDat
 
 import java.io.File;
 import java.io.IOException;
+import java.lang.reflect.Type;
 import java.util.HashMap;
 import java.util.Map;
+import java.util.Set;
 
 import org.apache.ambari.server.AmbariException;
 import org.apache.ambari.server.actionmanager.HostRoleStatus;
@@ -42,6 +44,7 @@ import org.apache.commons.lang.StringUtils;
 import org.slf4j.Logger;
 import org.slf4j.LoggerFactory;
 
+import com.google.common.reflect.TypeToken;
 import com.google.inject.Inject;
 
 /**
@@ -579,6 +582,24 @@ public abstract class KerberosServerAction extends AbstractServerAction {
     }
   }
 
+
+  protected Set<String> getHostFilter() {
+    String serializedValue = getCommandParameterValue(HOST_FILTER);
+
+    if (serializedValue != null) {
+      Type type = new TypeToken<Set<String>>() {
+      }.getType();
+      return StageUtils.getGson().fromJson(serializedValue, type);
+    } else {
+      return null;
+    }
+  }
+
+  protected boolean hasHostFilters() {
+    Set<String> hostFilers = getHostFilter();
+    return hostFilers != null && hostFilers.size() > 0;
+  }
+
   protected Long ambariServerHostID(){
     String ambariServerHostName = StageUtils.getHostName();
     HostEntity ambariServerHostEntity = hostDAO.findByName(ambariServerHostName);

http://git-wip-us.apache.org/repos/asf/ambari/blob/18e54903/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/stageutils/ResolvedKerberosKeytab.java
----------------------------------------------------------------------
diff --git a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/stageutils/ResolvedKerberosKeytab.java b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/stageutils/ResolvedKerberosKeytab.java
index f66d273..17e484a 100644
--- a/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/stageutils/ResolvedKerberosKeytab.java
+++ b/ambari-server/src/main/java/org/apache/ambari/server/serveraction/kerberos/stageutils/ResolvedKerberosKeytab.java
@@ -40,7 +40,7 @@ public class ResolvedKerberosKeytab {
   private String groupName = null;
   private String groupAccess = null;
   private String file = null;
-  private Set<Pair<Long, String>> mappedPrincipals = null;
+  private Set<Pair<Long, Pair<String, String>>> mappedPrincipals = null;
   private boolean isAmbariServerKeytab = false;
   private boolean mustWriteAmbariJaasFile = false;
 
@@ -50,7 +50,7 @@ public class ResolvedKerberosKeytab {
       String ownerAccess,
       String groupName,
       String groupAccess,
-      Set<Pair<Long, String>> mappedPrincipals,
+      Set<Pair<Long, Pair<String, String>>> mappedPrincipals,
       boolean isAmbariServerKeytab,
       boolean writeAmbariJaasFile
   ) {
@@ -177,7 +177,7 @@ public class ResolvedKerberosKeytab {
    *
    * @return a Set with mappedPrincipals associated with given keytab
    */
-  public Set<Pair<Long, String>> getMappedPrincipals() {
+  public Set<Pair<Long, Pair<String, String>>> getMappedPrincipals() {
     return mappedPrincipals;
   }
 
@@ -186,7 +186,7 @@ public class ResolvedKerberosKeytab {
    *
    * @param mappedPrincipals a Map with host-to-principal mapping associated with given keytab
    */
-  public void setMappedPrincipals(Set<Pair<Long, String>> mappedPrincipals) {
+  public void setMappedPrincipals(Set<Pair<Long, Pair<String, String>>> mappedPrincipals) {
     this.mappedPrincipals = mappedPrincipals;
   }
 
@@ -197,7 +197,7 @@ public class ResolvedKerberosKeytab {
    */
   public Set<Long> getHosts() {
     ImmutableSet.Builder<Long> builder = ImmutableSet.builder();
-    for (Pair<Long, String> principal : getMappedPrincipals()) {
+    for (Pair<Long, Pair<String, String>> principal : getMappedPrincipals()) {
       if (principal.getLeft() != null) {
         builder.add(principal.getLeft());
       }
@@ -210,9 +210,9 @@ public class ResolvedKerberosKeytab {
    *
    * @return a Set of principals
    */
-  public Set<String> getPrincipals() {
-    ImmutableSet.Builder<String> builder = ImmutableSet.builder();
-    for (Pair<Long, String> principal : getMappedPrincipals()) {
+  public Set<Pair<String, String>> getPrincipals() {
+    ImmutableSet.Builder<Pair<String, String>> builder = ImmutableSet.builder();
+    for (Pair<Long, Pair<String, String>> principal : getMappedPrincipals()) {
       builder.add(principal.getRight());
     }
     return builder.build();