RANGER-203: 1) Grant/revoke implementation for pluggable-service-model. 2) Hive plugin update for grant/revoke implementation 2) RangerBasePlugin now uses RangerAdminClient instead of ServiceStore to download policies (and for grant/revoke). The plugin does not need ant of ServiceStore methods, except for policy-download.
Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/4e121ea0 Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/4e121ea0 Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/4e121ea0 Branch: refs/heads/master Commit: 4e121ea0da3f846d65abc8d1c79396f32de28406 Parents: 5d6881b Author: Madhan Neethiraj <[email protected]> Authored: Sun Feb 8 14:26:58 2015 -0800 Committer: Madhan Neethiraj <[email protected]> Committed: Sun Feb 8 14:26:58 2015 -0800 ---------------------------------------------------------------------- .../ranger/admin/client/RangerAdminClient.java | 9 +- .../admin/client/RangerAdminRESTClient.java | 370 +++------------- .../ranger/plugin/model/RangerPolicy.java | 6 + .../plugin/policyengine/RangerResourceImpl.java | 25 +- .../RangerDefaultPolicyEvaluator.java | 107 ++++- .../policyevaluator/RangerPolicyEvaluator.java | 6 + .../RangerAbstractResourceMatcher.java | 28 ++ .../resourcematcher/RangerResourceMatcher.java | 2 + .../ranger/plugin/service/RangerBasePlugin.java | 78 +++- .../plugin/store/rest/ServiceRESTStore.java | 11 +- .../ranger/plugin/util/GrantRevokeRequest.java | 239 +++++++++++ .../ranger/plugin/util/PolicyRefresher.java | 16 +- .../ranger/plugin/util/TestPolicyRefresher.java | 183 -------- .../hbase/RangerAuthorizationCoprocessor.java | 4 +- .../authorizer/RangerHiveAccessRequest.java | 4 +- .../hive/authorizer/RangerHiveAuthorizer.java | 168 ++++---- .../hive/authorizer/RangerHiveResource.java | 18 +- .../org/apache/ranger/rest/ServiceREST.java | 425 ++++++++++++++++++- .../conf.dist/security-applicationContext.xml | 2 + 19 files changed, 1041 insertions(+), 660 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminClient.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminClient.java b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminClient.java index a9c2a9a..d5129bb 100644 --- a/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminClient.java +++ b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminClient.java @@ -20,13 +20,14 @@ package org.apache.ranger.admin.client; -import org.apache.ranger.admin.client.datatype.GrantRevokeData; +import org.apache.ranger.plugin.util.GrantRevokeRequest; +import org.apache.ranger.plugin.util.ServicePolicies; public interface RangerAdminClient { - String getPolicies(String repositoryName, long lastModifiedTime, int policyCount, String agentName); + ServicePolicies getServicePoliciesIfUpdated(String serviceName, long lastKnownVersion) throws Exception; - void grantPrivilege(GrantRevokeData grData) throws Exception; + void grantAccess(String serviceName, GrantRevokeRequest request) throws Exception; - void revokePrivilege(GrantRevokeData grData) throws Exception; + void revokeAccess(String serviceName, GrantRevokeRequest request) throws Exception; } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java index d883dd3..0c28062 100644 --- a/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java +++ b/agents-common/src/main/java/org/apache/ranger/admin/client/RangerAdminRESTClient.java @@ -19,371 +19,125 @@ package org.apache.ranger.admin.client; -import java.io.File; -import java.io.FileInputStream; -import java.io.FileNotFoundException; -import java.io.IOException; -import java.io.InputStream; -import java.util.List; -import java.security.KeyManagementException; -import java.security.KeyStore; -import java.security.KeyStoreException; -import java.security.NoSuchAlgorithmException; -import java.security.SecureRandom; -import java.security.UnrecoverableKeyException; -import java.security.cert.CertificateException; - -import javax.net.ssl.HostnameVerifier; -import javax.net.ssl.KeyManager; -import javax.net.ssl.KeyManagerFactory; -import javax.net.ssl.SSLContext; -import javax.net.ssl.SSLSession; -import javax.net.ssl.TrustManager; -import javax.net.ssl.TrustManagerFactory; - -import com.sun.jersey.api.client.Client; import com.sun.jersey.api.client.ClientResponse; import com.sun.jersey.api.client.WebResource; -import com.sun.jersey.api.client.config.ClientConfig; -import com.sun.jersey.api.client.config.DefaultClientConfig; -import com.sun.jersey.client.urlconnection.HTTPSProperties; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; -import org.apache.hadoop.conf.Configuration; -import org.apache.ranger.admin.client.datatype.GrantRevokeData; import org.apache.ranger.admin.client.datatype.RESTResponse; import org.apache.ranger.authorization.hadoop.config.RangerConfiguration; -import org.apache.ranger.authorization.hadoop.utils.RangerCredentialProvider; -import org.apache.ranger.authorization.utils.StringUtil; +import org.apache.ranger.plugin.util.GrantRevokeRequest; +import org.apache.ranger.plugin.util.RangerRESTClient; +import org.apache.ranger.plugin.util.ServicePolicies; public class RangerAdminRESTClient implements RangerAdminClient { private static final Log LOG = LogFactory.getLog(RangerAdminRESTClient.class); - public static final String RANGER_PROP_POLICYMGR_URL = "xasecure.policymgr.url"; - public static final String RANGER_PROP_POLICYMGR_SSLCONFIG_FILENAME = "xasecure.policymgr.sslconfig.filename"; - - public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE = "xasecure.policymgr.clientssl.keystore"; - public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_PASSWORD = "xasecure.policymgr.clientssl.keystore.password"; - public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_TYPE = "xasecure.policymgr.clientssl.keystore.type"; - public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_CREDENTIAL = "xasecure.policymgr.clientssl.keystore.credential.file"; - public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_CREDENTIAL_ALIAS = "sslKeyStore"; - public static final String RANGER_POLICYMGR_CLIENT_KEY_FILE_TYPE_DEFAULT = "jks"; - - public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE = "xasecure.policymgr.clientssl.truststore"; - public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_PASSWORD = "xasecure.policymgr.clientssl.truststore.password"; - public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_TYPE = "xasecure.policymgr.clientssl.truststore.type"; - public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_CREDENTIAL = "xasecure.policymgr.clientssl.truststore.credential.file"; - public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_CREDENTIAL_ALIAS = "sslTrustStore"; - public static final String RANGER_POLICYMGR_TRUSTSTORE_FILE_TYPE_DEFAULT = "jks"; - - public static final String RANGER_SSL_KEYMANAGER_ALGO_TYPE = "SunX509" ; - public static final String RANGER_SSL_TRUSTMANAGER_ALGO_TYPE = "SunX509" ; - public static final String RANGER_SSL_CONTEXT_ALGO_TYPE = "SSL" ; - - public static final String REST_EXPECTED_MIME_TYPE = "application/json" ; - - private static final String REST_URL_PATH_POLICYLIST = "/service/assets/policyList/"; - private static final String REST_URL_PATH_GRANT = "/service/assets/resources/grant"; - private static final String REST_URL_PATH_REVOKE = "/service/assets/resources/revoke"; - private static final String REST_URL_PARAM_LASTUPDATED_TIME = "epoch"; - private static final String REST_URL_PARAM_POLICY_COUNT = "policyCount"; - private static final String REST_URL_PARAM_AGENT_NAME = "agentId"; + public final String REST_URL_POLICY_GET_FOR_SERVICE_IF_UPDATED = "/service/plugins/policies/download/"; + public final String REST_URL_SERVICE_GRANT_ACCESS = "/service/plugins/services/grant/"; + public final String REST_URL_SERVICE_REVOKE_ACCESS = "/service/plugins/services/revoke/"; - private String mUrl = null; - private String mSslConfigFileName = null; - private boolean mIsSSL = false; + public static final String REST_EXPECTED_MIME_TYPE = "application/json" ; + public static final String REST_MIME_TYPE_JSON = "application/json" ; - private String mKeyStoreURL = null; - private String mKeyStoreAlias = null; - private String mKeyStoreFile = null; - private String mKeyStoreType = null; - private String mTrustStoreURL = null; - private String mTrustStoreAlias = null; - private String mTrustStoreFile = null; - private String mTrustStoreType = null; + private RangerRESTClient restClient = null; public RangerAdminRESTClient() { - mUrl = RangerConfiguration.getInstance().get(RANGER_PROP_POLICYMGR_URL); - mSslConfigFileName = RangerConfiguration.getInstance().get(RANGER_PROP_POLICYMGR_SSLCONFIG_FILENAME); + String url = RangerConfiguration.getInstance().get("ranger.service.store.rest.url"); + String sslConfigFileName = RangerConfiguration.getInstance().get("ranger.service.store.rest.ssl.config.file"); - init(); + init(url, sslConfigFileName); } public RangerAdminRESTClient(String url, String sslConfigFileName) { - mUrl = url; - mSslConfigFileName = sslConfigFileName; - - init(); + init(url, sslConfigFileName); } @Override - public String getPolicies(String repositoryName, long lastModifiedTime, int policyCount, String agentName) { - String ret = null; - Client client = null; + public ServicePolicies getServicePoliciesIfUpdated(String serviceName, long lastKnownVersion) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerAdminRESTClient.getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ")"); + } + + ServicePolicies ret = null; - try { - client = buildClient(); + WebResource webResource = createWebResource(REST_URL_POLICY_GET_FOR_SERVICE_IF_UPDATED + serviceName + "/" + lastKnownVersion); + ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).get(ClientResponse.class); - WebResource webResource = client.resource(mUrl + REST_URL_PATH_POLICYLIST + repositoryName) - .queryParam(REST_URL_PARAM_LASTUPDATED_TIME, String.valueOf(lastModifiedTime)) - .queryParam(REST_URL_PARAM_POLICY_COUNT, String.valueOf(policyCount)) - .queryParam(REST_URL_PARAM_AGENT_NAME, agentName); + if(response != null && response.getStatus() == 200) { + ret = response.getEntity(ServicePolicies.class); + } else if(response != null && response.getStatus() == 304) { + // no change + } else { + RESTResponse resp = RESTResponse.fromClientResponse(response); - ClientResponse response = webResource.accept(REST_EXPECTED_MIME_TYPE).get(ClientResponse.class); + throw new Exception(resp.getMessage()); + } - if(response != null && response.getStatus() == 200) { - ret = response.getEntity(String.class); - } - } finally { - destroy(client); + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerAdminRESTClient.getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + "): " + ret); } return ret; } @Override - public void grantPrivilege(GrantRevokeData grData) throws Exception { - Client client = null; - - try { - client = buildClient(); - - WebResource webResource = client.resource(mUrl + REST_URL_PATH_GRANT); - - ClientResponse response = webResource.accept(REST_EXPECTED_MIME_TYPE).type(REST_EXPECTED_MIME_TYPE).post(ClientResponse.class, grData.toJson()); - - if(response == null || response.getStatus() != 200) { - RESTResponse resp = RESTResponse.fromClientResponse(response); - - throw new Exception(resp.getMessage()); - } - } finally { - destroy(client); + public void grantAccess(String serviceName, GrantRevokeRequest request) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerAdminRESTClient.grantAccess(" + serviceName + ", " + request + ")"); } - } - - @Override - public void revokePrivilege(GrantRevokeData grData) throws Exception { - Client client = null; - - try { - client = buildClient(); - WebResource webResource = client.resource(mUrl + REST_URL_PATH_REVOKE); + WebResource webResource = createWebResource(REST_URL_SERVICE_GRANT_ACCESS + serviceName); + ClientResponse response = webResource.accept(REST_EXPECTED_MIME_TYPE).type(REST_EXPECTED_MIME_TYPE).post(ClientResponse.class, restClient.toJson(request)); - ClientResponse response = webResource.accept(REST_EXPECTED_MIME_TYPE).type(REST_EXPECTED_MIME_TYPE).post(ClientResponse.class, grData.toJson()); + if(response == null || response.getStatus() != 200) { + RESTResponse resp = RESTResponse.fromClientResponse(response); - if(response == null || response.getStatus() != 200) { - RESTResponse resp = RESTResponse.fromClientResponse(response); - - throw new Exception(resp.getMessage()); - } - } finally { - destroy(client); + throw new Exception(resp.getMessage()); } - } - private void init() { - mIsSSL = StringUtil.containsIgnoreCase(mUrl, "https"); - - InputStream in = null ; - - try { - Configuration conf = new Configuration() ; - - in = getFileInputStream(mSslConfigFileName) ; - if (in != null) { - conf.addResource(in); - } - - mKeyStoreURL = conf.get(RANGER_POLICYMGR_CLIENT_KEY_FILE_CREDENTIAL); - mKeyStoreAlias = RANGER_POLICYMGR_CLIENT_KEY_FILE_CREDENTIAL_ALIAS; - mKeyStoreType = conf.get(RANGER_POLICYMGR_CLIENT_KEY_FILE_TYPE, RANGER_POLICYMGR_CLIENT_KEY_FILE_TYPE_DEFAULT); - mKeyStoreFile = conf.get(RANGER_POLICYMGR_CLIENT_KEY_FILE); - - mTrustStoreURL = conf.get(RANGER_POLICYMGR_TRUSTSTORE_FILE_CREDENTIAL); - mTrustStoreAlias = RANGER_POLICYMGR_TRUSTSTORE_FILE_CREDENTIAL_ALIAS; - mTrustStoreType = conf.get(RANGER_POLICYMGR_TRUSTSTORE_FILE_TYPE, RANGER_POLICYMGR_TRUSTSTORE_FILE_TYPE_DEFAULT); - mTrustStoreFile = conf.get(RANGER_POLICYMGR_TRUSTSTORE_FILE); - } - catch(IOException ioe) { - LOG.error("Unable to load SSL Config FileName: [" + mSslConfigFileName + "]", ioe); - } - finally { - close(in, mSslConfigFileName); + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerAdminRESTClient.grantAccess(" + serviceName + ", " + request + ")"); } } - private synchronized Client buildClient() { - Client client = null; - - if (mIsSSL) { - KeyManager[] kmList = getKeyManagers(); - TrustManager[] tmList = getTrustManagers(); - SSLContext sslContext = getSSLContext(kmList, tmList); - ClientConfig config = new DefaultClientConfig(); - - HostnameVerifier hv = new HostnameVerifier() { - public boolean verify(String urlHostName, SSLSession session) { - return session.getPeerHost().equals(urlHostName); - } - }; - - config.getProperties().put(HTTPSProperties.PROPERTY_HTTPS_PROPERTIES, new HTTPSProperties(hv, sslContext)); - - client = Client.create(config); + @Override + public void revokeAccess(String serviceName, GrantRevokeRequest request) throws Exception { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerAdminRESTClient.revokeAccess(" + serviceName + ", " + request + ")"); } - if(client == null) { - client = Client.create(); - } + WebResource webResource = createWebResource(REST_URL_SERVICE_REVOKE_ACCESS + serviceName); + ClientResponse response = webResource.accept(REST_EXPECTED_MIME_TYPE).type(REST_EXPECTED_MIME_TYPE).post(ClientResponse.class, restClient.toJson(request)); - return client; - } + if(response == null || response.getStatus() != 200) { + RESTResponse resp = RESTResponse.fromClientResponse(response); - private KeyManager[] getKeyManagers() { - KeyManager[] kmList = null; - - String keyStoreFilepwd = getCredential(mKeyStoreURL, mKeyStoreAlias); - - if (!StringUtil.isEmpty(mKeyStoreFile) && !StringUtil.isEmpty(keyStoreFilepwd)) { - InputStream in = null ; - - try { - in = getFileInputStream(mKeyStoreFile) ; - - if (in != null) { - KeyStore keyStore = KeyStore.getInstance(mKeyStoreType); - - keyStore.load(in, keyStoreFilepwd.toCharArray()); - - KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance(RANGER_SSL_KEYMANAGER_ALGO_TYPE); - - keyManagerFactory.init(keyStore, keyStoreFilepwd.toCharArray()); - - kmList = keyManagerFactory.getKeyManagers(); - } else { - LOG.error("Unable to obtain keystore from file [" + mKeyStoreFile + "]"); - } - } catch (KeyStoreException e) { - LOG.error("Unable to obtain from KeyStore", e); - } catch (NoSuchAlgorithmException e) { - LOG.error("SSL algorithm is available in the environment", e); - } catch (CertificateException e) { - LOG.error("Unable to obtain the requested certification ", e); - } catch (FileNotFoundException e) { - LOG.error("Unable to find the necessary SSL Keystore and TrustStore Files", e); - } catch (IOException e) { - LOG.error("Unable to read the necessary SSL Keystore and TrustStore Files", e); - } catch (UnrecoverableKeyException e) { - LOG.error("Unable to recover the key from keystore", e); - } finally { - close(in, mKeyStoreFile); - } + throw new Exception(resp.getMessage()); } - return kmList; - } - - private TrustManager[] getTrustManagers() { - TrustManager[] tmList = null; - - String trustStoreFilepwd = getCredential(mTrustStoreURL, mTrustStoreAlias); - - if (!StringUtil.isEmpty(mTrustStoreFile) && !StringUtil.isEmpty(trustStoreFilepwd)) { - InputStream in = null ; - - try { - in = getFileInputStream(mTrustStoreFile) ; - - if (in != null) { - KeyStore trustStore = KeyStore.getInstance(mTrustStoreType); - - trustStore.load(in, trustStoreFilepwd.toCharArray()); - - TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(RANGER_SSL_TRUSTMANAGER_ALGO_TYPE); - - trustManagerFactory.init(trustStore); - - tmList = trustManagerFactory.getTrustManagers(); - } else { - LOG.error("Unable to obtain keystore from file [" + mTrustStoreFile + "]"); - } - } catch (KeyStoreException e) { - LOG.error("Unable to obtain from KeyStore", e); - } catch (NoSuchAlgorithmException e) { - LOG.error("SSL algorithm is available in the environment", e); - } catch (CertificateException e) { - LOG.error("Unable to obtain the requested certification ", e); - } catch (FileNotFoundException e) { - LOG.error("Unable to find the necessary SSL Keystore and TrustStore Files", e); - } catch (IOException e) { - LOG.error("Unable to read the necessary SSL Keystore and TrustStore Files", e); - } finally { - close(in, mTrustStoreFile); - } + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerAdminRESTClient.revokeAccess(" + serviceName + ", " + request + ")"); } - - return tmList; - } - - private SSLContext getSSLContext(KeyManager[] kmList, TrustManager[] tmList) { - try { - if(kmList != null && tmList != null) { - SSLContext sslContext = SSLContext.getInstance(RANGER_SSL_CONTEXT_ALGO_TYPE); - - sslContext.init(kmList, tmList, new SecureRandom()); - - return sslContext; - } - } catch (NoSuchAlgorithmException e) { - LOG.error("SSL algorithm is available in the environment", e); - } catch (KeyManagementException e) { - LOG.error("Unable to initials the SSLContext", e); - } - - return null; - } - - private String getCredential(String url, String alias) { - char[] credStr = RangerCredentialProvider.getInstance().getCredentialString(url, alias); - - return credStr == null ? null : new String(credStr); } - private InputStream getFileInputStream(String fileName) throws IOException { - InputStream in = null ; - - if(! StringUtil.isEmpty(fileName)) { - File f = new File(fileName) ; - - if (f.exists()) { - in = new FileInputStream(f) ; - } - else { - in = ClassLoader.getSystemResourceAsStream(fileName) ; - } + private void init(String url, String sslConfigFileName) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerAdminRESTClient.init(" + url + ", " + sslConfigFileName + ")"); } - return in ; - } + restClient = new RangerRESTClient(url, sslConfigFileName); - private void close(InputStream str, String filename) { - if (str != null) { - try { - str.close() ; - } catch (IOException excp) { - LOG.error("Error while closing file: [" + filename + "]", excp) ; - } + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerAdminRESTClient.init(" + url + ", " + sslConfigFileName + ")"); } } - private void destroy(Client client) { - if(client != null) { - client.destroy(); - } + private WebResource createWebResource(String url) { + WebResource ret = restClient.getResource(url); + + return ret; } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java index 78ba6e2..d118f84 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerPolicy.java @@ -258,6 +258,12 @@ public class RangerPolicy extends RangerBaseModelObject implements java.io.Seria this((List<String>)null, null, null); } + public RangerPolicyResource(String value) { + setValue(value); + setIsExcludes(null); + setIsRecursive(null); + } + public RangerPolicyResource(String value, Boolean isExcludes, Boolean isRecursive) { setValue(value); setIsExcludes(isExcludes); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceImpl.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceImpl.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceImpl.java index 740a427..da82cc3 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceImpl.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyengine/RangerResourceImpl.java @@ -30,6 +30,16 @@ public class RangerResourceImpl implements RangerMutableResource { public RangerResourceImpl() { + this(null, null); + } + + public RangerResourceImpl(Map<String, String> elements) { + this(elements, null); + } + + public RangerResourceImpl(Map<String, String> elements, String ownerUser) { + this.elements = elements; + this.ownerUser = ownerUser; } @Override @@ -71,13 +81,18 @@ public class RangerResourceImpl implements RangerMutableResource { @Override public void setValue(String name, String value) { - if(elements == null) { - elements = new HashMap<String, String>(); - } - if(value == null) { - elements.remove(name); + if(elements != null) { + elements.remove(name); + + if(elements.isEmpty()) { + elements = null; + } + } } else { + if(elements == null) { + elements = new HashMap<String, String>(); + } elements.put(name, value); } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java index 17fcc5e..f3322d2 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerDefaultPolicyEvaluator.java @@ -66,12 +66,14 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator String resourceName = resourceDef.getName(); RangerPolicyResource policyResource = policy.getResources().get(resourceName); - RangerResourceMatcher matcher = createResourceMatcher(resourceDef, policyResource); + if(policyResource != null) { + RangerResourceMatcher matcher = createResourceMatcher(resourceDef, policyResource); - if(matcher != null) { - matchers.put(resourceName, matcher); - } else { - LOG.error("failed to find matcher for resource " + resourceName); + if(matcher != null) { + matchers.put(resourceName, matcher); + } else { + LOG.error("failed to find matcher for resource " + resourceName); + } } } } @@ -90,7 +92,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator RangerPolicy policy = getPolicy(); if(policy != null && request != null && result != null) { - boolean isResourceMatch = matchResource(request.getResource()); + boolean isResourceMatch = isMatch(request.getResource()); boolean isResourceHeadMatch = isResourceMatch || matchResourceHead(request.getResource()); String accessType = request.getAccessType(); @@ -98,7 +100,8 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator accessType = RangerPolicyEngine.ANY_ACCESS; } - boolean isAnyAccess = StringUtils.equals(accessType, RangerPolicyEngine.ANY_ACCESS); + boolean isAnyAccess = StringUtils.equals(accessType, RangerPolicyEngine.ANY_ACCESS); + boolean isAdminAccess = StringUtils.equals(accessType, RangerPolicyEngine.ADMIN_ACCESS); if(isResourceMatch || (isResourceHeadMatch && isAnyAccess)) { if(policy.getIsAuditEnabled()) { @@ -106,8 +109,14 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator } for(RangerPolicyItem policyItem : policy.getPolicyItems()) { - if(result.getIsAllowed()) { - break; + if(isAdminAccess) { + if(policyItem.getDelegateAdmin()) { + result.setIsAllowed(true); + result.setPolicyId(policy.getId()); + break; + } + + continue; } if(CollectionUtils.isEmpty(policyItem.getAccesses())) { @@ -121,11 +130,11 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator } boolean isCustomConditionsMatch = matchCustomConditions(policyItem, request); - + if(! isCustomConditionsMatch) { continue; } - + if(isAnyAccess) { for(RangerPolicyItemAccess access : policyItem.getAccesses()) { if(access.getIsAllowed()) { @@ -142,6 +151,10 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator result.setPolicyId(policy.getId()); } } + + if(result.getIsAllowed()) { + break; + } } } } @@ -151,9 +164,10 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator } } - protected boolean matchResource(RangerResource resource) { + @Override + public boolean isMatch(RangerResource resource) { if(LOG.isDebugEnabled()) { - LOG.debug("==> RangerDefaultPolicyEvaluator.matchResource(" + resource + ")"); + LOG.debug("==> RangerDefaultPolicyEvaluator.isMatch(" + resource + ")"); } boolean ret = false; @@ -163,8 +177,8 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator if(serviceDef != null && serviceDef.getResources() != null) { Collection<String> resourceKeys = resource == null ? null : resource.getKeys(); Collection<String> policyKeys = matchers == null ? null : matchers.keySet(); - - boolean keysMatch = (resourceKeys == null) || (policyKeys != null && policyKeys.containsAll(resourceKeys)); + + boolean keysMatch = CollectionUtils.isEmpty(resourceKeys) || (policyKeys != null && policyKeys.containsAll(resourceKeys)); if(keysMatch) { for(RangerResourceDef resourceDef : serviceDef.getResources()) { @@ -172,7 +186,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator String resourceValue = resource == null ? null : resource.getValue(resourceName); RangerResourceMatcher matcher = matchers == null ? null : matchers.get(resourceName); - // when no value exists for a resourceName, consider it a match only if (policy doesn't have a matcher OR matcher allows no-value resource) + // when no value exists for a resourceName, consider it a match only if: policy doesn't have a matcher OR matcher allows no-value resource if(StringUtils.isEmpty(resourceValue)) { ret = matcher == null || matcher.isMatch(resourceValue); } else { @@ -183,11 +197,60 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator break; } } + } else { + if(LOG.isDebugEnabled()) { + LOG.debug("isMatch(): keysMatch=false. isMatch=" + resourceKeys + "; policyKeys=" + policyKeys); + } } } if(LOG.isDebugEnabled()) { - LOG.debug("<== RangerDefaultPolicyEvaluator.matchResource(" + resource + "): " + ret); + LOG.debug("<== RangerDefaultPolicyEvaluator.isMatch(" + resource + "): " + ret); + } + + return ret; + } + + public boolean isSingleAndExactMatch(RangerResource resource) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerDefaultPolicyEvaluator.isSingleAndExactMatch(" + resource + ")"); + } + + boolean ret = false; + + RangerServiceDef serviceDef = getServiceDef(); + + if(serviceDef != null && serviceDef.getResources() != null) { + Collection<String> resourceKeys = resource == null ? null : resource.getKeys(); + Collection<String> policyKeys = matchers == null ? null : matchers.keySet(); + + boolean keysMatch = CollectionUtils.isEqualCollection(resourceKeys, policyKeys); + + if(keysMatch) { + for(RangerResourceDef resourceDef : serviceDef.getResources()) { + String resourceName = resourceDef.getName(); + String resourceValue = resource == null ? null : resource.getValue(resourceName); + RangerResourceMatcher matcher = matchers == null ? null : matchers.get(resourceName); + + if(StringUtils.isEmpty(resourceValue)) { + ret = matcher == null || matcher.isSingleAndExactMatch(resourceValue); + } else { + ret = matcher != null && matcher.isSingleAndExactMatch(resourceValue); + } + + if(! ret) { + break; + } + } + } else { + if(LOG.isDebugEnabled()) { + LOG.debug("isSingleAndExactMatch(): keysMatch=false. resourceKeys=" + resourceKeys + "; policyKeys=" + policyKeys); + } + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerDefaultPolicyEvaluator.isSingleAndExactMatch(" + resource + "): " + ret); } return ret; @@ -227,7 +290,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator } else { isMatch = matcher != null && matcher.isMatch(resourceValue); } - + if(isMatch) { numMatched++; } else { @@ -235,7 +298,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator } } } - + ret = (numMatched > 0) && serviceDef.getResources().size() == (numMatched + numUnmatched); } @@ -257,7 +320,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator if(!ret && user != null && policyItem.getUsers() != null) { ret = policyItem.getUsers().contains(user); } - + if(!ret && groups != null && policyItem.getGroups() != null) { ret = policyItem.getGroups().contains(RangerPolicyEngine.GROUP_PUBLIC) || !Collections.disjoint(policyItem.getGroups(), groups); @@ -337,7 +400,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator if(ret == null) { ret = new RangerDefaultResourceMatcher(); } - + if(ret != null) { ret.init(resourceDef, resource, options); } @@ -351,7 +414,7 @@ public class RangerDefaultPolicyEvaluator extends RangerAbstractPolicyEvaluator public StringBuilder toString(StringBuilder sb) { sb.append("RangerDefaultPolicyEvaluator={"); - + super.toString(sb); sb.append("matchers={"); http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java index b6e0f10..cfe53a8 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/policyevaluator/RangerPolicyEvaluator.java @@ -19,10 +19,12 @@ package org.apache.ranger.plugin.policyevaluator; + import org.apache.ranger.plugin.model.RangerPolicy; import org.apache.ranger.plugin.model.RangerServiceDef; import org.apache.ranger.plugin.policyengine.RangerAccessRequest; import org.apache.ranger.plugin.policyengine.RangerAccessResult; +import org.apache.ranger.plugin.policyengine.RangerResource; public interface RangerPolicyEvaluator { void init(RangerPolicy policy, RangerServiceDef serviceDef); @@ -32,4 +34,8 @@ public interface RangerPolicyEvaluator { RangerServiceDef getServiceDef(); void evaluate(RangerAccessRequest request, RangerAccessResult result); + + boolean isMatch(RangerResource resource); + + boolean isSingleAndExactMatch(RangerResource resource); } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java index 3da7198..81f2412 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerAbstractResourceMatcher.java @@ -24,6 +24,7 @@ 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; @@ -136,6 +137,33 @@ public abstract class RangerAbstractResourceMatcher implements RangerResourceMat return optionsString; } + @Override + public boolean isSingleAndExactMatch(String resource) { + if(LOG.isDebugEnabled()) { + LOG.debug("==> RangerAbstractResourceMatcher.isSingleAndExactMatch(" + resource + ")"); + } + + boolean ret = false; + + if(CollectionUtils.isEmpty(policyValues)) { + ret = StringUtils.isEmpty(resource); + } else if(policyValues.size() == 1) { + String policyValue = policyValues.get(0); + + if(isMatchAny) { + ret = StringUtils.equals(resource, "*"); + } else { + ret = optIgnoreCase ? StringUtils.equalsIgnoreCase(resource, policyValue) : StringUtils.equals(resource, policyValue); + } + } + + if(LOG.isDebugEnabled()) { + LOG.debug("<== RangerAbstractResourceMatcher.isSingleAndExactMatch(" + resource + "): " + ret); + } + + return ret; + } + public String getOption(String name) { String ret = null; http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java index c750cd8..1368afb 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/resourcematcher/RangerResourceMatcher.java @@ -32,4 +32,6 @@ public interface RangerResourceMatcher { String getOptionsString(); boolean isMatch(String resource); + + boolean isSingleAndExactMatch(String resource); } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java index f442b9a..68ac3aa 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/service/RangerBasePlugin.java @@ -22,23 +22,28 @@ package org.apache.ranger.plugin.service; import java.util.Collection; import org.apache.commons.lang.StringUtils; +import org.apache.commons.logging.Log; +import org.apache.commons.logging.LogFactory; +import org.apache.ranger.admin.client.RangerAdminClient; +import org.apache.ranger.admin.client.RangerAdminRESTClient; import org.apache.ranger.authorization.hadoop.config.RangerConfiguration; import org.apache.ranger.plugin.audit.RangerAuditHandler; import org.apache.ranger.plugin.policyengine.RangerAccessRequest; import org.apache.ranger.plugin.policyengine.RangerAccessResult; import org.apache.ranger.plugin.policyengine.RangerPolicyEngine; import org.apache.ranger.plugin.policyengine.RangerPolicyEngineImpl; -import org.apache.ranger.plugin.store.ServiceStore; -import org.apache.ranger.plugin.store.ServiceStoreFactory; +import org.apache.ranger.plugin.util.GrantRevokeRequest; import org.apache.ranger.plugin.util.PolicyRefresher; public class RangerBasePlugin { + private static final Log LOG = LogFactory.getLog(RangerBasePlugin.class); + private String serviceType = null; private String auditAppType = null; private String serviceName = null; - private RangerPolicyEngine policyEngine = null; private PolicyRefresher refresher = null; + private RangerPolicyEngine policyEngine = null; public RangerBasePlugin(String serviceType, String auditAppType) { @@ -58,6 +63,10 @@ public class RangerBasePlugin { return serviceName; } + public PolicyRefresher getPolicyRefresher() { + return refresher; + } + public RangerPolicyEngine getPolicyEngine() { return policyEngine; } @@ -74,10 +83,7 @@ public class RangerBasePlugin { RangerConfiguration.getInstance().addResourcesForServiceType(serviceType); RangerConfiguration.getInstance().initAudit(auditAppType); - String serviceName = RangerConfiguration.getInstance().get("ranger.plugin." + serviceType + ".service.name"); - String serviceStoreClass = RangerConfiguration.getInstance().get("ranger.plugin." + serviceType + ".service.store.class", "org.apache.ranger.plugin.store.rest.ServiceRESTStore"); - String cacheDir = RangerConfiguration.getInstance().get("ranger.plugin." + serviceType + ".service.store.cache.dir", "/tmp"); - long pollingIntervalMs = RangerConfiguration.getInstance().getLong("ranger.plugin." + serviceType + ".service.store.pollIntervalMs", 30 * 1000); + serviceName = RangerConfiguration.getInstance().get("ranger.plugin." + serviceType + ".service.name"); if(StringUtils.isEmpty(serviceName)) { // get the serviceName from download URL: http://ranger-admin-host:port/service/assets/policyList/serviceName @@ -92,9 +98,12 @@ public class RangerBasePlugin { } } - ServiceStore serviceStore = ServiceStoreFactory.instance().getServiceStore(serviceStoreClass); + String cacheDir = RangerConfiguration.getInstance().get("ranger.plugin." + serviceType + ".service.store.cache.dir", "/tmp"); + long pollingIntervalMs = RangerConfiguration.getInstance().getLong("ranger.plugin." + serviceType + ".service.store.pollIntervalMs", 30 * 1000); + + RangerAdminClient admin = new RangerAdminRESTClient(); - refresher = new PolicyRefresher(policyEngine, serviceType, serviceName, serviceStore, pollingIntervalMs, cacheDir); + refresher = new PolicyRefresher(policyEngine, serviceType, serviceName, admin, pollingIntervalMs, cacheDir); refresher.startRefresher(); this.policyEngine = policyEngine; } @@ -130,17 +139,6 @@ public class RangerBasePlugin { } - public RangerAccessResult createAccessResult(RangerAccessRequest request) { - RangerPolicyEngine policyEngine = this.policyEngine; - - if(policyEngine != null) { - return policyEngine.createAccessResult(request); - } - - return null; - } - - public RangerAccessResult isAccessAllowed(RangerAccessRequest request) { RangerPolicyEngine policyEngine = this.policyEngine; @@ -183,4 +181,44 @@ public class RangerBasePlugin { return null; } + + public boolean grantAccess(GrantRevokeRequest request, RangerAuditHandler auditHandler) { + boolean ret = false; + + PolicyRefresher refresher = this.refresher; + + if(refresher != null) { + RangerAdminClient admin = refresher.getRangerAdminClient(); + + if(admin != null) { + try { + admin.grantAccess(serviceName, request); + } catch(Exception excp) { + LOG.error("grantAccess() failed", excp); + } + } + } + + return ret; + } + + public boolean revokeAccess(GrantRevokeRequest request, RangerAuditHandler auditHandler) { + boolean ret = false; + + PolicyRefresher refresher = this.refresher; + + if(refresher != null) { + RangerAdminClient admin = refresher.getRangerAdminClient(); + + if(admin != null) { + try { + admin.revokeAccess(serviceName, request); + } catch(Exception excp) { + LOG.error("revokeAccess() failed", excp); + } + } + } + + return ret; + } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/agents-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java b/agents-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java index dcdce10..ca8024f 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/store/rest/ServiceRESTStore.java @@ -20,7 +20,9 @@ package org.apache.ranger.plugin.store.rest; import java.util.List; +import java.util.Map; +import org.apache.commons.collections.MapUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; import org.apache.ranger.admin.client.datatype.RESTResponse; @@ -599,8 +601,13 @@ public class ServiceRESTStore implements ServiceStore { private WebResource createWebResource(String url, SearchFilter filter) { WebResource ret = restClient.getResource(url); - if(filter != null) { - // TODO: add query params for filter + if(filter != null && !MapUtils.isEmpty(filter.getParams())) { + for(Map.Entry<String, String> e : filter.getParams().entrySet()) { + String name = e.getKey(); + String value = e.getValue(); + + ret.queryParam(name, value); + } } return ret; http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/agents-common/src/main/java/org/apache/ranger/plugin/util/GrantRevokeRequest.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/GrantRevokeRequest.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/GrantRevokeRequest.java new file mode 100644 index 0000000..b40ea18 --- /dev/null +++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/GrantRevokeRequest.java @@ -0,0 +1,239 @@ +/* + * 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.util; + +import java.io.Serializable; +import java.util.HashMap; +import java.util.HashSet; +import java.util.Map; +import java.util.Set; + +import javax.xml.bind.annotation.XmlAccessType; +import javax.xml.bind.annotation.XmlAccessorType; +import javax.xml.bind.annotation.XmlRootElement; + +import org.codehaus.jackson.annotate.JsonAutoDetect; +import org.codehaus.jackson.annotate.JsonIgnoreProperties; +import org.codehaus.jackson.annotate.JsonAutoDetect.Visibility; +import org.codehaus.jackson.map.annotate.JsonSerialize; + + +@JsonAutoDetect(getterVisibility=Visibility.NONE, setterVisibility=Visibility.NONE, fieldVisibility=Visibility.ANY) +@JsonSerialize(include=JsonSerialize.Inclusion.NON_NULL ) +@JsonIgnoreProperties(ignoreUnknown=true) +@XmlRootElement +@XmlAccessorType(XmlAccessType.FIELD) +public class GrantRevokeRequest implements Serializable { + private static final long serialVersionUID = 1L; + + private String grantor = null; + private Map<String, String> resource = null; + private Set<String> users = null; + private Set<String> groups = null; + private Set<String> accessTypes = null; + private Boolean delegateAdmin = Boolean.FALSE; + private Boolean enableAudit = Boolean.TRUE; + private Boolean replaceExistingPermissions = Boolean.FALSE; + + + public GrantRevokeRequest() { + this(null, null, null, null, null, null, null, null); + } + + public GrantRevokeRequest(String grantor, Map<String, String> resource, Set<String> users, Set<String> groups, Set<String> accessTypes, Boolean delegateAdmin, Boolean enableAudit, Boolean replaceExistingPermissions) { + setGrantor(grantor); + setResource(resource); + setUsers(users); + setGroups(groups); + setAccessTypes(accessTypes); + setDelegateAdmin(delegateAdmin); + setAccessTypes(accessTypes); + setEnableAudit(enableAudit); + setReplaceExistingPermissions(replaceExistingPermissions); + } + + /** + * @return the grantor + */ + public String getGrantor() { + return grantor; + } + + /** + * @param grantor the grantor to set + */ + public void setGrantor(String grantor) { + this.grantor = grantor; + } + + /** + * @return the resource + */ + public Map<String, String> getResource() { + return resource; + } + + /** + * @param resource the resource to set + */ + public void setResource(Map<String, String> resource) { + this.resource = resource == null ? new HashMap<String, String>() : resource; + } + + /** + * @return the users + */ + public Set<String> getUsers() { + return users; + } + + /** + * @param users the users to set + */ + public void setUsers(Set<String> users) { + this.users = users == null ? new HashSet<String>() : users; + } + + /** + * @return the groups + */ + public Set<String> getGroups() { + return groups; + } + + /** + * @param groups the groups to set + */ + public void setGroups(Set<String> groups) { + this.groups = groups == null ? new HashSet<String>() : groups; + } + + /** + * @return the accessTypes + */ + public Set<String> getAccessTypes() { + return accessTypes; + } + + /** + * @param accessTypes the accessTypes to set + */ + public void setAccessTypes(Set<String> accessTypes) { + this.accessTypes = accessTypes == null ? new HashSet<String>() : groups; + } + + /** + * @return the delegateAdmin + */ + public Boolean getDelegateAdmin() { + return delegateAdmin; + } + + /** + * @param delegateAdmin the delegateAdmin to set + */ + public void setDelegateAdmin(Boolean delegateAdmin) { + this.delegateAdmin = delegateAdmin == null ? Boolean.FALSE : delegateAdmin; + } + + /** + * @return the enableAudit + */ + public Boolean getEnableAudit() { + return enableAudit; + } + + /** + * @param enableAudit the enableAudit to set + */ + public void setEnableAudit(Boolean enableAudit) { + this.enableAudit = enableAudit == null ? Boolean.TRUE : enableAudit; + } + + /** + * @return the replaceExistingPermissions + */ + public Boolean getReplaceExistingPermissions() { + return replaceExistingPermissions; + } + + /** + * @param replaceExistingPermissions the replaceExistingPermissions to set + */ + public void setReplaceExistingPermissions(Boolean replaceExistingPermissions) { + this.replaceExistingPermissions = replaceExistingPermissions == null ? Boolean.FALSE : replaceExistingPermissions; + } + + + @Override + public String toString( ) { + StringBuilder sb = new StringBuilder(); + + toString(sb); + + return sb.toString(); + } + + public StringBuilder toString(StringBuilder sb) { + sb.append("GrantRevokeRequest={"); + + sb.append("grantor={").append(grantor).append("} "); + + sb.append("resource={"); + if(resource != null) { + for(Map.Entry<String, String> e : resource.entrySet()) { + sb.append(e.getKey()).append("=").append(e.getValue()).append("; "); + } + } + sb.append("} "); + + sb.append("users={"); + if(users != null) { + for(String user : users) { + sb.append(user).append(" "); + } + } + sb.append("} "); + + sb.append("groups={"); + if(groups != null) { + for(String group : groups) { + sb.append(group).append(" "); + } + } + sb.append("} "); + + sb.append("accessTypes={"); + if(accessTypes != null) { + for(String accessType : accessTypes) { + sb.append(accessType).append(" "); + } + } + sb.append("} "); + + sb.append("delegateAdmin={").append(delegateAdmin).append("} "); + sb.append("enableAudit={").append(enableAudit).append("} "); + sb.append("replaceExistingPermissions={").append(replaceExistingPermissions).append("} "); + + sb.append("}"); + + return sb; + } +} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/agents-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java ---------------------------------------------------------------------- diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java index a814bfb..4974a10 100644 --- a/agents-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java +++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/PolicyRefresher.java @@ -28,8 +28,8 @@ import java.io.Writer; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; +import org.apache.ranger.admin.client.RangerAdminClient; import org.apache.ranger.plugin.policyengine.RangerPolicyEngine; -import org.apache.ranger.plugin.store.ServiceStore; import com.google.gson.Gson; import com.google.gson.GsonBuilder; @@ -41,7 +41,7 @@ public class PolicyRefresher extends Thread { private RangerPolicyEngine policyEngine = null; private String serviceType = null; private String serviceName = null; - private ServiceStore serviceStore = null; + private RangerAdminClient rangerAdmin = null; private long pollingIntervalMs = 30 * 1000; private String cacheFile = null; @@ -51,7 +51,7 @@ public class PolicyRefresher extends Thread { - public PolicyRefresher(RangerPolicyEngine policyEngine, String serviceType, String serviceName, ServiceStore serviceStore, long pollingIntervalMs, String cacheDir) { + public PolicyRefresher(RangerPolicyEngine policyEngine, String serviceType, String serviceName, RangerAdminClient rangerAdmin, long pollingIntervalMs, String cacheDir) { if(LOG.isDebugEnabled()) { LOG.debug("==> PolicyRefresher(serviceName=" + serviceName + ").PolicyRefresher()"); } @@ -59,7 +59,7 @@ public class PolicyRefresher extends Thread { this.policyEngine = policyEngine; this.serviceType = serviceType; this.serviceName = serviceName; - this.serviceStore = serviceStore; + this.rangerAdmin = rangerAdmin; this.pollingIntervalMs = pollingIntervalMs; this.cacheFile = cacheDir == null ? null : (cacheDir + File.separator + String.format("%s_%s.json", serviceType, serviceName)); @@ -96,10 +96,10 @@ public class PolicyRefresher extends Thread { } /** - * @return the serviceStore + * @return the rangerAdmin */ - public ServiceStore getServiceStore() { - return serviceStore; + public RangerAdminClient getRangerAdminClient() { + return rangerAdmin; } /** @@ -136,7 +136,7 @@ public class PolicyRefresher extends Thread { while(! shutdownFlag) { try { - ServicePolicies svcPolicies = serviceStore.getServicePoliciesIfUpdated(serviceName, lastKnownVersion); + ServicePolicies svcPolicies = rangerAdmin.getServicePoliciesIfUpdated(serviceName, lastKnownVersion); boolean isUpdated = svcPolicies != null; http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/agents-common/src/test/java/org/apache/ranger/plugin/util/TestPolicyRefresher.java ---------------------------------------------------------------------- diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestPolicyRefresher.java b/agents-common/src/test/java/org/apache/ranger/plugin/util/TestPolicyRefresher.java deleted file mode 100644 index 4cf7e3c..0000000 --- a/agents-common/src/test/java/org/apache/ranger/plugin/util/TestPolicyRefresher.java +++ /dev/null @@ -1,183 +0,0 @@ -/* - * 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.util; - -import static org.junit.Assert.*; - -import java.util.List; - -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.RangerPolicy.RangerPolicyItem; -import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess; -import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource; -import org.apache.ranger.plugin.policyengine.RangerPolicyEngineImpl; -import org.apache.ranger.plugin.store.ServiceStore; -import org.apache.ranger.plugin.store.ServiceStoreFactory; -import org.junit.AfterClass; -import org.junit.BeforeClass; -import org.junit.Test; - - -public class TestPolicyRefresher { - static RangerPolicyEngineImpl policyEngine = null; - static ServiceStore svcStore = null; - static PolicyRefresher refresher = null; - - static final long pollingIntervalInMs = 5 * 1000; - static final long sleepTimeInMs = pollingIntervalInMs + (5 * 1000); - static final String sdName = "hbase"; - static final String svcName = "svc-unit-test-TestPolicyRefresher"; - - static RangerService svc = null; - static RangerPolicy policy1 = null; - static RangerPolicy policy2 = null; - - static boolean isPolicyRefreshed = false; - static long policyCount = 0; - - - /** - * @throws java.lang.Exception - */ - @BeforeClass - public static void setUpBeforeClass() throws Exception { - svcStore = ServiceStoreFactory.instance().getServiceStore(); - - // cleanup if the test service already exists - svc = svcStore.getServiceByName(svcName); - if(svc != null) { - svcStore.deleteService(svc.getId()); - } - - policyEngine = new RangerPolicyEngineImpl() { - @Override - public void setPolicies(String serviceName, RangerServiceDef serviceDef, List<RangerPolicy> policies) { - isPolicyRefreshed = true; - policyCount = policies != null ? policies.size() : 0; - - super.setPolicies(serviceName, serviceDef, policies); - } - }; - - refresher = new PolicyRefresher(policyEngine, sdName, svcName, svcStore, pollingIntervalInMs, null); - refresher.start(); - - // create a service - svc = new RangerService(sdName, svcName, "test service description", null); - - svc = svcStore.createService(svc); - assertNotNull("createService(" + svcName + ") failed", svc); - } - - /** - * @throws java.lang.Exception - */ - @AfterClass - public static void tearDownAfterClass() throws Exception { - if(refresher != null) { - refresher.stopRefresher(); - } - - if(svcStore != null) { - if(policy1 != null) { - svcStore.deletePolicy(policy1.getId()); - } - - if(policy2 != null) { - svcStore.deletePolicy(policy2.getId()); - } - - if(svc != null) { - svcStore.deleteService(svc.getId()); - } - } - } - - @Test - public void testRefresher() throws Exception { - assertEquals("policy count - initial", 0, policyCount); - - RangerPolicy policy = new RangerPolicy(svc.getName(), "policy1", "test policy description", null, null); - policy.getResources().put("table", new RangerPolicyResource("employee", Boolean.FALSE, Boolean.TRUE)); - policy.getResources().put("column-family", new RangerPolicyResource("personal", Boolean.FALSE, Boolean.TRUE)); - policy.getResources().put("column", new RangerPolicyResource("ssn", Boolean.FALSE, Boolean.TRUE)); - - RangerPolicyItem item1 = new RangerPolicyItem(); - item1.getAccesses().add(new RangerPolicyItemAccess("admin")); - item1.getUsers().add("admin"); - item1.getGroups().add("hr"); - - RangerPolicyItem item2 = new RangerPolicyItem(); - item2.getAccesses().add(new RangerPolicyItemAccess("read")); - item2.getGroups().add("public"); - - policy.getPolicyItems().add(item1); - policy.getPolicyItems().add(item2); - - policy1 = svcStore.createPolicy(policy); - - policy = new RangerPolicy(svc.getName(), "policy2", "test policy description", null, null); - policy.getResources().put("table", new RangerPolicyResource("employee", Boolean.FALSE, Boolean.TRUE)); - policy.getResources().put("column-family", new RangerPolicyResource("finance", Boolean.FALSE, Boolean.TRUE)); - policy.getResources().put("column", new RangerPolicyResource("balance", Boolean.FALSE, Boolean.TRUE)); - - item1 = new RangerPolicyItem(); - item1.getAccesses().add(new RangerPolicyItemAccess("admin")); - item1.getUsers().add("admin"); - item1.getGroups().add("finance"); - - policy.getPolicyItems().add(item1); - - policy2 = svcStore.createPolicy(policy); - - Thread.sleep(sleepTimeInMs); - assertTrue("policy refresh - after two new policies", isPolicyRefreshed); - assertEquals("policy count - after two new policies", 2, policyCount); - isPolicyRefreshed = false; - - Thread.sleep(sleepTimeInMs); - assertFalse("policy refresh - after no new policies", isPolicyRefreshed); - assertEquals("policy count - after no new policies", 2, policyCount); - isPolicyRefreshed = false; - - item2 = new RangerPolicyItem(); - item2.getAccesses().add(new RangerPolicyItemAccess("read")); - item2.getGroups().add("public"); - policy2.getPolicyItems().add(item2); - - policy2 = svcStore.updatePolicy(policy2); - - Thread.sleep(sleepTimeInMs); - assertTrue("policy refresh - after update policy", isPolicyRefreshed); - assertEquals("policy count - after update policy", 2, policyCount); - isPolicyRefreshed = false; - - svcStore.deletePolicy(policy2.getId()); - - Thread.sleep(sleepTimeInMs); - assertTrue("policy refresh - after delete policy", isPolicyRefreshed); - assertEquals("policy count - after delete policy", 1, policyCount); - isPolicyRefreshed = false; - policy2 = null; - } - -} http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java ---------------------------------------------------------------------- diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java index 08c40e2..828ab7a 100644 --- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java +++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/RangerAuthorizationCoprocessor.java @@ -992,7 +992,7 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess RangerAdminRESTClient xaAdmin = new RangerAdminRESTClient(); - xaAdmin.grantPrivilege(grData); + // TODO: xaAdmin.grantPrivilege(grData); isSuccess = true; } catch(IOException excp) { @@ -1034,7 +1034,7 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess RangerAdminRESTClient xaAdmin = new RangerAdminRESTClient(); - xaAdmin.revokePrivilege(grData); + // TODO: xaAdmin.revokePrivilege(grData); isSuccess = true; } catch(IOException excp) { http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAccessRequest.java ---------------------------------------------------------------------- diff --git a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAccessRequest.java b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAccessRequest.java index 7617a6f..39f5773 100644 --- a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAccessRequest.java +++ b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAccessRequest.java @@ -63,8 +63,10 @@ public class RangerHiveAccessRequest extends RangerAccessRequestImpl { if(accessType == HiveAccessType.USE) { this.setAccessType(RangerPolicyEngine.ANY_ACCESS); + } else if(accessType == HiveAccessType.ADMIN) { + this.setAccessType(RangerPolicyEngine.ADMIN_ACCESS); } else { - this.setAccessType(accessType.toString().toLowerCase()); + this.setAccessType(accessType.name().toLowerCase()); } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java ---------------------------------------------------------------------- diff --git a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java index 980c56c..e862943 100644 --- a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java +++ b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java @@ -21,9 +21,12 @@ import java.util.ArrayList; import java.util.Collection; +import java.util.HashMap; import java.util.List; +import java.util.Map; import java.util.Set; +import org.apache.commons.collections.CollectionUtils; import org.apache.commons.lang.StringUtils; import org.apache.commons.logging.Log; import org.apache.commons.logging.LogFactory; @@ -46,14 +49,13 @@ import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObje import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject.HivePrivObjectActionType; import org.apache.hadoop.hive.ql.security.authorization.plugin.HivePrivilegeObject.HivePrivilegeObjectType; import org.apache.hadoop.security.UserGroupInformation; -import org.apache.ranger.admin.client.RangerAdminRESTClient; -import org.apache.ranger.admin.client.datatype.GrantRevokeData; import org.apache.ranger.authorization.hadoop.config.RangerConfiguration; import org.apache.ranger.authorization.hadoop.constants.RangerHadoopConstants; import org.apache.ranger.authorization.utils.StringUtil; import org.apache.ranger.plugin.policyengine.RangerAccessRequest; import org.apache.ranger.plugin.policyengine.RangerAccessResult; import org.apache.ranger.plugin.service.RangerBasePlugin; +import org.apache.ranger.plugin.util.GrantRevokeRequest; import com.google.common.collect.Sets; @@ -62,8 +64,6 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase { private static final char COLUMN_SEP = ','; - private static final boolean UpdateXaPoliciesOnGrantRevoke = RangerConfiguration.getInstance().getBoolean(RangerHadoopConstants.HIVE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_PROP, RangerHadoopConstants.HIVE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_DEFAULT_VALUE); - private static RangerHivePlugin hivePlugin = null ; @@ -119,38 +119,27 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase { HivePrincipal grantorPrincipal, boolean grantOption) throws HiveAuthzPluginException, HiveAccessControlException { - if(! UpdateXaPoliciesOnGrantRevoke) { + if(! RangerHivePlugin.UpdateXaPoliciesOnGrantRevoke) { throw new HiveAuthzPluginException("GRANT/REVOKE not supported in Ranger HiveAuthorizer. Please use Ranger Security Admin to setup access control."); } - /* TODO: - * - boolean isSuccess = false; - RangerHiveObjectAccessInfo objAccessInfo = getHiveAccessRequests(HiveOperationType.GRANT_PRIVILEGE, hivePrivObject, new RangerHiveAccessContext(null, getHiveAuthzSessionContext()), true); + RangerHiveAuditHandler auditHandler = new RangerHiveAuditHandler(); try { - GrantRevokeData grData = createGrantRevokeData(objAccessInfo, hivePrincipals, hivePrivileges, getGrantorUsername(grantorPrincipal), grantOption); + RangerHiveResource resource = getHiveResource(HiveOperationType.GRANT_PRIVILEGE, hivePrivObject); + GrantRevokeRequest request = createGrantRevokeData(resource, hivePrincipals, hivePrivileges, grantorPrincipal, grantOption); + LOG.info("grantPrivileges(): " + request); if(LOG.isDebugEnabled()) { - LOG.debug("grantPrivileges(): " + grData.toJson()); + LOG.debug("grantPrivileges(): " + request); } - RangerAdminRESTClient xaAdmin = new RangerAdminRESTClient(); - - xaAdmin.grantPrivilege(grData); - - isSuccess = true; + hivePlugin.grantAccess(request, auditHandler); } catch(Exception excp) { throw new HiveAccessControlException(excp); } finally { - if(mHiveAccessVerifier.isAudited(objAccessInfo)) { - UserGroupInformation ugi = this.getCurrentUserGroupInfo(); - - // Note: failed return from REST call will be logged as 'DENIED' - logAuditEvent(ugi, objAccessInfo, isSuccess); - } + auditHandler.flushAudit(); } - */ } /** @@ -170,38 +159,27 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase { HivePrincipal grantorPrincipal, boolean grantOption) throws HiveAuthzPluginException, HiveAccessControlException { - if(! UpdateXaPoliciesOnGrantRevoke) { + if(! RangerHivePlugin.UpdateXaPoliciesOnGrantRevoke) { throw new HiveAuthzPluginException("GRANT/REVOKE not supported in Ranger HiveAuthorizer. Please use Ranger Security Admin to setup access control."); } - /* TODO: - * - boolean isSuccess = false; - RangerHiveObjectAccessInfo objAccessInfo = getHiveAccessRequests(HiveOperationType.REVOKE_PRIVILEGE, hivePrivObject, new RangerHiveAccessContext(null, getHiveAuthzSessionContext()), true); + RangerHiveAuditHandler auditHandler = new RangerHiveAuditHandler(); try { - GrantRevokeData grData = createGrantRevokeData(objAccessInfo, hivePrincipals, hivePrivileges, getGrantorUsername(grantorPrincipal), grantOption); + RangerHiveResource resource = getHiveResource(HiveOperationType.REVOKE_PRIVILEGE, hivePrivObject); + GrantRevokeRequest request = createGrantRevokeData(resource, hivePrincipals, hivePrivileges, grantorPrincipal, grantOption); + LOG.info("revokePrivileges(): " + request); if(LOG.isDebugEnabled()) { - LOG.debug("revokePrivileges(): " + grData.toJson()); + LOG.debug("revokePrivileges(): " + request); } - RangerAdminRESTClient xaAdmin = new RangerAdminRESTClient(); - - xaAdmin.revokePrivilege(grData); - - isSuccess = true; + hivePlugin.revokeAccess(request, auditHandler); } catch(Exception excp) { throw new HiveAccessControlException(excp); } finally { - if(mHiveAccessVerifier.isAudited(objAccessInfo)) { - UserGroupInformation ugi = this.getCurrentUserGroupInfo(); - - // Note: failed return from REST call will be logged as 'DENIED' - logAuditEvent(ugi, objAccessInfo, isSuccess); - } + auditHandler.flushAudit(); } - */ } /** @@ -261,8 +239,7 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase { HiveAccessType accessType = getAccessType(hiveObj, hiveOpType, true); - // ADMIN: access check is performed at the Ranger policy server, as a part of updating the permissions - if(accessType == HiveAccessType.ADMIN || accessType == HiveAccessType.NONE) { + if(accessType == HiveAccessType.NONE) { continue; } @@ -291,8 +268,7 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase { HiveAccessType accessType = getAccessType(hiveObj, hiveOpType, false); - // ADMIN: access check is performed at the Ranger policy server, as a part of updating the permissions - if(accessType == HiveAccessType.ADMIN || accessType == HiveAccessType.NONE) { + if(accessType == HiveAccessType.NONE) { continue; } @@ -680,7 +656,6 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase { return ret; } - /* private String getGrantorUsername(HivePrincipal grantorPrincipal) { String grantor = grantorPrincipal != null ? grantorPrincipal.getName() : null; @@ -693,77 +668,75 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase { return grantor; } - private GrantRevokeData createGrantRevokeData(RangerHiveObjectAccessInfo objAccessInfo, - List<HivePrincipal> hivePrincipals, - List<HivePrivilege> hivePrivileges, - String grantor, - boolean grantOption) + private GrantRevokeRequest createGrantRevokeData(RangerHiveResource resource, + List<HivePrincipal> hivePrincipals, + List<HivePrivilege> hivePrivileges, + HivePrincipal grantorPrincipal, + boolean grantOption) throws HiveAccessControlException { - if(objAccessInfo == null || - ! ( objAccessInfo.getObjectType() == HiveObjectType.DATABASE - || objAccessInfo.getObjectType() == HiveObjectType.TABLE - || objAccessInfo.getObjectType() == HiveObjectType.VIEW - || objAccessInfo.getObjectType() == HiveObjectType.COLUMN + if(resource == null || + ! ( resource.getObjectType() == HiveObjectType.DATABASE + || resource.getObjectType() == HiveObjectType.TABLE + || resource.getObjectType() == HiveObjectType.VIEW + || resource.getObjectType() == HiveObjectType.COLUMN ) ) { - throw new HiveAccessControlException("grantPrivileges(): unexpected object type '" + objAccessInfo.getObjectType().name()); + throw new HiveAccessControlException("grant/revoke: unexpected object type '" + (resource == null ? null : resource.getObjectType().name())); } - String database = objAccessInfo.getDatabase(); - String table = objAccessInfo.getObjectType() == HiveObjectType.VIEW ? objAccessInfo.getView() : objAccessInfo.getTable(); - String columns = StringUtil.toString(objAccessInfo.getColumns()); + GrantRevokeRequest ret = new GrantRevokeRequest(); - GrantRevokeData.PermMap permMap = new GrantRevokeData.PermMap (); + ret.setGrantor(getGrantorUsername(grantorPrincipal)); + ret.setDelegateAdmin(grantOption ? Boolean.TRUE : Boolean.FALSE); + ret.setEnableAudit(Boolean.TRUE); + ret.setReplaceExistingPermissions(Boolean.FALSE); - for(HivePrivilege privilege : hivePrivileges) { - String privName = privilege.getName(); + String database = StringUtils.isEmpty(resource.getDatabase()) ? "*" : resource.getDatabase(); + String table = StringUtils.isEmpty(resource.getTableOrUdf()) ? "*" : resource.getTableOrUdf(); + String column = StringUtils.isEmpty(resource.getColumn()) ? "*" : resource.getColumn(); - if(StringUtil.equalsIgnoreCase(privName, HiveAccessType.ALL.name())) { - permMap.addPerm(HiveAccessType.ALL.name()); - } else if(StringUtil.equalsIgnoreCase(privName, HiveAccessType.ALTER.name())) { - permMap.addPerm(HiveAccessType.ALTER.name()); - } else if(StringUtil.equalsIgnoreCase(privName, HiveAccessType.CREATE.name())) { - permMap.addPerm(HiveAccessType.CREATE.name()); - } else if(StringUtil.equalsIgnoreCase(privName, HiveAccessType.DROP.name())) { - permMap.addPerm(HiveAccessType.DROP.name()); - } else if(StringUtil.equalsIgnoreCase(privName, HiveAccessType.INDEX.name())) { - permMap.addPerm(HiveAccessType.INDEX.name()); - } else if(StringUtil.equalsIgnoreCase(privName, HiveAccessType.LOCK.name())) { - permMap.addPerm(HiveAccessType.LOCK.name()); - } else if(StringUtil.equalsIgnoreCase(privName, HiveAccessType.SELECT.name())) { - permMap.addPerm(HiveAccessType.SELECT.name()); - } else if(StringUtil.equalsIgnoreCase(privName, HiveAccessType.UPDATE.name())) { - permMap.addPerm(HiveAccessType.UPDATE.name()); - } - } + Map<String, String> mapResource = new HashMap<String, String>(); + mapResource.put(RangerHiveResource.KEY_DATABASE, database); + mapResource.put(RangerHiveResource.KEY_TABLE, table); + mapResource.put(RangerHiveResource.KEY_COLUMN, column); - if(grantOption) { - permMap.addPerm(HiveAccessType.ADMIN.name()); - } + ret.setResource(mapResource); for(HivePrincipal principal : hivePrincipals) { switch(principal.getType()) { case USER: - permMap.addUser(principal.getName()); + ret.getUsers().add(principal.getName()); break; case GROUP: case ROLE: - permMap.addGroup(principal.getName()); + ret.getGroups().add(principal.getName()); break; - default: + case UNKNOWN: break; } } - GrantRevokeData grData = new GrantRevokeData(); - - grData.setHiveData(grantor, repositoryName, database, table, columns, permMap); + for(HivePrivilege privilege : hivePrivileges) { + String privName = privilege.getName(); + + if(StringUtils.equalsIgnoreCase(privName, HiveAccessType.ALL.name()) || + StringUtils.equalsIgnoreCase(privName, HiveAccessType.ALTER.name()) || + StringUtils.equalsIgnoreCase(privName, HiveAccessType.CREATE.name()) || + StringUtils.equalsIgnoreCase(privName, HiveAccessType.DROP.name()) || + StringUtils.equalsIgnoreCase(privName, HiveAccessType.INDEX.name()) || + StringUtils.equalsIgnoreCase(privName, HiveAccessType.LOCK.name()) || + StringUtils.equalsIgnoreCase(privName, HiveAccessType.SELECT.name()) || + StringUtils.equalsIgnoreCase(privName, HiveAccessType.UPDATE.name())) { + ret.getAccessTypes().add(privName.toLowerCase()); + } else { + LOG.warn("grant/revoke: unexpected privilege type '" + privName + "'. Ignored"); + } + } - return grData; + return ret; } - */ private String toString(HiveOperationType hiveOpType, List<HivePrivilegeObject> inputHObjs, @@ -830,9 +803,18 @@ enum HiveObjectType { NONE, DATABASE, TABLE, VIEW, PARTITION, INDEX, COLUMN, FUN enum HiveAccessType { NONE, CREATE, ALTER, DROP, INDEX, LOCK, SELECT, UPDATE, USE, ALL, ADMIN }; class RangerHivePlugin extends RangerBasePlugin { + public static boolean UpdateXaPoliciesOnGrantRevoke = RangerHadoopConstants.HIVE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_DEFAULT_VALUE; + public RangerHivePlugin(String appType) { super("hive", appType); } + + @Override + public void init() { + super.init(); + + RangerHivePlugin.UpdateXaPoliciesOnGrantRevoke = RangerConfiguration.getInstance().getBoolean(RangerHadoopConstants.HIVE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_PROP, RangerHadoopConstants.HIVE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_DEFAULT_VALUE); + } } http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/4e121ea0/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveResource.java ---------------------------------------------------------------------- diff --git a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveResource.java b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveResource.java index 82e256e..d49bd66 100644 --- a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveResource.java +++ b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveResource.java @@ -29,15 +29,15 @@ import com.google.common.collect.Sets; public class RangerHiveResource implements RangerResource { - private static final String KEY_DATABASE = "database"; - private static final String KEY_TABLE = "table"; - private static final String KEY_UDF = "udf"; - private static final String KEY_COLUMN = "column"; - - private static final Set<String> KEYS_DATABASE = Sets.newHashSet(KEY_DATABASE); - private static final Set<String> KEYS_TABLE = Sets.newHashSet(KEY_DATABASE, KEY_TABLE); - private static final Set<String> KEYS_UDF = Sets.newHashSet(KEY_DATABASE, KEY_UDF); - private static final Set<String> KEYS_COLUMN = Sets.newHashSet(KEY_DATABASE, KEY_TABLE, KEY_COLUMN); + public static final String KEY_DATABASE = "database"; + public static final String KEY_TABLE = "table"; + public static final String KEY_UDF = "udf"; + public static final String KEY_COLUMN = "column"; + + public static final Set<String> KEYS_DATABASE = Sets.newHashSet(KEY_DATABASE); + public static final Set<String> KEYS_TABLE = Sets.newHashSet(KEY_DATABASE, KEY_TABLE); + public static final Set<String> KEYS_UDF = Sets.newHashSet(KEY_DATABASE, KEY_UDF); + public static final Set<String> KEYS_COLUMN = Sets.newHashSet(KEY_DATABASE, KEY_TABLE, KEY_COLUMN); private HiveObjectType objectType = null; private String database = null;
