blob: ba6b459bbef5d7bebe39ad1e70b1a956440b9a0e [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.ranger.authorization.hive.authorizer;
import org.apache.commons.collections.MapUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePolicyChangeListener;
import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePolicyProvider;
import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject;
import org.apache.hadoop.hive.ql.security.authorization.plugin.HiveResourceACLs;
import org.apache.ranger.plugin.policyengine.RangerAccessRequestImpl;
import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
import org.apache.ranger.plugin.policyengine.RangerResourceACLs;
import org.apache.ranger.plugin.policyevaluator.RangerPolicyEvaluator;
import org.apache.ranger.plugin.service.RangerAuthContextListener;
import org.apache.ranger.plugin.service.RangerBasePlugin;
import org.apache.ranger.plugin.util.RangerPerfTracer;
import javax.validation.constraints.NotNull;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
public class RangerHivePolicyProvider implements HivePolicyProvider {
private static final Log LOG = LogFactory.getLog(RangerHivePolicyProvider.class);
private static final Log PERF_HIVEACLPROVIDER_REQUEST_LOG = RangerPerfTracer.getPerfLogger("hiveACLProvider.request");
private final RangerHiveAuthContextListener authContextListener = new RangerHiveAuthContextListener();
private final Set<String> hivePrivileges;
private final RangerBasePlugin rangerPlugin;
public RangerHivePolicyProvider(@NotNull RangerBasePlugin hivePlugin) {
Set<String> privileges = new HashSet<>();
for (HiveResourceACLs.Privilege privilege : HiveResourceACLs.Privilege.values()) {
privileges.add(privilege.name().toLowerCase());
}
this.hivePrivileges = new HashSet<>(privileges);
this.rangerPlugin = hivePlugin;
}
@Override
public HiveResourceACLs getResourceACLs(HivePrivilegeObject hiveObject) {
HiveResourceACLs ret;
RangerPerfTracer perf = null;
if (RangerPerfTracer.isPerfTraceEnabled(PERF_HIVEACLPROVIDER_REQUEST_LOG)) {
perf = RangerPerfTracer.getPerfTracer(PERF_HIVEACLPROVIDER_REQUEST_LOG, "RangerHivePolicyProvider.getResourceACLS()");
}
// Extract and build RangerHiveResource from inputObject
RangerHiveResource hiveResource = RangerHiveAuthorizer.createHiveResource(hiveObject);
ret = getResourceACLs(hiveResource);
RangerPerfTracer.log(perf);
return ret;
}
@Override
public void registerHivePolicyChangeListener(HivePolicyChangeListener listener) {
if (LOG.isDebugEnabled()) {
LOG.debug("==> RangerHiveACLProviderFactory.registerACLProviderChangeListener()");
}
authContextListener.providerChangeListeners.add(listener);
rangerPlugin.registerAuthContextEventListener(authContextListener);
if (LOG.isDebugEnabled()) {
LOG.debug("<== RangerHiveACLProviderFactory.registerACLProviderChangeListener()");
}
}
public HiveResourceACLs getResourceACLs(RangerHiveResource hiveResource) {
HiveResourceACLs ret;
RangerAccessRequestImpl request = new RangerAccessRequestImpl(hiveResource, RangerPolicyEngine.ANY_ACCESS, null, null);
RangerResourceACLs acls = rangerPlugin.getResourceACLs(request);
if (LOG.isDebugEnabled()) {
LOG.debug("HiveResource:[" + hiveResource.getAsString() + "], Computed ACLS:[" + acls + "]");
}
Map<String, Map<HiveResourceACLs.Privilege, HiveResourceACLs.AccessResult>> userPermissions = convertRangerACLsToHiveACLs(acls.getUserACLs());
Map<String, Map<HiveResourceACLs.Privilege, HiveResourceACLs.AccessResult>> groupPermissions = convertRangerACLsToHiveACLs(acls.getGroupACLs());
ret = new RangerHiveResourceACLs(userPermissions, groupPermissions);
return ret;
}
private Map<String, Map<HiveResourceACLs.Privilege, HiveResourceACLs.AccessResult>> convertRangerACLsToHiveACLs(Map<String, Map<String, RangerResourceACLs.AccessResult>> rangerACLs) {
Map<String, Map<HiveResourceACLs.Privilege, HiveResourceACLs.AccessResult>> ret = new HashMap<>();
if (MapUtils.isNotEmpty(rangerACLs)) {
for (Map.Entry<String, Map<String, RangerResourceACLs.AccessResult>> entry : rangerACLs.entrySet()) {
Map<HiveResourceACLs.Privilege, HiveResourceACLs.AccessResult> permissions = new HashMap<>();
ret.put(entry.getKey(), permissions);
for (Map.Entry<String, RangerResourceACLs.AccessResult> permission : entry.getValue().entrySet()) {
if (hivePrivileges.contains(permission.getKey())) {
HiveResourceACLs.Privilege privilege = HiveResourceACLs.Privilege.valueOf(StringUtils.upperCase(permission.getKey()));
HiveResourceACLs.AccessResult accessResult;
int rangerResultValue = permission.getValue().getResult();
if (rangerResultValue == RangerPolicyEvaluator.ACCESS_ALLOWED) {
accessResult = HiveResourceACLs.AccessResult.ALLOWED;
} else if (rangerResultValue == RangerPolicyEvaluator.ACCESS_DENIED) {
accessResult = HiveResourceACLs.AccessResult.NOT_ALLOWED;
} else if (rangerResultValue == RangerPolicyEvaluator.ACCESS_CONDITIONAL) {
accessResult = HiveResourceACLs.AccessResult.CONDITIONAL_ALLOWED;
} else {
// Should not get here
accessResult = HiveResourceACLs.AccessResult.NOT_ALLOWED;
}
permissions.put(privilege, accessResult);
}
}
}
}
return ret;
}
static class RangerHiveAuthContextListener implements RangerAuthContextListener {
Set<HivePolicyChangeListener> providerChangeListeners = new HashSet<>();
public void contextChanged() {
for (HivePolicyChangeListener eventListener : providerChangeListeners) {
eventListener.notifyPolicyChange(null);
}
}
}
}