/** * 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.tez.common.security; import java.util.Arrays; import java.util.Collections; import java.util.HashMap; import java.util.Map; import java.util.Map.Entry; import java.util.Set; import java.util.regex.Pattern; import org.slf4j.Logger; import org.slf4j.LoggerFactory; import org.apache.hadoop.classification.InterfaceAudience.Private; import org.apache.hadoop.conf.Configuration; import org.apache.hadoop.yarn.conf.YarnConfiguration; import org.apache.tez.common.TezCommonUtils; import org.apache.tez.dag.api.TezConfiguration; import org.apache.tez.dag.api.TezConstants; import com.google.common.collect.Sets; /** * Parser for extracting ACL information from Configs */ @Private public class ACLConfigurationParser { private static final Logger LOG = LoggerFactory.getLogger(ACLConfigurationParser.class); private final Configuration conf; private final Map<ACLType, Set<String>> allowedUsers; private final Map<ACLType, Set<String>> allowedGroups; private static final Pattern splitPattern = Pattern.compile("\\s+"); public ACLConfigurationParser(Configuration conf) { this(conf, false); } public ACLConfigurationParser(Configuration conf, boolean dagACLs) { this.conf = conf; allowedUsers = new HashMap<ACLType, Set<String>>(2); allowedGroups = new HashMap<ACLType, Set<String>>(2); parse(dagACLs); } private void parse(boolean dagACLs) { if (!dagACLs) { parseACLType(YarnConfiguration.YARN_ADMIN_ACL, ACLType.YARN_ADMIN_ACL); parseACLType(TezConfiguration.TEZ_AM_VIEW_ACLS, ACLType.AM_VIEW_ACL); parseACLType(TezConfiguration.TEZ_AM_MODIFY_ACLS, ACLType.AM_MODIFY_ACL); } else { parseACLType(YarnConfiguration.YARN_ADMIN_ACL, ACLType.YARN_ADMIN_ACL); parseACLType(TezConstants.TEZ_DAG_VIEW_ACLS, ACLType.DAG_VIEW_ACL); parseACLType(TezConstants.TEZ_DAG_MODIFY_ACLS, ACLType.DAG_MODIFY_ACL); } } private boolean isWildCard(String aclStr) { return aclStr.trim().equals(ACLManager.WILDCARD_ACL_VALUE); } private void parseACLType(String configProperty, ACLType aclType) { String aclsStr = conf.get(configProperty); if (aclsStr == null || aclsStr.isEmpty()) { return; } if (isWildCard(aclsStr)) { allowedUsers.put(aclType, Sets.newHashSet(ACLManager.WILDCARD_ACL_VALUE)); return; } final String[] splits = splitPattern.split(aclsStr); int counter = -1; String userListStr = null; String groupListStr = null; for (String s : splits) { if (s.isEmpty()) { if (userListStr != null) { continue; } } ++counter; if (counter == 0) { userListStr = s; } else if (counter == 1) { groupListStr = s; } else { LOG.warn("Invalid configuration specified for " + configProperty + ", ignoring configured ACLs, value=" + aclsStr); return; } } if (userListStr == null) { return; } if (userListStr.length() >= 1) { allowedUsers.put(aclType, Sets.newLinkedHashSet(Arrays.asList(TezCommonUtils.getTrimmedStrings(userListStr)))); } if (groupListStr != null && groupListStr.length() >= 1) { allowedGroups.put(aclType, Sets.newLinkedHashSet(Arrays.asList(TezCommonUtils.getTrimmedStrings(groupListStr)))); } } public Map<ACLType, Set<String>> getAllowedUsers() { return Collections.unmodifiableMap(allowedUsers); } public Map<ACLType, Set<String>> getAllowedGroups() { return Collections.unmodifiableMap(allowedGroups); } public void addAllowedUsers(Map<ACLType, Set<String>> additionalAllowedUsers) { for (Entry<ACLType, Set<String>> entry : additionalAllowedUsers.entrySet()) { if (allowedUsers.containsKey(entry.getKey())) { allowedUsers.get(entry.getKey()).addAll(entry.getValue()); } else { allowedUsers.put(entry.getKey(), entry.getValue()); } } } public void addAllowedGroups(Map<ACLType, Set<String>> additionalAllowedGroups) { for (Entry<ACLType, Set<String>> entry : additionalAllowedGroups.entrySet()) { if (allowedGroups.containsKey(entry.getKey())) { allowedGroups.get(entry.getKey()).addAll(entry.getValue()); } else { allowedGroups.put(entry.getKey(), entry.getValue()); } } } }