blob: 0f1d1c872babda782953814c13b272c9520ff2eb [file] [log] [blame]
/**
* 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.falcon.security;
import org.apache.commons.lang3.StringUtils;
import org.apache.falcon.FalconException;
import org.apache.falcon.entity.v0.Entity;
import org.apache.falcon.util.ReflectionUtils;
import org.apache.falcon.util.StartupProperties;
import org.apache.hadoop.security.authentication.server.KerberosAuthenticationHandler;
import org.apache.hadoop.security.authentication.server.PseudoAuthenticationHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.IOException;
import java.net.InetAddress;
import java.net.UnknownHostException;
/**
* Security Util - bunch of security related helper methods.
*/
public final class SecurityUtil {
/**
* Constant for the configuration property that indicates the prefix.
*/
private static final String CONFIG_PREFIX = "falcon.authentication.";
/**
* Constant for the configuration property that indicates the authentication type.
*/
public static final String AUTHENTICATION_TYPE = CONFIG_PREFIX + "type";
/**
* Constant for the configuration property that indicates the Name node principal.
*/
public static final String NN_PRINCIPAL = "dfs.namenode.kerberos.principal";
/**
* Constant for the configuration property that indicates the
* Resource Manager principal. This is useful when the remote cluster realm
* (with cross domain trust) or the auth to local rule definition results in a
* different RM principal than in Falcon server cluster.
*/
public static final String RM_PRINCIPAL = "yarn.resourcemanager.principal";
/**
* Constant for the configuration property that indicates the Name node principal.
* This is used to talk to Hive Meta Store during parsing and validations only.
*/
public static final String HIVE_METASTORE_KERBEROS_PRINCIPAL = "hive.metastore.kerberos.principal";
public static final String METASTORE_USE_THRIFT_SASL = "hive.metastore.sasl.enabled";
public static final String METASTORE_PRINCIPAL = "hcat.metastore.principal";
private static final Logger LOG = LoggerFactory.getLogger(SecurityUtil.class);
private SecurityUtil() {
}
public static String getAuthenticationType() {
return StartupProperties.get().getProperty(
AUTHENTICATION_TYPE, PseudoAuthenticationHandler.TYPE);
}
/**
* Checks if kerberos authentication is enabled in the configuration.
*
* @return true if falcon.authentication.type is kerberos, false otherwise
*/
public static boolean isSecurityEnabled() {
String authenticationType = StartupProperties.get().getProperty(
AUTHENTICATION_TYPE, PseudoAuthenticationHandler.TYPE);
final boolean useKerberos;
if (authenticationType == null || PseudoAuthenticationHandler.TYPE.equals(authenticationType)) {
useKerberos = false;
} else if (KerberosAuthenticationHandler.TYPE.equals(authenticationType)) {
useKerberos = true;
} else {
throw new IllegalArgumentException("Invalid attribute value for "
+ AUTHENTICATION_TYPE + " of " + authenticationType);
}
return useKerberos;
}
public static String getLocalHostName() throws UnknownHostException {
return InetAddress.getLocalHost().getCanonicalHostName();
}
/**
* Checks if authorization is enabled in the configuration.
*
* @return true if falcon.security.authorization.enabled is enabled, false otherwise
*/
public static boolean isAuthorizationEnabled() {
return Boolean.valueOf(StartupProperties.get().getProperty(
"falcon.security.authorization.enabled", "false"));
}
/**
* Checks if CSRF filter is enabled in the configuration.
*
* @return true if falcon.security.csrf.enabled is enabled, false otherwise
*/
public static boolean isCSRFFilterEnabled() {
return Boolean.valueOf(StartupProperties.get().getProperty(
"falcon.security.csrf.enabled", "false"));
}
public static AuthorizationProvider getAuthorizationProvider() throws FalconException {
String providerClassName = StartupProperties.get().getProperty(
"falcon.security.authorization.provider",
"org.apache.falcon.security.DefaultAuthorizationProvider");
return ReflectionUtils.getInstanceByClassName(providerClassName);
}
public static void tryProxy(Entity entity, final String doAsUser) throws IOException, FalconException {
if (entity != null && entity.getACL() != null && SecurityUtil.isAuthorizationEnabled()) {
final String aclOwner = entity.getACL().getOwner();
final String aclGroup = entity.getACL().getGroup();
if (StringUtils.isNotEmpty(doAsUser)) {
if (!doAsUser.equalsIgnoreCase(aclOwner)) {
LOG.warn("doAs user {} not same as acl owner {}. Ignoring acl owner.", doAsUser, aclOwner);
throw new FalconException("doAs user and ACL owner mismatch. doAs user " + doAsUser
+ " should be same as ACL owner " + aclOwner);
}
return;
}
if (SecurityUtil.getAuthorizationProvider().shouldProxy(
CurrentUser.getAuthenticatedUGI(), aclOwner, aclGroup)) {
CurrentUser.proxy(aclOwner, aclGroup);
}
}
}
}