diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java index 015baa1..c9cbf5b 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-api/src/main/java/org/apache/hadoop/yarn/conf/YarnConfiguration.java @@ -435,6 +435,8 @@ private static void addDeprecatedKeys() { public static final String DEFAULT_RM_CONFIGURATION_PROVIDER_CLASS = "org.apache.hadoop.yarn.LocalConfigurationProvider"; + public static final String YARN_AUTHORIZATION_PROVIDER = YARN_PREFIX + + "authorization-provider"; private static final List RM_SERVICES_ADDRESS_CONF_KEYS_HTTP = Collections.unmodifiableList(Arrays.asList( RM_ADDRESS, diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/AdminACLsManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/AdminACLsManager.java index 70c1a6e..a386123 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/AdminACLsManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/AdminACLsManager.java @@ -99,15 +99,6 @@ public boolean areACLsEnabled() { } /** - * Returns the internal structure used to maintain administrator ACLs - * - * @return Structure used to maintain administrator access - */ - public AccessControlList getAdminAcl() { - return adminAcl; - } - - /** * Returns whether the specified user/group is an administrator * * @param callerUGI user/group to to check @@ -117,26 +108,4 @@ public AccessControlList getAdminAcl() { public boolean isAdmin(UserGroupInformation callerUGI) { return adminAcl.isUserAllowed(callerUGI); } - - /** - * Returns whether the specified user/group has administrator access - * - * @param callerUGI user/group to to check - * @return true if the UserGroupInformation specified - * is a member of the access control list for administrators - * and ACLs are enabled for this cluster - * - * @see #getAdminAcl - * @see #areACLsEnabled - */ - public boolean checkAccess(UserGroupInformation callerUGI) { - - // Any user may perform this operation if authorization is not enabled - if (!areACLsEnabled()) { - return true; - } - - // Administrators may perform any operation - return isAdmin(callerUGI); - } } diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/DefaultYarnAuthorizer.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/DefaultYarnAuthorizer.java new file mode 100644 index 0000000..e40103c --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/DefaultYarnAuthorizer.java @@ -0,0 +1,72 @@ +/** + * 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.hadoop.yarn.security; + +import java.util.Map; +import java.util.concurrent.ConcurrentHashMap; +import java.util.concurrent.ConcurrentMap; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.authorize.AccessControlList; +import org.apache.hadoop.yarn.conf.YarnConfiguration; + +public class DefaultYarnAuthorizer extends YarnAuthorizationProvider { + + private final ConcurrentMap> allAcls = + new ConcurrentHashMap<>(); + private volatile AccessControlList adminAcl = null; + + + @Override + public void init(Configuration conf) { + adminAcl = + new AccessControlList(conf.get(YarnConfiguration.YARN_ADMIN_ACL, + YarnConfiguration.DEFAULT_YARN_ADMIN_ACL)); + } + + @Override + public void setPermission(PrivilegedEntity target, + Map acls) { + allAcls.put(target, acls); + } + + @Override + public boolean checkPermission(AccessType accessType, PrivilegedEntity target, + UserGroupInformation user) { + Map acls = allAcls.get(target); + if (acls != null) { + AccessControlList list = acls.get(accessType); + if (list != null) { + return list.isUserAllowed(user); + } + } + return false; + } + + @Override + public void setAdmins(AccessControlList acls) { + adminAcl = acls; + } + + @Override + public boolean isAdmin(UserGroupInformation ugi) { + return adminAcl.isUserAllowed(ugi); + } +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/PrivilegedEntity.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/PrivilegedEntity.java new file mode 100644 index 0000000..fb926e0 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/PrivilegedEntity.java @@ -0,0 +1,73 @@ +/** +* 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.hadoop.yarn.security; + +/** + * An entity that can be accessed through privileges. e.g. app / queue + */ +public class PrivilegedEntity { + + public enum EntityType { + QUEUE + } + + EntityType type; + String name; + + public PrivilegedEntity(EntityType type, String name) { + this.type = type; + this.name = name; + } + + public EntityType getType() { + return type; + } + + public String getName() { + return name; + } + + @Override + public int hashCode() { + final int prime = 31; + int result = 1; + result = prime * result + ((name == null) ? 0 : name.hashCode()); + result = prime * result + ((type == null) ? 0 : type.hashCode()); + return result; + } + + @Override + public boolean equals(Object obj) { + if (this == obj) + return true; + if (obj == null) + return false; + if (getClass() != obj.getClass()) + return false; + PrivilegedEntity other = (PrivilegedEntity) obj; + if (name == null) { + if (other.name != null) + return false; + } else if (!name.equals(other.name)) + return false; + if (type != other.type) + return false; + return true; + } +} \ No newline at end of file diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/YarnAuthorizationProvider.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/YarnAuthorizationProvider.java new file mode 100644 index 0000000..c08b511 --- /dev/null +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/security/YarnAuthorizationProvider.java @@ -0,0 +1,102 @@ +/** +* 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.hadoop.yarn.security; + +import java.util.Map; + +import org.apache.hadoop.conf.Configuration; +import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.authorize.AccessControlList; +import org.apache.hadoop.util.ReflectionUtils; +import org.apache.hadoop.yarn.conf.YarnConfiguration; + +/** + * An implementation of the interface will provide authorization related + * information and enforce permission check. It is excepted that any of the + * methods defined in this interface should be non-blocking call and should not + * involve expensive computation as these method could be invoked in client RPC. + */ +public abstract class YarnAuthorizationProvider { + + private static YarnAuthorizationProvider authorizer = null; + + public enum AccessType { + SUBMIT_APP, + ADMINISTER_QUEUE + } + + public static YarnAuthorizationProvider getInstance(Configuration conf) { + synchronized (YarnAuthorizationProvider.class) { + if (authorizer == null) { + Class authorizerClass = + conf.getClass(YarnConfiguration.YARN_AUTHORIZATION_PROVIDER, + DefaultYarnAuthorizer.class); + authorizer = + (YarnAuthorizationProvider) ReflectionUtils.newInstance( + authorizerClass, conf); + } + } + return authorizer; + } + + /** + * Initialize the provider. Invoked on daemon startup. DefaultYarnAuthorizer is + * initialized based on configurations. + */ + public abstract void init(Configuration conf); + + /** + * Check if user has the permission to access the target object. + * + * @param accessType + * The type of accessing method. + * @param target + * The target object being accessed, e.g. app/queue + * @param user + * User who access the target + * @return true if user can access the object, otherwise false. + */ + public abstract boolean checkPermission(AccessType accessType, + PrivilegedEntity target, UserGroupInformation user); + + /** + * Set ACLs for the target object. AccessControlList class encapsulate the + * users and groups who can access the target. + * + * @param target + * The target object. + * @param acls + * A map from access method to a list of users and/or groups who has + * permission to do the access. + */ + public abstract void setPermission(PrivilegedEntity target, + Map acls); + + /** + * Set a list of users/groups who have admin access + * + * @param acls users/groups who have admin access + */ + public abstract void setAdmins(AccessControlList acls); + + /** + * Check if the user is an admin. + */ + public abstract boolean isAdmin(UserGroupInformation ugi); +} diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApps.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApps.java index f8c6f55..1b5840f 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApps.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-common/src/main/java/org/apache/hadoop/yarn/webapp/WebApps.java @@ -36,11 +36,10 @@ import org.apache.hadoop.classification.InterfaceAudience; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.http.HttpConfig.Policy; -import org.apache.hadoop.http.HttpConfig; import org.apache.hadoop.http.HttpServer2; import org.apache.hadoop.security.UserGroupInformation; +import org.apache.hadoop.security.authorize.AccessControlList; import org.apache.hadoop.yarn.conf.YarnConfiguration; -import org.apache.hadoop.yarn.security.AdminACLsManager; import org.apache.hadoop.yarn.webapp.util.WebAppUtils; import org.slf4j.Logger; import org.slf4j.LoggerFactory; @@ -240,7 +239,9 @@ public void setup() { .addEndpoint( URI.create(httpScheme + bindAddress + ":" + port)).setConf(conf).setFindPort(findPort) - .setACL(new AdminACLsManager(conf).getAdminAcl()) + .setACL(new AccessControlList(conf.get( + YarnConfiguration.YARN_ADMIN_ACL, + YarnConfiguration.DEFAULT_YARN_ADMIN_ACL))) .setPathSpec(pathList.toArray(new String[0])); boolean hasSpnegoConf = spnegoPrincipalKey != null diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/AdminService.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/AdminService.java index d79de58..93c59b4 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/AdminService.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/AdminService.java @@ -56,6 +56,7 @@ import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider; import org.apache.hadoop.yarn.ipc.RPCUtil; import org.apache.hadoop.yarn.ipc.YarnRPC; +import org.apache.hadoop.yarn.security.YarnAuthorizationProvider; import org.apache.hadoop.yarn.server.api.ResourceManagerAdministrationProtocol; import org.apache.hadoop.yarn.server.api.protocolrecords.AddToClusterNodeLabelsRequest; import org.apache.hadoop.yarn.server.api.protocolrecords.AddToClusterNodeLabelsResponse; @@ -103,6 +104,8 @@ private InetSocketAddress masterServiceBindAddress; private AccessControlList adminAcl; + private YarnAuthorizationProvider authorizer; + private final RecordFactory recordFactory = RecordFactoryProvider.getRecordFactory(null); @@ -129,10 +132,11 @@ public void serviceInit(Configuration conf) throws Exception { YarnConfiguration.RM_ADMIN_ADDRESS, YarnConfiguration.DEFAULT_RM_ADMIN_ADDRESS, YarnConfiguration.DEFAULT_RM_ADMIN_PORT); - adminAcl = new AccessControlList(conf.get( - YarnConfiguration.YARN_ADMIN_ACL, - YarnConfiguration.DEFAULT_YARN_ADMIN_ACL)); + YarnConfiguration.YARN_ADMIN_ACL, + YarnConfiguration.DEFAULT_YARN_ADMIN_ACL)); + authorizer = YarnAuthorizationProvider.getInstance(conf); + authorizer.setAdmins(adminAcl); rmId = conf.get(YarnConfiguration.RM_HA_ID); super.serviceInit(conf); } @@ -206,7 +210,7 @@ void resetLeaderElection() { } private UserGroupInformation checkAccess(String method) throws IOException { - return RMServerUtils.verifyAccess(adminAcl, method, LOG); + return RMServerUtils.verifyAccess(authorizer, method, LOG); } private UserGroupInformation checkAcls(String method) throws YarnException { @@ -449,6 +453,7 @@ private RefreshAdminAclsResponse refreshAdminAcls(boolean checkRMHAState) adminAcl = new AccessControlList(conf.get( YarnConfiguration.YARN_ADMIN_ACL, YarnConfiguration.DEFAULT_YARN_ADMIN_ACL)); + authorizer.setAdmins(adminAcl); RMAuditLogger.logSuccess(user.getShortUserName(), argName, "AdminService"); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMServerUtils.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMServerUtils.java index c80778c..81b887a 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMServerUtils.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/RMServerUtils.java @@ -45,6 +45,7 @@ import org.apache.hadoop.yarn.exceptions.InvalidResourceBlacklistRequestException; import org.apache.hadoop.yarn.exceptions.InvalidResourceRequestException; import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; +import org.apache.hadoop.yarn.security.YarnAuthorizationProvider; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.RMAppState; import org.apache.hadoop.yarn.server.resourcemanager.rmapp.attempt.RMAppAttemptState; import org.apache.hadoop.yarn.server.resourcemanager.rmnode.RMNode; @@ -141,16 +142,16 @@ public static void validateBlacklistRequest( } public static UserGroupInformation verifyAccess( - AccessControlList acl, String method, final Log LOG) + YarnAuthorizationProvider authorizer, String method, final Log LOG) throws IOException { // by default, this method will use AdminService as module name - return verifyAccess(acl, method, "AdminService", LOG); + return verifyAccess(authorizer, method, "AdminService", LOG); } /** * Utility method to verify if the current user has access based on the * passed {@link AccessControlList} - * @param acl the {@link AccessControlList} to check against + * @param authorizer the {@link AccessControlList} to check against * @param method the method name to be logged * @param module, like AdminService or NodeLabelManager * @param LOG the logger to use @@ -158,25 +159,25 @@ public static UserGroupInformation verifyAccess( * @throws IOException */ public static UserGroupInformation verifyAccess( - AccessControlList acl, String method, String module, final Log LOG) + YarnAuthorizationProvider authorizer, String method, String module, + final Log LOG) throws IOException { UserGroupInformation user; try { user = UserGroupInformation.getCurrentUser(); } catch (IOException ioe) { LOG.warn("Couldn't get current user", ioe); - RMAuditLogger.logFailure("UNKNOWN", method, acl.toString(), + RMAuditLogger.logFailure("UNKNOWN", method, "", "AdminService", "Couldn't get current user"); throw ioe; } - if (!acl.isUserAllowed(user)) { + if (!authorizer.isAdmin(user)) { LOG.warn("User " + user.getShortUserName() + " doesn't have permission" + " to call '" + method + "'"); - RMAuditLogger.logFailure(user.getShortUserName(), method, - acl.toString(), module, - RMAuditLogger.AuditConstants.UNAUTHORIZED_USER); + RMAuditLogger.logFailure(user.getShortUserName(), method, "", module, + RMAuditLogger.AuditConstants.UNAUTHORIZED_USER); throw new AccessControlException("User " + user.getShortUserName() + " doesn't have permission" + diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java index 4f242e93..a8f9da4 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/ResourceManager.java @@ -19,6 +19,7 @@ package org.apache.hadoop.yarn.server.resourcemanager; import com.google.common.annotations.VisibleForTesting; + import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.classification.InterfaceAudience.Private; @@ -53,6 +54,7 @@ import org.apache.hadoop.yarn.event.Dispatcher; import org.apache.hadoop.yarn.event.EventHandler; import org.apache.hadoop.yarn.exceptions.YarnRuntimeException; +import org.apache.hadoop.yarn.security.YarnAuthorizationProvider; import org.apache.hadoop.yarn.server.resourcemanager.ahs.RMApplicationHistoryWriter; import org.apache.hadoop.yarn.server.resourcemanager.amlauncher.AMLauncherEventType; import org.apache.hadoop.yarn.server.resourcemanager.amlauncher.ApplicationMasterLauncher; @@ -236,6 +238,8 @@ protected void serviceInit(Configuration conf) throws Exception { throw new YarnRuntimeException("Failed to login", ie); } + YarnAuthorizationProvider.getInstance(conf).init(conf); + // register the handlers for all AlwaysOn services using setupDispatcher(). rmDispatcher = setupDispatcher(); addIfService(rmDispatcher); diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/nodelabels/RMNodeLabelsManager.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/nodelabels/RMNodeLabelsManager.java index 18478e3..25479b7 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/nodelabels/RMNodeLabelsManager.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/nodelabels/RMNodeLabelsManager.java @@ -33,12 +33,11 @@ import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.security.UserGroupInformation; -import org.apache.hadoop.security.authorize.AccessControlList; import org.apache.hadoop.yarn.api.records.NodeId; import org.apache.hadoop.yarn.api.records.Resource; -import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.hadoop.yarn.nodelabels.CommonNodeLabelsManager; import org.apache.hadoop.yarn.nodelabels.NodeLabel; +import org.apache.hadoop.yarn.security.YarnAuthorizationProvider; import org.apache.hadoop.yarn.server.resourcemanager.RMContext; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.event.NodeLabelsUpdateSchedulerEvent; import org.apache.hadoop.yarn.util.resource.Resources; @@ -60,16 +59,13 @@ protected Queue() { ConcurrentMap queueCollections = new ConcurrentHashMap(); - protected AccessControlList adminAcl; - + private YarnAuthorizationProvider authorizer; private RMContext rmContext = null; @Override protected void serviceInit(Configuration conf) throws Exception { super.serviceInit(conf); - adminAcl = - new AccessControlList(conf.get(YarnConfiguration.YARN_ADMIN_ACL, - YarnConfiguration.DEFAULT_YARN_ADMIN_ACL)); + authorizer = YarnAuthorizationProvider.getInstance(conf); } @Override @@ -468,7 +464,7 @@ private boolean isNodeUsableByQueue(Set nodeLabels, Queue q) { public boolean checkAccess(UserGroupInformation user) { // make sure only admin can invoke // this method - if (adminAcl.isUserAllowed(user)) { + if (authorizer.isAdmin(user)) { return true; } return false; diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/AbstractCSQueue.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/AbstractCSQueue.java index fec3a56..0bc6fa8 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/AbstractCSQueue.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/AbstractCSQueue.java @@ -33,6 +33,10 @@ import org.apache.hadoop.yarn.api.records.Resource; import org.apache.hadoop.yarn.factories.RecordFactory; import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider; +import org.apache.hadoop.yarn.security.PrivilegedEntity; +import org.apache.hadoop.yarn.security.PrivilegedEntity.EntityType; +import org.apache.hadoop.yarn.security.YarnAuthorizationProvider; +import org.apache.hadoop.yarn.security.YarnAuthorizationProvider.AccessType; import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.QueueMetrics; import org.apache.hadoop.yarn.server.resourcemanager.scheduler.SchedulerUtils; @@ -59,7 +63,8 @@ final Resource maximumAllocation; QueueState state; final QueueMetrics metrics; - + protected final PrivilegedEntity queueEntity; + final ResourceCalculator resourceCalculator; Set accessibleLabels; RMNodeLabelsManager labelManager; @@ -77,7 +82,8 @@ private final RecordFactory recordFactory = RecordFactoryProvider.getRecordFactory(null); - + protected YarnAuthorizationProvider authorizer = null; + public AbstractCSQueue(CapacitySchedulerContext cs, String queueName, CSQueue parent, CSQueue old) throws IOException { this.minimumAllocation = cs.getMinimumResourceCapability(); @@ -120,6 +126,8 @@ public AbstractCSQueue(CapacitySchedulerContext cs, maxCapacityByNodeLabels = cs.getConfiguration().getMaximumNodeLabelCapacities(getQueuePath(), accessibleLabels, labelManager); + queueEntity = new PrivilegedEntity(EntityType.QUEUE, queueName); + authorizer = YarnAuthorizationProvider.getInstance(cs.getConf()); } @Override @@ -193,7 +201,7 @@ public synchronized void setParent(CSQueue newParentQueue) { @Override public boolean hasAccess(QueueACL acl, UserGroupInformation user) { synchronized (this) { - if (acls.get(acl).isUserAllowed(user)) { + if (authorizer.checkPermission(toAccessType(acl), queueEntity, user)) { return true; } } @@ -204,7 +212,17 @@ public boolean hasAccess(QueueACL acl, UserGroupInformation user) { return false; } - + + protected AccessType toAccessType(QueueACL acl) { + switch (acl) { + case ADMINISTER_QUEUE: + return AccessType.ADMINISTER_QUEUE; + case SUBMIT_APPLICATIONS: + return AccessType.SUBMIT_APP; + } + return null; + } + @Override public synchronized void setUsedCapacity(float usedCapacity) { this.usedCapacity = usedCapacity; diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/LeafQueue.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/LeafQueue.java index fd8a7ee..ed17da6 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/LeafQueue.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/LeafQueue.java @@ -55,6 +55,7 @@ import org.apache.hadoop.yarn.factories.RecordFactory; import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider; import org.apache.hadoop.yarn.nodelabels.CommonNodeLabelsManager; +import org.apache.hadoop.yarn.security.YarnAuthorizationProvider.AccessType; import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager; import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainer; import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainerEventType; @@ -240,11 +241,14 @@ protected synchronized void setupQueueConfigs( } this.nodeLocalityDelay = nodeLocalityDelay; + Map queueAcl= new HashMap<>(); StringBuilder aclsString = new StringBuilder(); for (Map.Entry e : acls.entrySet()) { aclsString.append(e.getKey() + ":" + e.getValue().getAclString()); + queueAcl.put(toAccessType(e.getKey()), e.getValue()); } + authorizer.setPermission(queueEntity, queueAcl); StringBuilder labelStrBuilder = new StringBuilder(); if (labels != null) { diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/ParentQueue.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/ParentQueue.java index f820cca..d22158e 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/ParentQueue.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-resourcemanager/src/main/java/org/apache/hadoop/yarn/server/resourcemanager/scheduler/capacity/ParentQueue.java @@ -27,6 +27,7 @@ import java.util.Iterator; import java.util.List; import java.util.Map; +import java.util.Map.Entry; import java.util.Set; import java.util.TreeSet; @@ -49,6 +50,7 @@ import org.apache.hadoop.yarn.factories.RecordFactory; import org.apache.hadoop.yarn.factory.providers.RecordFactoryProvider; import org.apache.hadoop.yarn.nodelabels.CommonNodeLabelsManager; +import org.apache.hadoop.yarn.security.YarnAuthorizationProvider.AccessType; import org.apache.hadoop.yarn.server.resourcemanager.nodelabels.RMNodeLabelsManager; import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainer; import org.apache.hadoop.yarn.server.resourcemanager.rmcontainer.RMContainerEventType; @@ -74,7 +76,6 @@ final Comparator queueComparator; volatile int numApplications; private final CapacitySchedulerContext scheduler; - private final RecordFactory recordFactory = RecordFactoryProvider.getRecordFactory(null); @@ -110,6 +111,12 @@ public ParentQueue(CapacitySchedulerContext cs, Map acls = cs.getConfiguration().getAcls(getQueuePath()); + Map queueAcl= new HashMap<>(); + for (Entry e : acls.entrySet()) { + queueAcl.put(toAccessType(e.getKey()), e.getValue()); + } + authorizer.setPermission(queueEntity, queueAcl); + setupQueueConfigs(cs.getClusterResource(), capacity, absoluteCapacity, maximumCapacity, absoluteMaxCapacity, state, acls, accessibleLabels, defaultLabelExpression, capacitiyByNodeLabels, maxCapacityByNodeLabels, diff --git a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-sharedcachemanager/src/main/java/org/apache/hadoop/yarn/server/sharedcachemanager/SCMAdminProtocolService.java b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-sharedcachemanager/src/main/java/org/apache/hadoop/yarn/server/sharedcachemanager/SCMAdminProtocolService.java index 3ecca02..6ac1500 100644 --- a/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-sharedcachemanager/src/main/java/org/apache/hadoop/yarn/server/sharedcachemanager/SCMAdminProtocolService.java +++ b/hadoop-yarn-project/hadoop-yarn/hadoop-yarn-server/hadoop-yarn-server-sharedcachemanager/src/main/java/org/apache/hadoop/yarn/server/sharedcachemanager/SCMAdminProtocolService.java @@ -31,6 +31,7 @@ import org.apache.hadoop.security.UserGroupInformation; import org.apache.hadoop.security.authorize.AccessControlList; import org.apache.hadoop.service.AbstractService; +import org.apache.hadoop.yarn.security.YarnAuthorizationProvider; import org.apache.hadoop.yarn.server.api.SCMAdminProtocol; import org.apache.hadoop.yarn.server.api.protocolrecords.RunSharedCacheCleanerTaskRequest; import org.apache.hadoop.yarn.server.api.protocolrecords.RunSharedCacheCleanerTaskResponse; @@ -58,8 +59,7 @@ private Server server; InetSocketAddress clientBindAddress; private final CleanerService cleanerService; - private AccessControlList adminAcl; - + private YarnAuthorizationProvider authorizer; public SCMAdminProtocolService(CleanerService cleanerService) { super(SCMAdminProtocolService.class.getName()); this.cleanerService = cleanerService; @@ -68,9 +68,8 @@ public SCMAdminProtocolService(CleanerService cleanerService) { @Override protected void serviceInit(Configuration conf) throws Exception { this.clientBindAddress = getBindAddress(conf); - adminAcl = new AccessControlList(conf.get( - YarnConfiguration.YARN_ADMIN_ACL, - YarnConfiguration.DEFAULT_YARN_ADMIN_ACL)); + authorizer = YarnAuthorizationProvider.getInstance(conf); + authorizer.init(conf); super.serviceInit(conf); } @@ -119,7 +118,7 @@ private void checkAcls(String method) throws YarnException { throw RPCUtil.getRemoteException(ioe); } - if (!adminAcl.isUserAllowed(user)) { + if (!authorizer.isAdmin(user)) { LOG.warn("User " + user.getShortUserName() + " doesn't have permission" + " to call '" + method + "'");