You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ga...@apache.org on 2016/04/21 08:20:18 UTC
[3/3] incubator-ranger git commit: RANGER-867 : Add Kerberos support
for ranger admin and clients
RANGER-867 : Add Kerberos support for ranger admin and clients
Signed-off-by: Gautam Borad <ga...@apache.org>
Project: http://git-wip-us.apache.org/repos/asf/incubator-ranger/repo
Commit: http://git-wip-us.apache.org/repos/asf/incubator-ranger/commit/8614032c
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/8614032c
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/8614032c
Branch: refs/heads/master
Commit: 8614032c909dd5599fedc35c8f4b80f71b3a950d
Parents: 981f01a
Author: Ankita Sinha <an...@freestoneinfotech.com>
Authored: Wed Apr 20 14:35:46 2016 +0530
Committer: Gautam Borad <ga...@apache.org>
Committed: Thu Apr 21 11:50:01 2016 +0530
----------------------------------------------------------------------
.../hadoop/security/SecureClientLogin.java | 71 ++-
.../admin/client/RangerAdminRESTClient.java | 121 +++-
.../hadoop/config/RangerConfiguration.java | 5 +
.../apache/ranger/plugin/client/BaseClient.java | 86 +--
.../plugin/client/HadoopConfigHolder.java | 31 +-
.../plugin/store/rest/ServiceRESTStore.java | 23 +-
.../ranger/plugin/util/RangerRESTUtils.java | 5 +
.../main/resources/resourcenamemap.properties | 2 +
embeddedwebserver/pom.xml | 15 +
.../scripts/ranger-admin-services.sh | 4 +-
.../ranger/server/tomcat/EmbeddedServer.java | 80 ++-
.../ranger/services/hdfs/client/HdfsClient.java | 32 +-
.../ranger/services/kms/client/KMSClient.java | 28 +-
.../services/kms/client/KMSConnectionMgr.java | 15 +-
.../services/kms/client/KMSResourceMgr.java | 9 +-
security-admin/scripts/install.properties | 11 +
security-admin/scripts/setup.sh | 93 +++
.../java/org/apache/ranger/biz/KmsKeyMgr.java | 7 +-
.../org/apache/ranger/biz/RangerBizUtil.java | 22 +
.../org/apache/ranger/biz/ServiceDBStore.java | 51 +-
.../java/org/apache/ranger/biz/ServiceMgr.java | 37 +-
.../java/org/apache/ranger/biz/SessionMgr.java | 19 +
.../java/org/apache/ranger/biz/XUserMgr.java | 2 +-
.../apache/ranger/common/UserSessionBase.java | 9 +
.../org/apache/ranger/rest/PublicAPIsv2.java | 5 +-
.../org/apache/ranger/rest/ServiceREST.java | 292 +++++++++-
.../java/org/apache/ranger/rest/TagREST.java | 80 +++
.../apache/ranger/rest/TagRESTConstants.java | 1 +
.../context/RangerPreAuthSecurityHandler.java | 9 +
.../filter/RangerKRBAuthenticationFilter.java | 569 ++++++++++++++++++
.../security/web/filter/RangerKrbFilter.java | 576 +++++++++++++++++++
.../resources/conf.dist/ranger-admin-site.xml | 38 ++
.../conf.dist/security-applicationContext.xml | 8 +-
.../main/resources/resourcenamemap.properties | 2 +
.../main/webapp/META-INF/applicationContext.xml | 3 +-
.../org/apache/ranger/rest/TestServiceREST.java | 1 -
src/main/assembly/admin-web.xml | 6 +
src/main/assembly/usersync.xml | 1 +
.../services/storm/client/StormClient.java | 55 +-
.../storm/client/StormConnectionMgr.java | 17 +-
.../services/storm/client/StormResourceMgr.java | 9 +-
.../conf/templates/installprop2xml.properties | 5 +-
.../conf/templates/ranger-tagsync-template.xml | 11 +-
tagsync/scripts/install.properties | 7 +-
tagsync/scripts/ranger-tagsync-services.sh | 2 +-
tagsync/scripts/setup.py | 47 ++
.../ranger/tagsync/process/TagSyncConfig.java | 45 +-
.../tagsync/sink/tagadmin/TagAdminRESTSink.java | 50 +-
ugsync/pom.xml | 5 +
.../config/UserGroupSyncConfig.java | 5 +-
.../process/PolicyMgrUserGroupBuilder.java | 332 ++++++++---
unixauthservice/scripts/install.properties | 4 +
.../scripts/ranger-usersync-services.sh | 2 +-
unixauthservice/scripts/setup.py | 31 +-
.../templates/installprop2xml.properties | 2 +
.../templates/ranger-ugsync-template.xml | 8 +
56 files changed, 2758 insertions(+), 248 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/agents-common/src/main/java/org/apache/hadoop/security/SecureClientLogin.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/hadoop/security/SecureClientLogin.java b/agents-common/src/main/java/org/apache/hadoop/security/SecureClientLogin.java
index ba0c443..ce78cbe 100644
--- a/agents-common/src/main/java/org/apache/hadoop/security/SecureClientLogin.java
+++ b/agents-common/src/main/java/org/apache/hadoop/security/SecureClientLogin.java
@@ -18,6 +18,7 @@
*/
package org.apache.hadoop.security;
+import java.io.File;
import java.io.IOException;
import java.security.Principal;
import java.util.HashMap;
@@ -31,11 +32,16 @@ import javax.security.auth.login.AppConfigurationEntry.LoginModuleControlFlag;
import javax.security.auth.login.LoginContext;
import javax.security.auth.login.LoginException;
+import org.apache.commons.logging.Log;
+import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.security.UserGroupInformation.AuthenticationMethod;
import org.apache.hadoop.security.authentication.util.KerberosUtil;
-
+import org.apache.hadoop.security.authentication.util.KerberosName;
+import org.apache.hadoop.util.StringUtils;
public class SecureClientLogin {
+ private static final Log LOG = LogFactory.getLog(SecureClientLogin.class);
+ public static final String HOSTNAME_PATTERN = "_HOST";
public synchronized static Subject loginUserFromKeytab(String user, String path) throws IOException {
try {
@@ -49,6 +55,20 @@ public class SecureClientLogin {
throw new IOException("Login failure for " + user + " from keytab " + path, le);
}
}
+
+ public synchronized static Subject loginUserFromKeytab(String user, String path, String nameRules) throws IOException {
+ try {
+ Subject subject = new Subject();
+ SecureClientLoginConfiguration loginConf = new SecureClientLoginConfiguration(true, user, path);
+ LoginContext login = new LoginContext("hadoop-keytab-kerberos", subject, null, loginConf);
+ KerberosName.setRules(nameRules);
+ subject.getPrincipals().add(new User(user, AuthenticationMethod.KERBEROS, login));
+ login.login();
+ return login.getSubject();
+ } catch (LoginException le) {
+ throw new IOException("Login failure for " + user + " from keytab " + path, le);
+ }
+ }
public synchronized static Subject loginUserWithPassword(String user, String password) throws IOException {
String tmpPass = password;
@@ -90,7 +110,54 @@ public class SecureClientLogin {
public static Principal createUserPrincipal(String aLoginName) {
return new User(aLoginName) ;
}
-
+
+ public static boolean isKerberosCredentialExists(String principal, String keytabPath){
+ boolean isValid = false;
+ if (keytabPath != null && !keytabPath.isEmpty()) {
+ File keytabFile = new File(keytabPath);
+ if (!keytabFile.exists()) {
+ LOG.warn(keytabPath + " doesn't exist.");
+ } else if (!keytabFile.canRead()) {
+ LOG.warn("Unable to read " + keytabPath + " Please check the file access permissions for user");
+ }else{
+ isValid = true;
+ }
+ } else {
+ LOG.warn("Can't find keyTab Path : "+keytabPath);
+ }
+ if (!(principal != null && !principal.isEmpty() && isValid)) {
+ isValid = false;
+ LOG.warn("Can't find principal : "+principal);
+ }
+ return isValid;
+ }
+
+ public static String getPrincipal(String principalConfig, String hostName) throws IOException {
+ String[] components = getComponents(principalConfig);
+ if (components == null || components.length != 3 || !components[1].equals(HOSTNAME_PATTERN)) {
+ return principalConfig;
+ } else {
+ if (hostName == null) {
+ throw new IOException("Can't replace " + HOSTNAME_PATTERN + " pattern since client ranger.service.host is null");
+ }
+ return replacePattern(components, hostName);
+ }
+ }
+
+ private static String[] getComponents(String principalConfig) {
+ if (principalConfig == null)
+ return null;
+ return principalConfig.split("[/@]");
+ }
+
+ private static String replacePattern(String[] components, String hostname)
+ throws IOException {
+ String fqdn = hostname;
+ if (fqdn == null || fqdn.isEmpty() || fqdn.equals("0.0.0.0")) {
+ fqdn = java.net.InetAddress.getLocalHost().getCanonicalHostName();
+ }
+ return components[0] + "/" + StringUtils.toLowerCase(fqdn) + "@" + components[2];
+ }
}
class SecureClientLoginConfiguration extends javax.security.auth.login.Configuration {
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/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 bd2b749..afa347e 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
@@ -27,13 +27,15 @@ import com.sun.jersey.api.client.WebResource;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.security.AccessControlException;
+import org.apache.hadoop.security.UserGroupInformation;
import org.apache.ranger.admin.client.datatype.RESTResponse;
-
+import org.apache.ranger.audit.provider.MiscUtil;
import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
import org.apache.ranger.plugin.util.*;
import java.lang.reflect.ParameterizedType;
import java.lang.reflect.Type;
+import java.security.PrivilegedAction;
import java.util.List;
public class RangerAdminRESTClient implements RangerAdminClient {
@@ -44,7 +46,6 @@ public class RangerAdminRESTClient implements RangerAdminClient {
private RangerRESTClient restClient = null;
private RangerRESTUtils restUtils = new RangerRESTUtils();
-
public RangerAdminRESTClient() {
}
@@ -76,31 +77,44 @@ public class RangerAdminRESTClient implements RangerAdminClient {
String sslConfigFileName = RangerConfiguration.getInstance().get(propertyPrefix + ".policy.rest.ssl.config.file");
int restClientConnTimeOutMs = RangerConfiguration.getInstance().getInt(propertyPrefix + ".policy.rest.client.connection.timeoutMs", 120 * 1000);
int restClientReadTimeOutMs = RangerConfiguration.getInstance().getInt(propertyPrefix + ".policy.rest.client.read.timeoutMs", 30 * 1000);
-
+
init(url, sslConfigFileName, restClientConnTimeOutMs , restClientReadTimeOutMs);
}
@Override
- public ServicePolicies getServicePoliciesIfUpdated(long lastKnownVersion) throws Exception {
+ public ServicePolicies getServicePoliciesIfUpdated(final long lastKnownVersion) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerAdminRESTClient.getServicePoliciesIfUpdated(" + lastKnownVersion + ")");
}
ServicePolicies ret = null;
- WebResource webResource = createWebResource(RangerRESTUtils.REST_URL_POLICY_GET_FOR_SERVICE_IF_UPDATED + serviceName)
- .queryParam(RangerRESTUtils.REST_PARAM_LAST_KNOWN_POLICY_VERSION, Long.toString(lastKnownVersion))
- .queryParam(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
- ClientResponse response = webResource.accept(RangerRESTUtils.REST_MIME_TYPE_JSON).get(ClientResponse.class);
-
+ ClientResponse response = null;
+ if (MiscUtil.getUGILoginUser() != null && UserGroupInformation.isSecurityEnabled()) {
+ LOG.info("Checking Service policy if updated as user : " + MiscUtil.getUGILoginUser());
+ PrivilegedAction<ClientResponse> action = new PrivilegedAction<ClientResponse>() {
+ public ClientResponse run() {
+ WebResource secureWebResource = createWebResource(RangerRESTUtils.REST_URL_POLICY_GET_FOR_SECURE_SERVICE_IF_UPDATED + serviceName)
+ .queryParam(RangerRESTUtils.REST_PARAM_LAST_KNOWN_POLICY_VERSION, Long.toString(lastKnownVersion))
+ .queryParam(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
+ return secureWebResource.accept(RangerRESTUtils.REST_MIME_TYPE_JSON).get(ClientResponse.class);
+ };
+ };
+ response = MiscUtil.getUGILoginUser().doAs(action);
+ }else{
+ WebResource webResource = createWebResource(RangerRESTUtils.REST_URL_POLICY_GET_FOR_SERVICE_IF_UPDATED + serviceName)
+ .queryParam(RangerRESTUtils.REST_PARAM_LAST_KNOWN_POLICY_VERSION, Long.toString(lastKnownVersion))
+ .queryParam(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
+ response = webResource.accept(RangerRESTUtils.REST_MIME_TYPE_JSON).get(ClientResponse.class);
+ }
+
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);
- LOG.error("Error getting policies. request=" + webResource.toString()
- + ", response=" + resp.toString() + ", serviceName=" + serviceName);
+ LOG.error("Error getting policies. response=" + resp.toString() + ", serviceName=" + serviceName);
throw new Exception(resp.getMessage());
}
@@ -112,15 +126,27 @@ public class RangerAdminRESTClient implements RangerAdminClient {
}
@Override
- public void grantAccess(GrantRevokeRequest request) throws Exception {
+ public void grantAccess(final GrantRevokeRequest request) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerAdminRESTClient.grantAccess(" + request + ")");
}
- WebResource webResource = createWebResource(RangerRESTUtils.REST_URL_SERVICE_GRANT_ACCESS + serviceName)
- .queryParam(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
- ClientResponse response = webResource.accept(RangerRESTUtils.REST_EXPECTED_MIME_TYPE).type(RangerRESTUtils.REST_EXPECTED_MIME_TYPE).post(ClientResponse.class, restClient.toJson(request));
-
+ ClientResponse response = null;
+ if (MiscUtil.getUGILoginUser() != null && UserGroupInformation.isSecurityEnabled()) {
+ PrivilegedAction<ClientResponse> action = new PrivilegedAction<ClientResponse>() {
+ public ClientResponse run() {
+ WebResource secureWebResource = createWebResource(RangerRESTUtils.REST_URL_SECURE_SERVICE_GRANT_ACCESS + serviceName)
+ .queryParam(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
+ return secureWebResource.accept(RangerRESTUtils.REST_EXPECTED_MIME_TYPE).type(RangerRESTUtils.REST_EXPECTED_MIME_TYPE).post(ClientResponse.class, restClient.toJson(request));
+ };
+ };
+ LOG.info("grantAccess as user " + MiscUtil.getUGILoginUser());
+ response = MiscUtil.getUGILoginUser().doAs(action);
+ } else {
+ WebResource webResource = createWebResource(RangerRESTUtils.REST_URL_SERVICE_GRANT_ACCESS + serviceName)
+ .queryParam(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
+ response = webResource.accept(RangerRESTUtils.REST_EXPECTED_MIME_TYPE).type(RangerRESTUtils.REST_EXPECTED_MIME_TYPE).post(ClientResponse.class, restClient.toJson(request));
+ }
if(response != null && response.getStatus() != 200) {
LOG.error("grantAccess() failed: HTTP status=" + response.getStatus());
@@ -139,14 +165,27 @@ public class RangerAdminRESTClient implements RangerAdminClient {
}
@Override
- public void revokeAccess(GrantRevokeRequest request) throws Exception {
+ public void revokeAccess(final GrantRevokeRequest request) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerAdminRESTClient.revokeAccess(" + request + ")");
}
- WebResource webResource = createWebResource(RangerRESTUtils.REST_URL_SERVICE_REVOKE_ACCESS + serviceName)
- .queryParam(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
- ClientResponse response = webResource.accept(RangerRESTUtils.REST_EXPECTED_MIME_TYPE).type(RangerRESTUtils.REST_EXPECTED_MIME_TYPE).post(ClientResponse.class, restClient.toJson(request));
+ ClientResponse response = null;
+ if (MiscUtil.getUGILoginUser() != null && UserGroupInformation.isSecurityEnabled()) {
+ PrivilegedAction<ClientResponse> action = new PrivilegedAction<ClientResponse>() {
+ public ClientResponse run() {
+ WebResource secureWebResource = createWebResource(RangerRESTUtils.REST_URL_SECURE_SERVICE_REVOKE_ACCESS + serviceName)
+ .queryParam(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
+ return secureWebResource.accept(RangerRESTUtils.REST_EXPECTED_MIME_TYPE).type(RangerRESTUtils.REST_EXPECTED_MIME_TYPE).post(ClientResponse.class, restClient.toJson(request));
+ };
+ };
+ LOG.info("revokeAccess as user " + MiscUtil.getUGILoginUser());
+ response = MiscUtil.getUGILoginUser().doAs(action);
+ } else {
+ WebResource webResource = createWebResource(RangerRESTUtils.REST_URL_SERVICE_REVOKE_ACCESS + serviceName)
+ .queryParam(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
+ response = webResource.accept(RangerRESTUtils.REST_EXPECTED_MIME_TYPE).type(RangerRESTUtils.REST_EXPECTED_MIME_TYPE).post(ClientResponse.class, restClient.toJson(request));
+ }
if(response != null && response.getStatus() != 200) {
LOG.error("revokeAccess() failed: HTTP status=" + response.getStatus());
@@ -186,18 +225,31 @@ public class RangerAdminRESTClient implements RangerAdminClient {
}
@Override
- public ServiceTags getServiceTagsIfUpdated(long lastKnownVersion) throws Exception {
+ public ServiceTags getServiceTagsIfUpdated(final long lastKnownVersion) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> RangerAdminRESTClient.getServiceTagsIfUpdated(" + lastKnownVersion + "): ");
}
ServiceTags ret = null;
-
- WebResource webResource = createWebResource(RangerRESTUtils.REST_URL_GET_SERVICE_TAGS_IF_UPDATED + serviceName)
- .queryParam(RangerRESTUtils.LAST_KNOWN_TAG_VERSION_PARAM, Long.toString(lastKnownVersion))
- .queryParam(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
-
- ClientResponse response = webResource.accept(RangerRESTUtils.REST_MIME_TYPE_JSON).get(ClientResponse.class);
+ ClientResponse response = null;
+ WebResource webResource = null;
+ if (MiscUtil.getUGILoginUser() != null && UserGroupInformation.isSecurityEnabled()) {
+ PrivilegedAction<ClientResponse> action = new PrivilegedAction<ClientResponse>() {
+ public ClientResponse run() {
+ WebResource secureWebResource = createWebResource(RangerRESTUtils.REST_URL_GET_SECURE_SERVICE_TAGS_IF_UPDATED + serviceName)
+ .queryParam(RangerRESTUtils.LAST_KNOWN_TAG_VERSION_PARAM, Long.toString(lastKnownVersion))
+ .queryParam(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
+ return secureWebResource.accept(RangerRESTUtils.REST_MIME_TYPE_JSON).get(ClientResponse.class);
+ };
+ };
+ LOG.info("getServiceTagsIfUpdated as user " + MiscUtil.getUGILoginUser());
+ response = MiscUtil.getUGILoginUser().doAs(action);
+ } else {
+ webResource = createWebResource(RangerRESTUtils.REST_URL_GET_SERVICE_TAGS_IF_UPDATED + serviceName)
+ .queryParam(RangerRESTUtils.LAST_KNOWN_TAG_VERSION_PARAM, Long.toString(lastKnownVersion))
+ .queryParam(RangerRESTUtils.REST_PARAM_PLUGIN_ID, pluginId);
+ response = webResource.accept(RangerRESTUtils.REST_MIME_TYPE_JSON).get(ClientResponse.class);
+ }
if(response != null && response.getStatus() == 200) {
ret = response.getEntity(ServiceTags.class);
@@ -227,11 +279,22 @@ public class RangerAdminRESTClient implements RangerAdminClient {
List<String> ret = null;
String emptyString = "";
- WebResource webResource = createWebResource(RangerRESTUtils.REST_URL_LOOKUP_TAG_NAMES)
+ final WebResource webResource = createWebResource(RangerRESTUtils.REST_URL_LOOKUP_TAG_NAMES)
.queryParam(RangerRESTUtils.SERVICE_NAME_PARAM, serviceName)
.queryParam(RangerRESTUtils.PATTERN_PARAM, pattern);
- ClientResponse response = webResource.accept(RangerRESTUtils.REST_MIME_TYPE_JSON).get(ClientResponse.class);
+ ClientResponse response = null;
+ if (MiscUtil.getUGILoginUser() != null) {
+ PrivilegedAction<ClientResponse> action = new PrivilegedAction<ClientResponse>() {
+ public ClientResponse run() {
+ return webResource.accept(RangerRESTUtils.REST_MIME_TYPE_JSON).get(ClientResponse.class);
+ };
+ };
+ LOG.info("getTagTypes as user " + MiscUtil.getUGILoginUser());
+ response = MiscUtil.getUGILoginUser().doAs(action);
+ } else {
+ response = webResource.accept(RangerRESTUtils.REST_MIME_TYPE_JSON).get(ClientResponse.class);
+ }
if(response != null && response.getStatus() == 200) {
ret = response.getEntity(getGenericType(emptyString));
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/config/RangerConfiguration.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/config/RangerConfiguration.java b/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/config/RangerConfiguration.java
index 6cb289f..2a4241c 100644
--- a/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/config/RangerConfiguration.java
+++ b/agents-common/src/main/java/org/apache/ranger/authorization/hadoop/config/RangerConfiguration.java
@@ -55,6 +55,7 @@ public class RangerConfiguration extends Configuration {
public boolean addAdminResources() {
String defaultCfg = "ranger-admin-default-site.xml";
String addlCfg = "ranger-admin-site.xml";
+ String coreCfg = "core-site.xml";
if(LOG.isDebugEnabled()) {
LOG.debug("==> addAdminResources()");
@@ -68,6 +69,10 @@ public class RangerConfiguration extends Configuration {
if (! addResourceIfReadable(addlCfg)) {
ret = false;
}
+
+ if(! addResourceIfReadable(coreCfg)){
+ ret = false;
+ }
if(LOG.isDebugEnabled()) {
LOG.debug("<== addAdminResources(), result=" + ret);
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/agents-common/src/main/java/org/apache/ranger/plugin/client/BaseClient.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/client/BaseClient.java b/agents-common/src/main/java/org/apache/ranger/plugin/client/BaseClient.java
index df69e2a..86a91a4 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/client/BaseClient.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/client/BaseClient.java
@@ -36,8 +36,11 @@ public abstract class BaseClient {
private static final Log LOG = LogFactory.getLog(BaseClient.class) ;
- private String serviceName ;
- private String defaultConfigFile ;
+ private static final String DEFAULT_NAME_RULE = "DEFAULT";
+
+
+ private String serviceName ;
+ private String defaultConfigFile ;
private Subject loginSubject ;
private HadoopConfigHolder configHolder;
@@ -50,7 +53,7 @@ public abstract class BaseClient {
public BaseClient(String serivceName, Map<String,String> connectionProperties, String defaultConfigFile) {
this.serviceName = serivceName ;
this.connectionProperties = connectionProperties ;
- this.defaultConfigFile = defaultConfigFile ;
+ this.defaultConfigFile = defaultConfigFile ;
init() ;
login() ;
}
@@ -73,38 +76,57 @@ public abstract class BaseClient {
+ "resource names. Check xa_portal.log for more info.";
try {
//Thread.currentThread().setContextClassLoader(configHolder.getClassLoader());
- String userName = configHolder.getUserName() ;
- if (userName == null) {
- String msgDesc = "Unable to find login username for hadoop environment, ["
+ String lookupPrincipal = SecureClientLogin.getPrincipal(configHolder.getLookupPrincipal(), java.net.InetAddress.getLocalHost().getCanonicalHostName());
+ String lookupKeytab = configHolder.getLookupKeytab();
+ String nameRules = configHolder.getNameRules();
+ if(StringUtils.isEmpty(nameRules)){
+ if(LOG.isDebugEnabled()){
+ LOG.debug("Name is empty. Setting Name Rule as 'DEFAULT'");
+ }
+ nameRules = DEFAULT_NAME_RULE;
+ }
+ String userName = configHolder.getUserName() ;
+ if(StringUtils.isEmpty(lookupPrincipal) || StringUtils.isEmpty(lookupKeytab)){
+ if (userName == null) {
+ String msgDesc = "Unable to find login username for hadoop environment, ["
+ serviceName + "]";
- HadoopException hdpException = new HadoopException(msgDesc);
- hdpException.generateResponseDataMap(false, msgDesc + errMsg, msgDesc + errMsg,
+ HadoopException hdpException = new HadoopException(msgDesc);
+ hdpException.generateResponseDataMap(false, msgDesc + errMsg, msgDesc + errMsg,
null, null);
- throw hdpException;
- }
- String keyTabFile = configHolder.getKeyTabFile() ;
- if (keyTabFile != null) {
- if ( configHolder.isKerberosAuthentication() ) {
- LOG.info("Init Login: security enabled, using username/keytab");
- loginSubject = SecureClientLogin.loginUserFromKeytab(userName, keyTabFile) ;
- }
- else {
- LOG.info("Init Login: using username");
- loginSubject = SecureClientLogin.login(userName) ;
- }
- }
- else {
- String password = configHolder.getPassword() ;
- if ( configHolder.isKerberosAuthentication() ) {
- LOG.info("Init Login: using username/password");
- loginSubject = SecureClientLogin.loginUserWithPassword(userName, password) ;
- }
- else {
- LOG.info("Init Login: security not enabled, using username");
- loginSubject = SecureClientLogin.login(userName) ;
- }
- }
+ throw hdpException;
+ }
+ String keyTabFile = configHolder.getKeyTabFile() ;
+ if (keyTabFile != null) {
+ if ( configHolder.isKerberosAuthentication() ) {
+ LOG.info("Init Login: security enabled, using username/keytab");
+ loginSubject = SecureClientLogin.loginUserFromKeytab(userName, keyTabFile, nameRules) ;
+ }
+ else {
+ LOG.info("Init Login: using username");
+ loginSubject = SecureClientLogin.login(userName) ;
+ }
+ }
+ else {
+ String password = configHolder.getPassword() ;
+ if ( configHolder.isKerberosAuthentication() ) {
+ LOG.info("Init Login: using username/password");
+ loginSubject = SecureClientLogin.loginUserWithPassword(userName, password) ;
+ }
+ else {
+ LOG.info("Init Login: security not enabled, using username");
+ loginSubject = SecureClientLogin.login(userName) ;
+ }
+ }
+ }else{
+ if ( configHolder.isKerberosAuthentication() ) {
+ LOG.info("Init Lookup Login: security enabled, using lookupPrincipal/lookupKeytab");
+ loginSubject = SecureClientLogin.loginUserFromKeytab(lookupPrincipal, lookupKeytab, nameRules) ;
+ }else{
+ LOG.info("Init Login: security not enabled, using username");
+ loginSubject = SecureClientLogin.login(userName);
+ }
+ }
} catch (IOException ioe) {
String msgDesc = "Unable to login to Hadoop environment ["
+ serviceName + "]";
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/agents-common/src/main/java/org/apache/ranger/plugin/client/HadoopConfigHolder.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/client/HadoopConfigHolder.java b/agents-common/src/main/java/org/apache/ranger/plugin/client/HadoopConfigHolder.java
index b7416b4..1f3987f 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/client/HadoopConfigHolder.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/client/HadoopConfigHolder.java
@@ -29,6 +29,7 @@ import java.util.Set;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.security.SecureClientLogin;
public class HadoopConfigHolder {
private static final Log LOG = LogFactory.getLog(HadoopConfigHolder.class) ;
@@ -40,7 +41,11 @@ public class HadoopConfigHolder {
public static final String RANGER_LOGIN_USER_NAME_PROP = "username" ;
public static final String RANGER_LOGIN_KEYTAB_FILE_PROP = "keytabfile" ;
public static final String RANGER_LOGIN_PASSWORD = "password" ;
+ public static final String RANGER_LOOKUP_PRINCIPAL = "lookupprincipal";
+ public static final String RANGER_LOOKUP_KEYTAB = "lookupkeytab";
+ public static final String RANGER_NAME_RULES = "namerules";
public static final String HADOOP_SECURITY_AUTHENTICATION = "hadoop.security.authentication";
+ public static final String HADOOP_NAME_RULES = "hadoop.security.auth_to_local";
public static final String HADOOP_SECURITY_AUTHENTICATION_METHOD = "kerberos";
public static final String HADOOP_RPC_PROTECTION = "hadoop.rpc.protection";
@@ -53,11 +58,14 @@ public class HadoopConfigHolder {
private String datasourceName ;
- private String defaultConfigFile ;
+ private String defaultConfigFile ;
private String userName ;
private String keyTabFile ;
private String password ;
private boolean isKerberosAuth ;
+ private String lookupPrincipal;
+ private String lookupKeytab;
+ private String nameRules;
private Map<String,String> connectionProperties;
@@ -270,14 +278,17 @@ public class HadoopConfigHolder {
userName = prop.getProperty(RANGER_LOGIN_USER_NAME_PROP) ;
keyTabFile = prop.getProperty(RANGER_LOGIN_KEYTAB_FILE_PROP) ;
password = prop.getProperty(RANGER_LOGIN_PASSWORD) ;
-
+ lookupPrincipal = prop.getProperty(RANGER_LOOKUP_PRINCIPAL);
+ lookupKeytab = prop.getProperty(RANGER_LOOKUP_KEYTAB);
+ nameRules = prop.getProperty(RANGER_NAME_RULES);
+
String hadoopSecurityAuthenticationn = getHadoopSecurityAuthentication();
if ( hadoopSecurityAuthenticationn != null) {
isKerberosAuth = ( hadoopSecurityAuthenticationn.equalsIgnoreCase(HADOOP_SECURITY_AUTHENTICATION_METHOD));
}
else {
- isKerberosAuth = (userName != null) && (userName.indexOf("@") > -1) ;
+ isKerberosAuth = (((userName != null) && (userName.indexOf("@") > -1)) || (SecureClientLogin.isKerberosCredentialExists(lookupPrincipal, lookupKeytab)));
}
}
}
@@ -367,7 +378,7 @@ public class HadoopConfigHolder {
return ret;
}
-
+
public String getUserName() {
return userName;
}
@@ -383,6 +394,18 @@ public class HadoopConfigHolder {
public boolean isKerberosAuthentication() {
return isKerberosAuth;
}
+
+ public String getLookupPrincipal(){
+ return lookupPrincipal;
+ }
+
+ public String getLookupKeytab(){
+ return lookupKeytab;
+ }
+
+ public String getNameRules(){
+ return nameRules;
+ }
public Set<String> getRangerInternalPropertyKeys() {
return rangerInternalPropertyKeys;
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/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 cf81d1f..1cb2175 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
@@ -19,13 +19,16 @@
package org.apache.ranger.plugin.store.rest;
+import java.security.PrivilegedAction;
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.hadoop.security.UserGroupInformation;
import org.apache.ranger.admin.client.datatype.RESTResponse;
+import org.apache.ranger.audit.provider.MiscUtil;
import org.apache.ranger.authorization.hadoop.config.RangerConfiguration;
import org.apache.ranger.plugin.model.RangerPolicy;
import org.apache.ranger.plugin.model.RangerService;
@@ -67,6 +70,7 @@ public class ServiceRESTStore extends AbstractServiceStore {
public final String REST_URL_POLICY_GET_FOR_SERVICE = "/service/plugins/policies/service/";
public final String REST_URL_POLICY_GET_FOR_SERVICE_BY_NAME = "/service/plugins/policies/service/name/";
public final String REST_URL_POLICY_GET_FOR_SERVICE_IF_UPDATED = "/service/plugins/policies/download/";
+ public final String REST_URL_POLICY_GET_FOR_SECURE_SERVICE_IF_UPDATED = "/service/plugins/secure/policies/download/";
public static final String REST_MIME_TYPE_JSON = "application/json" ;
@@ -572,15 +576,26 @@ public class ServiceRESTStore extends AbstractServiceStore {
}
@Override
- public ServicePolicies getServicePoliciesIfUpdated(String serviceName, Long lastKnownVersion) throws Exception {
+ public ServicePolicies getServicePoliciesIfUpdated(final String serviceName, final Long lastKnownVersion) throws Exception {
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceRESTStore.getServicePoliciesIfUpdated(" + serviceName + ", " + lastKnownVersion + ")");
}
ServicePolicies ret = null;
-
- WebResource webResource = createWebResource(REST_URL_POLICY_GET_FOR_SERVICE_IF_UPDATED + serviceName + "/" + lastKnownVersion);
- ClientResponse response = webResource.accept(REST_MIME_TYPE_JSON).get(ClientResponse.class);
+ ClientResponse response = null;
+ if (MiscUtil.getUGILoginUser() != null && UserGroupInformation.isSecurityEnabled()) {
+ LOG.info("Checking Service policy if updated as user : "+ MiscUtil.getUGILoginUser());
+ PrivilegedAction<ClientResponse> action = new PrivilegedAction<ClientResponse>() {
+ public ClientResponse run() {
+ WebResource secureWebResource = createWebResource(REST_URL_POLICY_GET_FOR_SECURE_SERVICE_IF_UPDATED + serviceName + "/" + lastKnownVersion);
+ return secureWebResource.accept(REST_MIME_TYPE_JSON).get(ClientResponse.class);
+ };
+ };
+ response = MiscUtil.getUGILoginUser().doAs(action);
+ } else {
+ WebResource webResource = createWebResource(REST_URL_POLICY_GET_FOR_SERVICE_IF_UPDATED + serviceName + "/" + lastKnownVersion);
+ response = webResource.accept(REST_MIME_TYPE_JSON).get(ClientResponse.class);
+ }
if(response != null && response.getStatus() == 200) {
ret = response.getEntity(ServicePolicies.class);
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTUtils.java
----------------------------------------------------------------------
diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTUtils.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTUtils.java
index ad113fe..9a47280 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTUtils.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/RangerRESTUtils.java
@@ -39,8 +39,13 @@ public class RangerRESTUtils {
public static final String REST_URL_POLICY_GET_FOR_SERVICE_IF_UPDATED = "/service/plugins/policies/download/";
public static final String REST_URL_SERVICE_GRANT_ACCESS = "/service/plugins/services/grant/";
public static final String REST_URL_SERVICE_REVOKE_ACCESS = "/service/plugins/services/revoke/";
+
+ public static final String REST_URL_POLICY_GET_FOR_SECURE_SERVICE_IF_UPDATED = "/service/plugins/secure/policies/download/";
+ public static final String REST_URL_SECURE_SERVICE_GRANT_ACCESS = "/service/plugins/secure/services/grant/";
+ public static final String REST_URL_SECURE_SERVICE_REVOKE_ACCESS = "/service/plugins/secure/services/revoke/";
public static final String REST_URL_GET_SERVICE_TAGS_IF_UPDATED = "/service/tags/download/";
+ public static final String REST_URL_GET_SECURE_SERVICE_TAGS_IF_UPDATED = "/service/tags/secure/download/";
public static final String SERVICE_NAME_PARAM = "serviceName";
public static final String LAST_KNOWN_TAG_VERSION_PARAM = "lastKnownVersion";
public static final String PATTERN_PARAM = "pattern";
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/agents-common/src/main/resources/resourcenamemap.properties
----------------------------------------------------------------------
diff --git a/agents-common/src/main/resources/resourcenamemap.properties b/agents-common/src/main/resources/resourcenamemap.properties
index d9b4d71..9bfaf61 100644
--- a/agents-common/src/main/resources/resourcenamemap.properties
+++ b/agents-common/src/main/resources/resourcenamemap.properties
@@ -24,6 +24,8 @@ dfs.secondary.namenode.kerberos.principal=hdfs-site.xml
username=xalogin.xml
keytabfile=xalogin.xml
password=xalogin.xml
+lookupprincipal=xalogin.xml
+lookupkeytab=xalogin.xml
hbase.master.kerberos.principal=hbase-site.xml
hbase.rpc.engine=hbase-site.xml
hbase.rpc.protection=hbase-site.xml
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/embeddedwebserver/pom.xml
----------------------------------------------------------------------
diff --git a/embeddedwebserver/pom.xml b/embeddedwebserver/pom.xml
index 9772075..6fde208 100644
--- a/embeddedwebserver/pom.xml
+++ b/embeddedwebserver/pom.xml
@@ -63,5 +63,20 @@
<artifactId>ecj</artifactId>
<version>P20140317-1600</version>
</dependency>
+ <dependency>
+ <groupId>log4j</groupId>
+ <artifactId>log4j</artifactId>
+ <version>${log4j.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ranger</groupId>
+ <artifactId>ranger-plugins-audit</artifactId>
+ <version>${project.version}</version>
+ </dependency>
+ <dependency>
+ <groupId>org.apache.ranger</groupId>
+ <artifactId>ranger-plugins-common</artifactId>
+ <version>${project.version}</version>
+ </dependency>
</dependencies>
</project>
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/embeddedwebserver/scripts/ranger-admin-services.sh
----------------------------------------------------------------------
diff --git a/embeddedwebserver/scripts/ranger-admin-services.sh b/embeddedwebserver/scripts/ranger-admin-services.sh
index 92016b6..bd913af 100755
--- a/embeddedwebserver/scripts/ranger-admin-services.sh
+++ b/embeddedwebserver/scripts/ranger-admin-services.sh
@@ -53,12 +53,12 @@ then
fi
start() {
- java -Dproc_rangeradmin ${JAVA_OPTS} -Dlogdir=${RANGER_ADMIN_LOG_DIR} -Dcatalina.base=${XAPOLICYMGR_EWS_DIR} -cp "${XAPOLICYMGR_EWS_DIR}/webapp/WEB-INF/classes/conf:${XAPOLICYMGR_EWS_DIR}/lib/*:${RANGER_JAAS_LIB_DIR}/*:${RANGER_JAAS_CONF_DIR}:${JAVA_HOME}/lib/*:$CLASSPATH" org.apache.ranger.server.tomcat.EmbeddedServer > ${RANGER_ADMIN_LOG_DIR}/catalina.out 2>&1 &
+ java -Dproc_rangeradmin ${JAVA_OPTS} -Dlogdir=${RANGER_ADMIN_LOG_DIR} -Dcatalina.base=${XAPOLICYMGR_EWS_DIR} -cp "${XAPOLICYMGR_EWS_DIR}/webapp/WEB-INF/classes/conf:${XAPOLICYMGR_EWS_DIR}/lib/*:${RANGER_JAAS_LIB_DIR}/*:${RANGER_JAAS_CONF_DIR}:${JAVA_HOME}/lib/*:${RANGER_HADOOP_CONF_DIR}/*:$CLASSPATH" org.apache.ranger.server.tomcat.EmbeddedServer > ${RANGER_ADMIN_LOG_DIR}/catalina.out 2>&1 &
echo "Apache Ranger Admin has started."
}
stop(){
- java ${JAVA_OPTS} -Dlogdir=${RANGER_ADMIN_LOG_DIR} -Dcatalina.base=${XAPOLICYMGR_EWS_DIR} -cp "${XAPOLICYMGR_EWS_DIR}/webapp/WEB-INF/classes/conf:${XAPOLICYMGR_EWS_DIR}/lib/*:${RANGER_JAAS_LIB_DIR}/*:${RANGER_JAAS_CONF_DIR}:$CLASSPATH" org.apache.ranger.server.tomcat.StopEmbeddedServer > ${RANGER_ADMIN_LOG_DIR}/catalina.out 2>&1
+ java ${JAVA_OPTS} -Dlogdir=${RANGER_ADMIN_LOG_DIR} -Dcatalina.base=${XAPOLICYMGR_EWS_DIR} -cp "${XAPOLICYMGR_EWS_DIR}/webapp/WEB-INF/classes/conf:${XAPOLICYMGR_EWS_DIR}/lib/*:${RANGER_JAAS_LIB_DIR}/*:${RANGER_JAAS_CONF_DIR}:${RANGER_HADOOP_CONF_DIR}/*:$CLASSPATH" org.apache.ranger.server.tomcat.StopEmbeddedServer > ${RANGER_ADMIN_LOG_DIR}/catalina.out 2>&1
echo "Apache Ranger Admin has been stopped."
}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServer.java
----------------------------------------------------------------------
diff --git a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServer.java b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServer.java
index d49ea61..19e944b 100644
--- a/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServer.java
+++ b/embeddedwebserver/src/main/java/org/apache/ranger/server/tomcat/EmbeddedServer.java
@@ -20,7 +20,9 @@
package org.apache.ranger.server.tomcat;
import java.io.File;
+import java.io.IOException;
import java.net.URL;
+import java.security.PrivilegedAction;
import java.util.Date;
import java.util.Iterator;
import java.util.Properties;
@@ -35,6 +37,10 @@ import org.apache.catalina.LifecycleException;
import org.apache.catalina.connector.Connector;
import org.apache.catalina.startup.Tomcat;
import org.apache.catalina.valves.AccessLogValve;
+import org.apache.hadoop.security.SecureClientLogin;
+
+import javax.security.auth.Subject;
+
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
@@ -46,11 +52,19 @@ public class EmbeddedServer {
.getName());
private static final String DEFAULT_CONFIG_FILENAME = "ranger-admin-site.xml";
+ private static final String CORE_SITE_CONFIG_FILENAME = "core-site.xml";
private static final String DEFAULT_WEBAPPS_ROOT_FOLDER = "webapps";
private static String configFile = DEFAULT_CONFIG_FILENAME;
+ private static final String AUTH_TYPE_KERBEROS = "kerberos";
+ private static final String AUTHENTICATION_TYPE = "hadoop.security.authentication";
+ private static final String ADMIN_USER_PRINCIPAL = "ranger.admin.kerberos.principal";
+ private static final String ADMIN_USER_KEYTAB = "ranger.admin.kerberos.keytab";
+
+ private static final String ADMIN_NAME_RULES = "hadoop.security.auth_to_local";
+
private Properties serverConfigProperties = new Properties();
public static void main(String[] args) {
@@ -61,14 +75,15 @@ public class EmbeddedServer {
if (args.length > 0) {
configFile = args[0];
}
- loadRangerSiteConfig();
+ loadConfig(CORE_SITE_CONFIG_FILENAME);
+ loadConfig(configFile);
}
public static int DEFAULT_SHUTDOWN_PORT = 6185;
public static String DEFAULT_SHUTDOWN_COMMAND = "SHUTDOWN";
public void start() {
- Tomcat server = new Tomcat();
+ final Tomcat server = new Tomcat();
String logDir = null;
logDir = getConfig("logdir");
@@ -198,16 +213,55 @@ public class EmbeddedServer {
LOG.severe("Tomcat Server failed to start webapp:" + lce.toString());
lce.printStackTrace();
}
-
+
+ String keytab = getConfig(ADMIN_USER_KEYTAB);
+// String principal = getConfig(ADMIN_USER_PRINCIPAL);
+ String principal = null;
try {
- server.start();
- server.getServer().await();
- shutdownServer();
-
- } catch (LifecycleException e) {
- LOG.severe("Tomcat Server failed to start:" + e.toString());
- e.printStackTrace();
- }
+ principal = SecureClientLogin.getPrincipal(getConfig(ADMIN_USER_PRINCIPAL), hostName);
+ } catch (IOException ignored) {
+ // do nothing
+ }
+ String nameRules = getConfig(ADMIN_NAME_RULES);
+ if(getConfig(AUTHENTICATION_TYPE) != null && getConfig(AUTHENTICATION_TYPE).trim().equalsIgnoreCase(AUTH_TYPE_KERBEROS) && SecureClientLogin.isKerberosCredentialExists(principal, keytab)){
+ try{
+ LOG.info("Provided Kerberos Credential : Principal = "+principal+" and Keytab = "+keytab);
+ Subject sub = SecureClientLogin.loginUserFromKeytab(principal, keytab, nameRules) ;
+ Subject.doAs(sub, new PrivilegedAction<Void>() {
+ @Override
+ public Void run() {
+ try{
+ LOG.info("Starting Server using kerberos crendential");
+ server.start();
+ server.getServer().await();
+ shutdownServer();
+ }catch (LifecycleException e) {
+ LOG.severe("Tomcat Server failed to start:" + e.toString());
+ e.printStackTrace();
+ }catch (Exception e) {
+ LOG.severe("Tomcat Server failed to start:" + e.toString());
+ e.printStackTrace();
+ }
+ return null;
+ }
+ });
+ }catch(Exception e){
+ LOG.severe("Tomcat Server failed to start:" + e.toString());
+ e.printStackTrace();
+ }
+ }else{
+ try{
+ server.start();
+ server.getServer().await();
+ shutdownServer();
+ } catch (LifecycleException e) {
+ LOG.severe("Tomcat Server failed to start:" + e.toString());
+ e.printStackTrace();
+ } catch (Exception e) {
+ LOG.severe("Tomcat Server failed to start:" + e.toString());
+ e.printStackTrace();
+ }
+ }
}
private String getKeystoreFile() {
@@ -310,8 +364,8 @@ public class EmbeddedServer {
}
- public void loadRangerSiteConfig() {
- String path = getResourceFileName(configFile);
+ public void loadConfig(String configFileName) {
+ String path = getResourceFileName(configFileName);
try {
DocumentBuilderFactory xmlDocumentBuilderFactory = DocumentBuilderFactory
.newInstance();
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/hdfs-agent/src/main/java/org/apache/ranger/services/hdfs/client/HdfsClient.java
----------------------------------------------------------------------
diff --git a/hdfs-agent/src/main/java/org/apache/ranger/services/hdfs/client/HdfsClient.java b/hdfs-agent/src/main/java/org/apache/ranger/services/hdfs/client/HdfsClient.java
index bc4f05a..4d563a3 100644
--- a/hdfs-agent/src/main/java/org/apache/ranger/services/hdfs/client/HdfsClient.java
+++ b/hdfs-agent/src/main/java/org/apache/ranger/services/hdfs/client/HdfsClient.java
@@ -35,6 +35,8 @@ import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.FileStatus;
import org.apache.hadoop.fs.FileSystem;
import org.apache.hadoop.fs.Path;
+import org.apache.commons.lang.StringUtils;
+import org.apache.hadoop.security.SecureClientLogin;
import org.apache.hadoop.security.UserGroupInformation;
import org.apache.ranger.plugin.client.BaseClient;
import org.apache.ranger.plugin.client.HadoopException;
@@ -252,18 +254,26 @@ public class HdfsClient extends BaseClient {
public static void validateConnectionConfigs(Map<String, String> configs)
throws IllegalArgumentException {
+ String lookupPrincipal=null;
+ try{
+ lookupPrincipal = SecureClientLogin.getPrincipal(configs.get("lookupprincipal"), java.net.InetAddress.getLocalHost().getCanonicalHostName());
+ }catch(Exception e){
+ //do nothing
+ }
+ String lookupKeytab = configs.get("lookupkeytab");
+ if(StringUtils.isEmpty(lookupPrincipal) || StringUtils.isEmpty(lookupKeytab)){
+ // username
+ String username = configs.get("username") ;
+ if ((username == null || username.isEmpty())) {
+ throw new IllegalArgumentException("Value for username not specified");
+ }
- // username
- String username = configs.get("username") ;
- if ((username == null || username.isEmpty())) {
- throw new IllegalArgumentException("Value for username not specified");
- }
-
- // password
- String password = configs.get("password") ;
- if ((password == null || password.isEmpty())) {
- throw new IllegalArgumentException("Value for password not specified");
- }
+ // password
+ String password = configs.get("password") ;
+ if ((password == null || password.isEmpty())) {
+ throw new IllegalArgumentException("Value for password not specified");
+ }
+ }
// hadoop.security.authentication
String authentication = configs.get("hadoop.security.authentication") ;
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSClient.java
----------------------------------------------------------------------
diff --git a/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSClient.java b/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSClient.java
index 061f95c..6a79433 100755
--- a/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSClient.java
+++ b/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSClient.java
@@ -29,8 +29,10 @@ import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
+
import javax.security.auth.Subject;
+import org.apache.commons.lang.StringUtils;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.security.HadoopKerberosName;
import org.apache.hadoop.security.ProviderUtils;
@@ -64,11 +66,18 @@ public class KMSClient {
String provider;
String username;
String password;
+ String lookupPrincipal;
+ String lookupKeytab;
+ String nameRules;
- public KMSClient(String provider, String username, String password) {
+ public KMSClient(String provider, String username, String password, String lookupPrincipal, String lookupKeytab, String nameRules) {
this.provider = provider;
this.username = username;
this.password = password;
+ this.lookupPrincipal = lookupPrincipal;
+ this.lookupKeytab = lookupKeytab;
+ this.nameRules = nameRules;
+
if (LOG.isDebugEnabled()) {
LOG.debug("Kms Client is build with url [" + provider + "] user: ["
+ username + "]");
@@ -164,9 +173,18 @@ public class KMSClient {
String shortName = new HadoopKerberosName(username).getShortName();
uri = uri.concat("?doAs="+shortName);
Subject sub = new Subject();
- if (username.contains("@")) {
+ if(!StringUtils.isEmpty(lookupPrincipal) && !StringUtils.isEmpty(lookupKeytab) && lookupPrincipal.contains("@")){
+ if(StringUtils.isEmpty(nameRules)){
+ nameRules = "DEFAULT";
+ }
+ LOG.info("Init Lookup Login: security enabled, using lookupPrincipal/lookupKeytab");
+ sub = SecureClientLogin.loginUserFromKeytab(lookupPrincipal, lookupKeytab, nameRules);
+ }
+ else if (username.contains("@")) {
+ LOG.info("Init Login: using username/password");
sub = SecureClientLogin.loginUserWithPassword(username, password);
} else {
+ LOG.info("Init Login: security not enabled, using username");
sub = SecureClientLogin.login(username);
}
final WebResource webResource = client.resource(uri);
@@ -324,7 +342,11 @@ public class KMSClient {
String kmsUrl = configs.get("provider");
String kmsUserName = configs.get("username");
String kmsPassWord = configs.get("password");
- kmsClient = new KMSClient(kmsUrl, kmsUserName, kmsPassWord);
+ String lookupPrincipal = configs.get("lookupprincipal");
+ String lookupKeytab = configs.get("lookupkeytab");
+ String nameRules = configs.get("namerules");
+
+ kmsClient = new KMSClient(kmsUrl, kmsUserName, kmsPassWord, lookupPrincipal, lookupKeytab, nameRules);
}
return kmsClient;
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSConnectionMgr.java
----------------------------------------------------------------------
diff --git a/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSConnectionMgr.java b/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSConnectionMgr.java
index 94eaba4..5e96a1c 100755
--- a/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSConnectionMgr.java
+++ b/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSConnectionMgr.java
@@ -19,6 +19,7 @@
package org.apache.ranger.services.kms.client;
+import org.apache.commons.lang.StringUtils;
import org.apache.log4j.Logger;
@@ -26,16 +27,18 @@ public class KMSConnectionMgr {
public static final Logger LOG = Logger.getLogger(KMSConnectionMgr.class);
- public static KMSClient getKMSClient(final String kmsURL, String userName, String password) {
+ public static KMSClient getKMSClient(final String kmsURL, String userName, String password, String lookupPrincipal, String lookupKeytab, String nameRules) {
KMSClient kmsClient = null;
if (kmsURL == null || kmsURL.isEmpty()) {
LOG.error("Can not create KMSClient: kmsURL is empty");
- } else if (userName == null || userName.isEmpty()) {
- LOG.error("Can not create KMSClient: kmsuserName is empty");
- } else if (password == null || password.isEmpty()) {
- LOG.error("Can not create KMSClient: kmsPassWord is empty");
+ } else if(StringUtils.isEmpty(lookupPrincipal)){
+ if(userName == null || userName.isEmpty()) {
+ LOG.error("Can not create KMSClient: kmsuserName is empty");
+ } else if (password == null || password.isEmpty()) {
+ LOG.error("Can not create KMSClient: kmsPassWord is empty");
+ }
} else {
- kmsClient = new KMSClient(kmsURL, userName, password);
+ kmsClient = new KMSClient(kmsURL, userName, password, lookupPrincipal, lookupKeytab, nameRules);
}
return kmsClient;
}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSResourceMgr.java
----------------------------------------------------------------------
diff --git a/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSResourceMgr.java b/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSResourceMgr.java
index 007b97b..6b96515 100755
--- a/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSResourceMgr.java
+++ b/plugin-kms/src/main/java/org/apache/ranger/services/kms/client/KMSResourceMgr.java
@@ -72,14 +72,17 @@ public class KMSResourceMgr {
String url = configs.get("provider");
String username = configs.get("username");
String password = configs.get("password");
- resultList = getKMSResource(url, username, password,kmsKeyName,kmsKeyList) ;
+ String lookupPrincipal = configs.get("lookupprincipal");
+ String lookupKeytab = configs.get("lookupkeytab");
+ String nameRules = configs.get("namerules");
+ resultList = getKMSResource(url, username, password, lookupPrincipal, lookupKeytab, nameRules, kmsKeyName,kmsKeyList) ;
}
return resultList ;
}
- public static List<String> getKMSResource(String url, String username, String password,String kmsKeyName, List<String> kmsKeyList) {
+ public static List<String> getKMSResource(String url, String username, String password, String lookupPrincipal, String lookupKeytab, String nameRules, String kmsKeyName, List<String> kmsKeyList) {
List<String> topologyList = null;
- final KMSClient KMSClient = KMSConnectionMgr.getKMSClient(url, username, password);
+ final KMSClient KMSClient = KMSConnectionMgr.getKMSClient(url, username, password, lookupPrincipal, lookupKeytab, nameRules);
synchronized(KMSClient){
topologyList = KMSClient.getKeyList(kmsKeyName, kmsKeyList);
}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/security-admin/scripts/install.properties
----------------------------------------------------------------------
diff --git a/security-admin/scripts/install.properties b/security-admin/scripts/install.properties
index 4070259..3913254 100644
--- a/security-admin/scripts/install.properties
+++ b/security-admin/scripts/install.properties
@@ -155,6 +155,17 @@ xa_ldap_ad_bind_password=
xa_ldap_ad_referral=
xa_ldap_ad_userSearchFilter=
+#------------ Kerberos Config -----------------
+spnego_principal=
+spnego_keytab=
+token_valid=30
+cookie_domain=
+cookie_path=/
+admin_principal=
+admin_keytab=
+lookup_principal=
+lookup_keytab=
+hadoop_conf=/etc/hadoop/conf
#
#-------- SSO CONFIG - Start ------------------
#
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/security-admin/scripts/setup.sh
----------------------------------------------------------------------
diff --git a/security-admin/scripts/setup.sh b/security-admin/scripts/setup.sh
index 832932c..51daf6d 100755
--- a/security-admin/scripts/setup.sh
+++ b/security-admin/scripts/setup.sh
@@ -117,6 +117,17 @@ sso_cookiename=$(get_prop 'sso_cookiename' $PROPFILE)
sso_query_param_originalurl=$(get_prop 'sso_query_param_originalurl' $PROPFILE)
RANGER_ADMIN_LOG_DIR=$(eval echo "$(get_prop 'RANGER_ADMIN_LOG_DIR' $PROPFILE)")
+spnego_principal=$(get_prop 'spnego_principal' $PROPFILE)
+spnego_keytab=$(get_prop 'spnego_keytab' $PROPFILE)
+token_valid=$(get_prop 'token_valid' $PROPFILE)
+cookie_domain=$(get_prop 'cookie_domain' $PROPFILE)
+cookie_path=$(get_prop 'cookie_path' $PROPFILE)
+admin_principal=$(get_prop 'admin_principal' $PROPFILE)
+admin_keytab=$(get_prop 'admin_keytab' $PROPFILE)
+lookup_principal=$(get_prop 'lookup_principal' $PROPFILE)
+lookup_keytab=$(get_prop 'lookup_keytab' $PROPFILE)
+hadoop_conf=$(get_prop 'hadoop_conf' $PROPFILE)
+
DB_HOST="${db_host}"
check_ret_status(){
@@ -356,6 +367,69 @@ update_properties() {
log "[E] $to_file_default does not exists" ; exit 1;
fi
+ if [ "${spnego_principal}" != "" ]
+ then
+ propertyName=ranger.spnego.kerberos.principal
+ newPropertyValue="${spnego_principal}"
+ updatePropertyToFilePy $propertyName $newPropertyValue $to_file_ranger
+ fi
+
+ if [ "${spnego_keytab}" != "" ]
+ then
+ propertyName=ranger.spnego.kerberos.keytab
+ newPropertyValue="${spnego_keytab}"
+ updatePropertyToFilePy $propertyName $newPropertyValue $to_file_ranger
+ fi
+
+ if [ "${token_valid}" != "" ]
+ then
+ propertyName=ranger.admin.kerberos.token.valid.seconds
+ newPropertyValue="${token_valid}"
+ updatePropertyToFilePy $propertyName $newPropertyValue $to_file_ranger
+ fi
+
+ if [ "${cookie_domain}" != "" ]
+ then
+ propertyName=ranger.admin.kerberos.cookie.domain
+ newPropertyValue="${cookie_domain}"
+ updatePropertyToFilePy $propertyName $newPropertyValue $to_file_ranger
+ fi
+
+ if [ "${cookie_path}" != "" ]
+ then
+ propertyName=ranger.admin.kerberos.cookie.path
+ newPropertyValue="${cookie_path}"
+ updatePropertyToFilePy $propertyName $newPropertyValue $to_file_ranger
+ fi
+
+ if [ "${admin_principal}" != "" ]
+ then
+ propertyName=ranger.admin.kerberos.principal
+ newPropertyValue="${admin_principal}"
+ updatePropertyToFilePy $propertyName $newPropertyValue $to_file_ranger
+ fi
+
+ if [ "${admin_keytab}" != "" ]
+ then
+ propertyName=ranger.admin.kerberos.keytab
+ newPropertyValue="${admin_keytab}"
+ updatePropertyToFilePy $propertyName $newPropertyValue $to_file_ranger
+ fi
+
+ if [ "${lookup_principal}" != "" ]
+ then
+ propertyName=ranger.lookup.kerberos.principal
+ newPropertyValue="${lookup_principal}"
+ updatePropertyToFilePy $propertyName $newPropertyValue $to_file_ranger
+ fi
+
+ if [ "${lookup_keytab}" != "" ]
+ then
+ propertyName=ranger.lookup.kerberos.keytab
+ newPropertyValue="${lookup_keytab}"
+ updatePropertyToFilePy $propertyName $newPropertyValue $to_file_ranger
+ fi
+
if [ "${DB_FLAVOR}" == "MYSQL" ]
then
propertyName=ranger.jpa.jdbc.url
@@ -965,8 +1039,27 @@ setup_install_files(){
mkdir -p ${WEBAPP_ROOT}/WEB-INF/classes/conf
cp ${WEBAPP_ROOT}/WEB-INF/classes/conf.dist/* ${WEBAPP_ROOT}/WEB-INF/classes/conf
fi
+
+ echo "export RANGER_HADOOP_CONF_DIR=${hadoop_conf}" > ${WEBAPP_ROOT}/WEB-INF/classes/conf/ranger-admin-env-hadoopconfdir.sh
+ chmod a+rx ${WEBAPP_ROOT}/WEB-INF/classes/conf/ranger-admin-env-hadoopconfdir.sh
+
+ hadoop_conf_file=${hadoop_conf}/core-site.xml
+ ranger_hadoop_conf_file=${WEBAPP_ROOT}/WEB-INF/classes/conf/core-site.xml
+
if [ -d ${WEBAPP_ROOT}/WEB-INF/classes/conf ]; then
chown -R ${unix_user} ${WEBAPP_ROOT}/WEB-INF/classes/conf
+ if [ "${hadoop_conf}" == "" ]
+ then
+ log "[WARN] Property hadoop_conf not found. Creating blank core-site.xml."
+ echo "<configuration></configuration>" > ${WEBAPP_ROOT}/WEB-INF/classes/conf/core-site.xml
+ else
+ if [ -f ${hadoop_conf_file} ]; then
+ ln -sf ${hadoop_conf_file} ${WEBAPP_ROOT}/WEB-INF/classes/conf/core-site.xml
+ else
+ log "[WARN] core-site.xml file not found in provided hadoop_conf path. Creating blank core-site.xml"
+ echo "<configuration></configuration>" > ${WEBAPP_ROOT}/WEB-INF/classes/conf/core-site.xml
+ fi
+ fi
fi
if [ ! -d ${WEBAPP_ROOT}/WEB-INF/classes/lib ]; then
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/security-admin/src/main/java/org/apache/ranger/biz/KmsKeyMgr.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/KmsKeyMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/KmsKeyMgr.java
index 3647bb1..82dc190 100755
--- a/security-admin/src/main/java/org/apache/ranger/biz/KmsKeyMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/KmsKeyMgr.java
@@ -49,6 +49,7 @@ import org.apache.log4j.Logger;
import org.apache.ranger.common.ContextUtil;
import org.apache.ranger.common.MessageEnums;
import org.apache.ranger.common.PasswordUtils;
+import org.apache.ranger.common.PropertiesUtil;
import org.apache.ranger.common.RESTErrorUtil;
import org.apache.ranger.common.RangerConfigUtil;
import org.apache.ranger.common.SortField;
@@ -87,6 +88,7 @@ public class KmsKeyMgr {
private static final String KMS_USERNAME = "username";
private static Map<String, String> providerList = new HashMap<String, String>();
private static int nextProvider = 0;
+ static final String NAME_RULES = "hadoop.security.auth_to_local";
@Autowired
ServiceDBStore svcStore;
@@ -526,8 +528,11 @@ public class KmsKeyMgr {
private Subject getSubjectForKerberos(String provider) throws Exception{
String userName = getKMSUserName(provider);
String password = getKMSPassword(provider);
- if (KerberosName.getRules() == null) {
+ String nameRules = PropertiesUtil.getProperty(NAME_RULES);
+ if (StringUtils.isEmpty(nameRules)) {
KerberosName.setRules("DEFAULT") ;
+ }else{
+ KerberosName.setRules(nameRules);
}
Subject sub = new Subject();
if (userName.contains("@")) {
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/security-admin/src/main/java/org/apache/ranger/biz/RangerBizUtil.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/RangerBizUtil.java b/security-admin/src/main/java/org/apache/ranger/biz/RangerBizUtil.java
index 2980e51..63c630e 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/RangerBizUtil.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/RangerBizUtil.java
@@ -56,6 +56,7 @@ import org.apache.ranger.entity.XXServiceDef;
import org.apache.ranger.entity.XXTrxLog;
import org.apache.ranger.entity.XXUser;
import org.apache.ranger.plugin.model.RangerBaseModelObject;
+import org.apache.ranger.plugin.model.RangerService;
import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
import org.apache.ranger.service.AbstractBaseResourceService;
import org.apache.ranger.view.VXDataObject;
@@ -1538,5 +1539,26 @@ public class RangerBizUtil {
MessageEnums.OPER_NOT_ALLOWED_FOR_STATE);
}
}
+
+ public boolean isUserAllowed(RangerService rangerService, String cfgNameAllowedUsers) {
+ Map<String, String> map = rangerService.getConfigs();
+ String user = null;
+ UserSessionBase userSession = ContextUtil.getCurrentUserSession();
+ if(userSession != null){
+ user = userSession.getLoginId();
+ }
+ if (map != null && map.containsKey(cfgNameAllowedUsers)) {
+ String userNames = map.get(cfgNameAllowedUsers);
+ String[] userList = userNames.split(",");
+ if(userList != null){
+ for (String u : userList) {
+ if (u.equals("*") || (user != null && u.equalsIgnoreCase(user))) {
+ return true;
+ }
+ }
+ }
+ }
+ return false;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
index 21ed686..7ef950a 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceDBStore.java
@@ -28,10 +28,13 @@ import java.text.SimpleDateFormat;
import javax.annotation.PostConstruct;
import javax.servlet.http.HttpServletResponse;
+
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.common.*;
import org.apache.ranger.db.*;
@@ -96,6 +99,11 @@ import org.apache.poi.ss.usermodel.Workbook;
public class ServiceDBStore extends AbstractServiceStore {
private static final Log LOG = LogFactory.getLog(ServiceDBStore.class);
public static final String RANGER_TAG_EXPIRY_CONDITION_NAME = "accessed-after-expiry";
+ private static final String LOOKUP_PRINCIPAL = "ranger.lookup.kerberos.principal";
+ private static final String LOOKUP_KEYTAB = "ranger.lookup.kerberos.keytab";
+ static final String RANGER_AUTH_TYPE = "hadoop.security.authentication";
+
+ private static final String KERBEROS_TYPE = "kerberos";
@Autowired
RangerServiceDefService serviceDefService;
@@ -1267,7 +1275,7 @@ public class ServiceDBStore extends AbstractServiceStore {
vXUser = xUserService.populateViewBean(xxUser);
} else {
UserSessionBase usb = ContextUtil.getCurrentUserSession();
- if (usb != null && !usb.isUserAdmin()) {
+ if (usb != null && !usb.isUserAdmin() && !usb.isSpnegoEnabled()) {
throw restErrorUtil.createRESTException("User does not exist with given username: ["
+ userName + "] please use existing user", MessageEnums.OPER_NO_PERMISSION);
}
@@ -2273,6 +2281,14 @@ public class ServiceDBStore extends AbstractServiceStore {
List<String> users = new ArrayList<String>();
users.add(vXUser.getName());
+ VXUser vXLookupUser = getLookupUser();
+ if(vXLookupUser != null){
+ users.add(vXLookupUser.getName());
+ }
+ UserSessionBase usb = ContextUtil.getCurrentUserSession();
+ if (usb != null && usb.isSpnegoEnabled()) {
+ users.add(usb.getLoginId());
+ }
policyItem.setUsers(users);
List<XXAccessTypeDef> accessTypeDefs = daoMgr.getXXAccessTypeDef().findByServiceDefId(createdService.getType());
@@ -2291,6 +2307,39 @@ public class ServiceDBStore extends AbstractServiceStore {
}
policy = createPolicy(policy);
}
+
+ private VXUser getLookupUser() {
+ VXUser vXUser = null;
+ String authType = PropertiesUtil.getProperty(RANGER_AUTH_TYPE);
+ String lookupPrincipal = PropertiesUtil.getProperty(LOOKUP_PRINCIPAL);
+ String lookupKeytab = PropertiesUtil.getProperty(LOOKUP_KEYTAB);
+ if(!StringUtils.isEmpty(authType) && authType.equalsIgnoreCase(KERBEROS_TYPE)){
+ if(SecureClientLogin.isKerberosCredentialExists(lookupPrincipal, lookupKeytab)){
+ KerberosName krbName = new KerberosName(lookupPrincipal);
+ String lookupUser=null;
+ try {
+ lookupUser = krbName.getShortName();
+ } catch (IOException e) {
+ throw restErrorUtil.createRESTException("Please provide proper value of lookup user principal : "+ lookupPrincipal, MessageEnums.INVALID_INPUT_DATA);
+ }
+
+ if(LOG.isDebugEnabled()){
+ LOG.debug("Checking for Lookup User : "+lookupUser);
+ }
+ if(!StringUtils.isEmpty(lookupUser)){
+ XXUser xxUser = daoMgr.getXXUser().findByUserName(lookupUser);
+ if (xxUser != null) {
+ vXUser = xUserService.populateViewBean(xxUser);
+ } else {
+ vXUser = xUserMgr.createServiceConfigUser(lookupUser);
+ LOG.info("Creating Lookup User : "+vXUser.getName());
+ }
+ }
+ }
+ }
+ return vXUser;
+ }
+
Map<String, RangerPolicyResource> createDefaultPolicyResource(List<RangerResourceDef> resourceHierarchy) throws Exception {
Map<String, RangerPolicyResource> resourceMap = new HashMap<>();
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java
index 16b00cd..e0f22d2 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java
@@ -33,8 +33,10 @@ import java.util.concurrent.TimeUnit;
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.ranger.common.PropertiesUtil;
import org.apache.ranger.common.TimedExecutor;
+import org.apache.ranger.plugin.client.HadoopConfigHolder;
import org.apache.ranger.plugin.client.HadoopException;
import org.apache.ranger.plugin.model.RangerService;
import org.apache.ranger.plugin.model.RangerServiceDef;
@@ -55,6 +57,13 @@ public class ServiceMgr {
private static final Log LOG = LogFactory.getLog(ServiceMgr.class);
+ private static final String LOOKUP_PRINCIPAL = "ranger.lookup.kerberos.principal";
+ private static final String LOOKUP_KEYTAB = "ranger.lookup.kerberos.keytab";
+ private static final String AUTHENTICATION_TYPE = "hadoop.security.authentication";
+ private static final String KERBEROS_TYPE = "kerberos";
+ static final String NAME_RULES = "hadoop.security.auth_to_local";
+ static final String HOST_NAME = "ranger.service.host";
+
@Autowired
RangerServiceService rangerSvcService;
@@ -72,11 +81,24 @@ public class ServiceMgr {
RangerService service = svcDBStore.getServiceByName(serviceName);
+ String authType = PropertiesUtil.getProperty(AUTHENTICATION_TYPE);
+ String lookupPrincipal = SecureClientLogin.getPrincipal(PropertiesUtil.getProperty(LOOKUP_PRINCIPAL), PropertiesUtil.getProperty(HOST_NAME));
+ String lookupKeytab = PropertiesUtil.getProperty(LOOKUP_KEYTAB);
+ String nameRules = PropertiesUtil.getProperty(NAME_RULES);
+
+ if(!StringUtils.isEmpty(authType) && authType.trim().equalsIgnoreCase(KERBEROS_TYPE) && SecureClientLogin.isKerberosCredentialExists(lookupPrincipal, lookupKeytab)){
+ if(service != null && service.getConfigs() != null){
+ service.getConfigs().put(HadoopConfigHolder.RANGER_LOOKUP_PRINCIPAL, lookupPrincipal);
+ service.getConfigs().put(HadoopConfigHolder.RANGER_LOOKUP_KEYTAB, lookupKeytab);
+ service.getConfigs().put(HadoopConfigHolder.RANGER_NAME_RULES, nameRules);
+ }
+ }
+
Map<String, String> newConfigs = rangerSvcService.getConfigsWithDecryptedPassword(service);
service.setConfigs(newConfigs);
RangerBaseService svc = getRangerServiceByService(service, svcStore);
-
+
if(LOG.isDebugEnabled()) {
LOG.debug("==> ServiceMgr.lookupResource for Service: (" + svc + "Context: " + context + ")");
}
@@ -101,6 +123,19 @@ public class ServiceMgr {
public VXResponse validateConfig(RangerService service, ServiceStore svcStore) throws Exception {
VXResponse ret = new VXResponse();
+ String authType = PropertiesUtil.getProperty(AUTHENTICATION_TYPE);
+ String lookupPrincipal = SecureClientLogin.getPrincipal(PropertiesUtil.getProperty(LOOKUP_PRINCIPAL), PropertiesUtil.getProperty(HOST_NAME));
+ String lookupKeytab = PropertiesUtil.getProperty(LOOKUP_KEYTAB);
+ String nameRules = PropertiesUtil.getProperty(NAME_RULES);
+
+ if(!StringUtils.isEmpty(authType) && authType.trim().equalsIgnoreCase(KERBEROS_TYPE) && SecureClientLogin.isKerberosCredentialExists(lookupPrincipal, lookupKeytab)){
+ if(service != null && service.getConfigs() != null){
+ service.getConfigs().put(HadoopConfigHolder.RANGER_LOOKUP_PRINCIPAL, lookupPrincipal);
+ service.getConfigs().put(HadoopConfigHolder.RANGER_LOOKUP_KEYTAB, lookupKeytab);
+ service.getConfigs().put(HadoopConfigHolder.RANGER_NAME_RULES, nameRules);
+ }
+ }
+
Map<String, String> newConfigs = rangerSvcService.getConfigsWithDecryptedPassword(service);
service.setConfigs(newConfigs);
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/security-admin/src/main/java/org/apache/ranger/biz/SessionMgr.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/SessionMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/SessionMgr.java
index c461e83..106d910 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/SessionMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/SessionMgr.java
@@ -77,6 +77,9 @@ public class SessionMgr {
RangerDaoManager daoManager;
@Autowired
+ XUserMgr xUserMgr;
+
+ @Autowired
AuthSessionService authSessionService;
@Autowired
@@ -118,6 +121,8 @@ public class SessionMgr {
}
if (newSessionCreation) {
+
+ getSpnegoAuthCheckForAPI(currentLoginId, httpRequest);
// Need to build the UserSession
XXPortalUser gjUser = daoManager.getXXPortalUser().findByLoginId(currentLoginId);
if (gjUser == null) {
@@ -157,6 +162,9 @@ public class SessionMgr {
userSession = new UserSessionBase();
userSession.setXXPortalUser(gjUser);
userSession.setXXAuthSession(gjAuthSession);
+ if(httpRequest.getAttribute("spnegoEnabled") != null && (boolean)httpRequest.getAttribute("spnegoEnabled")){
+ userSession.setSpnegoEnabled(true);
+ }
resetUserSessionForProfiles(userSession);
resetUserModulePermission(userSession);
@@ -180,6 +188,17 @@ public class SessionMgr {
return userSession;
}
+ private void getSpnegoAuthCheckForAPI(String currentLoginId, HttpServletRequest request) {
+
+ XXPortalUser gjUser = daoManager.getXXPortalUser().findByLoginId(currentLoginId);
+ if (gjUser == null && request.getAttribute("spnegoEnabled") != null && (boolean)request.getAttribute("spnegoEnabled")) {
+ if(logger.isDebugEnabled()){
+ logger.debug("User : "+currentLoginId+" doesn't exist in Ranger DB So creating user as it's spnego authenticated");
+ }
+ xUserMgr.createServiceConfigUser(currentLoginId);
+ }
+ }
+
public void resetUserModulePermission(UserSessionBase userSession) {
XXUser xUser = daoManager.getXXUser().findByUserName(userSession.getLoginId());
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
index 96ddf3f..571947c 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/XUserMgr.java
@@ -1813,7 +1813,7 @@ public class XUserMgr extends XUserMgrBase {
}
}
- protected VXUser createServiceConfigUser(String userName){
+ public VXUser createServiceConfigUser(String userName){
if (userName == null || "null".equalsIgnoreCase(userName) || userName.trim().isEmpty()) {
logger.error("User Name: "+userName);
throw restErrorUtil.createRESTException("Please provide a valid username.",MessageEnums.INVALID_INPUT_DATA);
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/security-admin/src/main/java/org/apache/ranger/common/UserSessionBase.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/common/UserSessionBase.java b/security-admin/src/main/java/org/apache/ranger/common/UserSessionBase.java
index 144a408..520aa88 100644
--- a/security-admin/src/main/java/org/apache/ranger/common/UserSessionBase.java
+++ b/security-admin/src/main/java/org/apache/ranger/common/UserSessionBase.java
@@ -40,6 +40,7 @@ public class UserSessionBase implements Serializable {
private RangerUserPermission rangerUserPermission;
int clientTimeOffsetInMinute = 0;
private Boolean isSSOEnabled;
+ private Boolean isSpnegoEnabled = false;
public Long getUserId() {
if (xXPortalUser != null) {
@@ -137,6 +138,14 @@ public class UserSessionBase implements Serializable {
this.isSSOEnabled = isSSOEnabled;
}
+ public Boolean isSpnegoEnabled() {
+ return isSpnegoEnabled;
+ }
+
+ public void setSpnegoEnabled(Boolean isSpnegoEnabled) {
+ this.isSpnegoEnabled = isSpnegoEnabled;
+ }
+
public static class RangerUserPermission implements Serializable {
private static final long serialVersionUID = 1L;
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/8614032c/security-admin/src/main/java/org/apache/ranger/rest/PublicAPIsv2.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/PublicAPIsv2.java b/security-admin/src/main/java/org/apache/ranger/rest/PublicAPIsv2.java
index b7c1b59..4432bac 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/PublicAPIsv2.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/PublicAPIsv2.java
@@ -38,6 +38,7 @@ import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.ws.rs.*;
import javax.ws.rs.core.Context;
+
import java.util.List;
@Path("public/v2")
@@ -187,15 +188,15 @@ public class PublicAPIsv2 {
@GET
@Path("/api/service/")
- @PreAuthorize("hasRole('ROLE_SYS_ADMIN')")
@Produces({ "application/json", "application/xml" })
+ @PreAuthorize("@rangerPreAuthSecurityHandler.isAPISpnegoAccessible()")
public List<RangerService> searchServices(@Context HttpServletRequest request) {
return serviceREST.getServices(request).getServices();
}
@POST
@Path("/api/service/")
- @PreAuthorize("hasRole('ROLE_SYS_ADMIN')")
+ @PreAuthorize("@rangerPreAuthSecurityHandler.isAPISpnegoAccessible()")
@Produces({ "application/json", "application/xml" })
public RangerService createService(RangerService service) {
return serviceREST.createService(service);