/* * 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.plugin.service; import java.io.IOException; import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; import java.util.List; import java.util.Map; import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.hadoop.security.SecureClientLogin; import org.apache.hadoop.security.authentication.util.KerberosName; import org.apache.ranger.authorization.hadoop.config.RangerConfiguration; import org.apache.ranger.plugin.model.RangerPolicy; import org.apache.ranger.plugin.model.RangerService; import org.apache.ranger.plugin.model.RangerServiceDef; import org.apache.ranger.plugin.model.validation.RangerServiceDefHelper; import org.apache.ranger.plugin.resourcematcher.RangerAbstractResourceMatcher; public abstract class RangerBaseService { private static final Log LOG = LogFactory.getLog(RangerBaseService.class); protected static final String ADMIN_USER_PRINCIPAL = "ranger.admin.kerberos.principal"; protected static final String ADMIN_USER_KEYTAB = "ranger.admin.kerberos.keytab"; protected static final String LOOKUP_PRINCIPAL = "ranger.lookup.kerberos.principal"; protected static final String LOOKUP_KEYTAB = "ranger.lookup.kerberos.keytab"; protected static final String RANGER_AUTH_TYPE = "hadoop.security.authentication"; protected static final String KERBEROS_TYPE = "kerberos"; protected RangerServiceDef serviceDef; protected RangerService service; protected Map<String, String> configs; protected String serviceName; protected String serviceType; public void init(RangerServiceDef serviceDef, RangerService service) { this.serviceDef = serviceDef; this.service = service; this.configs = service.getConfigs(); this.serviceName = service.getName(); this.serviceType = service.getType(); } /** * @return the serviceDef */ public RangerServiceDef getServiceDef() { return serviceDef; } /** * @return the service */ public RangerService getService() { return service; } public Map<String, String> getConfigs() { return configs; } public void setConfigs(Map<String, String> configs) { this.configs = configs; } public String getServiceName() { return serviceName; } public void setServiceName(String serviceName) { this.serviceName = serviceName; } public String getServiceType() { return serviceType; } public void setServiceType(String serviceType) { this.serviceType = serviceType; } public abstract Map<String, Object> validateConfig() throws Exception; public abstract List<String> lookupResource(ResourceLookupContext context) throws Exception; public List<RangerPolicy> getDefaultRangerPolicies() throws Exception { if (LOG.isDebugEnabled()) { LOG.debug("==> RangerBaseService.getDefaultRangerPolicies() "); } List<RangerPolicy> ret = new ArrayList<RangerPolicy>(); try { // we need to create one policy for each resource hierarchy RangerServiceDefHelper serviceDefHelper = new RangerServiceDefHelper(serviceDef); for (List<RangerServiceDef.RangerResourceDef> aHierarchy : serviceDefHelper.getResourceHierarchies(RangerPolicy.POLICY_TYPE_ACCESS)) { RangerPolicy policy = getDefaultPolicy(aHierarchy); if (policy != null) { ret.add(policy); } } } catch (Exception e) { LOG.error("Error getting default polcies for Service: " + service.getName(), e); } if (LOG.isDebugEnabled()) { LOG.debug("<== RangerBaseService.getDefaultRangerPolicies(): " + ret); } return ret; } public List<RangerPolicy.RangerPolicyItemAccess> getAndAllowAllAccesses() { List<RangerPolicy.RangerPolicyItemAccess> ret = new ArrayList<RangerPolicy.RangerPolicyItemAccess>(); for (RangerServiceDef.RangerAccessTypeDef accessTypeDef : serviceDef.getAccessTypes()) { RangerPolicy.RangerPolicyItemAccess access = new RangerPolicy.RangerPolicyItemAccess(); access.setType(accessTypeDef.getName()); access.setIsAllowed(true); ret.add(access); } return ret; } private RangerPolicy getDefaultPolicy(List<RangerServiceDef.RangerResourceDef> resourceHierarchy) throws Exception { if (LOG.isDebugEnabled()) { LOG.debug("==> RangerBaseService.getDefaultPolicy()"); } RangerPolicy policy = new RangerPolicy(); String policyName=buildPolicyName(resourceHierarchy); policy.setIsEnabled(true); policy.setVersion(1L); policy.setName(policyName); policy.setService(service.getName()); policy.setDescription("Policy for " + policyName); policy.setIsAuditEnabled(true); policy.setResources(createDefaultPolicyResource(resourceHierarchy)); List<RangerPolicy.RangerPolicyItem> policyItems = new ArrayList<RangerPolicy.RangerPolicyItem>(); //Create Default policy item for the service user RangerPolicy.RangerPolicyItem policyItem = createDefaultPolicyItem(); policyItems.add(policyItem); policy.setPolicyItems(policyItems); if (LOG.isDebugEnabled()) { LOG.debug("<== RangerBaseService.getDefaultPolicy()" + policy); } return policy; } private RangerPolicy.RangerPolicyItem createDefaultPolicyItem() throws Exception { if (LOG.isDebugEnabled()) { LOG.debug("==> RangerBaseService.createDefaultPolicyItem()"); } RangerPolicy.RangerPolicyItem policyItem = new RangerPolicy.RangerPolicyItem(); policyItem.setUsers(getUserList()); policyItem.setAccesses(getAndAllowAllAccesses()); policyItem.setDelegateAdmin(true); if (LOG.isDebugEnabled()) { LOG.debug("<== RangerBaseService.createDefaultPolicyItem(): " + policyItem ); } return policyItem; } private Map<String, RangerPolicy.RangerPolicyResource> createDefaultPolicyResource(List<RangerServiceDef.RangerResourceDef> resourceHierarchy) throws Exception { if (LOG.isDebugEnabled()) { LOG.debug("==> RangerBaseService.createDefaultPolicyResource()"); } Map<String, RangerPolicy.RangerPolicyResource> resourceMap = new HashMap<>(); for (RangerServiceDef.RangerResourceDef resourceDef : resourceHierarchy) { RangerPolicy.RangerPolicyResource polRes = new RangerPolicy.RangerPolicyResource(); polRes.setIsExcludes(false); polRes.setIsRecursive(resourceDef.getRecursiveSupported()); polRes.setValue(RangerAbstractResourceMatcher.WILDCARD_ASTERISK); resourceMap.put(resourceDef.getName(), polRes); } if (LOG.isDebugEnabled()) { LOG.debug("<== RangerBaseService.createDefaultPolicyResource():" + resourceMap); } return resourceMap; } private String buildPolicyName(List<RangerServiceDef.RangerResourceDef> resourceHierarchy) { StringBuilder sb = new StringBuilder("all"); if (CollectionUtils.isNotEmpty(resourceHierarchy)) { int resourceDefCount = 0; for (RangerServiceDef.RangerResourceDef resourceDef : resourceHierarchy) { if (resourceDefCount > 0) { sb.append(", "); } else { sb.append(" - "); } sb.append(resourceDef.getName()); resourceDefCount++; } } return sb.toString().trim(); } private List<String> getUserList() { List<String> ret = new ArrayList<>(); Map<String, String> serviceConfig = service.getConfigs(); if (serviceConfig != null ) { ret.add(serviceConfig.get("username")); String defaultUsers = serviceConfig.get("default.policy.users"); if (!StringUtils.isEmpty(defaultUsers)) { List<String> defaultUserList = new ArrayList<>(Arrays.asList(StringUtils.split(defaultUsers,","))); if (!defaultUserList.isEmpty()) { ret.addAll(defaultUserList); } } } String authType = RangerConfiguration.getInstance().get(RANGER_AUTH_TYPE,"simple"); String lookupPrincipal = RangerConfiguration.getInstance().get(LOOKUP_PRINCIPAL); String lookupKeytab = RangerConfiguration.getInstance().get(LOOKUP_KEYTAB); String lookUpUser = getLookupUser(authType, lookupPrincipal, lookupKeytab); if (StringUtils.isNotBlank(lookUpUser)) { ret.add(lookUpUser); } return ret; } protected String getLookupUser(String authType, String lookupPrincipal, String lookupKeytab) { String lookupUser = null; if(!StringUtils.isEmpty(authType) && authType.equalsIgnoreCase(KERBEROS_TYPE)){ if(SecureClientLogin.isKerberosCredentialExists(lookupPrincipal, lookupKeytab)){ KerberosName krbName = new KerberosName(lookupPrincipal); try { lookupUser = krbName.getShortName(); } catch (IOException e) { LOG.error("Unknown lookup user", e); } } } return lookupUser; } }