You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by ma...@apache.org on 2015/04/18 07:58:36 UTC
incubator-ranger git commit: RANGER-405 Hbase plugin: Don't skipt
auditing access requests by "superusers"
Repository: incubator-ranger
Updated Branches:
refs/heads/master 80c289370 -> f8b4d4a9a
RANGER-405 Hbase plugin: Don't skipt auditing access requests by "superusers"
Signed-off-by: Madhan Neethiraj <ma...@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/f8b4d4a9
Tree: http://git-wip-us.apache.org/repos/asf/incubator-ranger/tree/f8b4d4a9
Diff: http://git-wip-us.apache.org/repos/asf/incubator-ranger/diff/f8b4d4a9
Branch: refs/heads/master
Commit: f8b4d4a9a28e097abe21565a0af9c21ee700c699
Parents: 80c2893
Author: Alok Lal <al...@hortonworks.com>
Authored: Fri Apr 17 01:07:27 2015 -0700
Committer: Madhan Neethiraj <ma...@apache.org>
Committed: Fri Apr 17 22:52:19 2015 -0700
----------------------------------------------------------------------
.../hbase/AuthorizationSession.java | 16 ++++++-
.../authorization/hbase/HbaseAuditHandler.java | 5 ++
.../hbase/HbaseAuditHandlerImpl.java | 21 +++++++-
.../authorization/hbase/HbaseAuthUtilsImpl.java | 1 -
.../authorization/hbase/HbaseFactory.java | 6 +++
.../authorization/hbase/HbaseUserUtils.java | 7 +++
.../authorization/hbase/HbaseUserUtilsImpl.java | 50 ++++++++++++++++++--
.../hbase/RangerAuthorizationCoprocessor.java | 44 ++++-------------
.../java/org/apache/ranger/biz/AssetMgr.java | 2 +-
9 files changed, 110 insertions(+), 42 deletions(-)
----------------------------------------------------------------------
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f8b4d4a9/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java
index 1c712a4..46ed758 100644
--- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/AuthorizationSession.java
@@ -57,6 +57,7 @@ public class AuthorizationSession {
Set<String> _groups; // this exits to avoid having to get group for a user repeatedly. It is kept in sync with _user;
// Passing a null handler to policy engine would suppress audit logging.
HbaseAuditHandler _auditHandler = null;
+ boolean _superUser = false; // is this session for a super user?
// internal state per-authorization
RangerAccessRequest _request;
@@ -89,10 +90,11 @@ public class AuthorizationSession {
AuthorizationSession user(User aUser) {
_user = aUser;
if (_user == null) {
- LOG.debug("AuthorizationSession.user: user is null!");
+ LOG.warn("AuthorizationSession.user: user is null!");
_groups = null;
} else {
_groups = _userUtils.getUserGroups(_user);
+ _superUser = _userUtils.isSuperUser(_user);
}
return this;
}
@@ -185,6 +187,12 @@ public class AuthorizationSession {
throw new IllegalStateException(message);
} else {
// ok to pass potentially null handler to policy engine. Null handler effectively suppresses the audit.
+ if (_auditHandler != null && _superUser) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("Setting super-user override on audit handler");
+ }
+ _auditHandler.setSuperUserOverride(_superUser);
+ }
_result = _authorizer.isAccessAllowed(_request, _auditHandler);
}
if (LOG.isDebugEnabled()) {
@@ -255,6 +263,12 @@ public class AuthorizationSession {
} else {
allowed = _result.getIsAllowed();
}
+ if (!allowed && _superUser) {
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("User [" + _user + "] is a superUser! Overriding policy engine's decision. Request is deemed authorized!");
+ }
+ allowed = true;
+ }
return allowed;
}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f8b4d4a9/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandler.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandler.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandler.java
index 28d41aa..f94cef4 100644
--- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandler.java
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandler.java
@@ -45,4 +45,9 @@ public interface HbaseAuditHandler extends RangerAuditHandler {
*/
void setMostRecentEvent(AuthzAuditEvent capturedEvents);
+ /**
+ * Is audit handler being used in context of a access authorization of a superuser?
+ * @param override
+ */
+ void setSuperUserOverride(boolean override);
}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f8b4d4a9/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandlerImpl.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandlerImpl.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandlerImpl.java
index fb4f8a0..e383614 100644
--- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandlerImpl.java
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuditHandlerImpl.java
@@ -31,6 +31,7 @@ public class HbaseAuditHandlerImpl extends RangerDefaultAuditHandler implements
final List<AuthzAuditEvent> _allEvents = new ArrayList<AuthzAuditEvent>();
// we replace its contents anytime new audit events are generated.
AuthzAuditEvent _mostRecentEvent = null;
+ boolean _superUserOverride = false;
@Override
public AuthzAuditEvent getAuthzEvents(RangerAccessResult result) {
@@ -52,13 +53,14 @@ public class HbaseAuditHandlerImpl extends RangerDefaultAuditHandler implements
if (_mostRecentEvent != null) {
result.add(_mostRecentEvent);
}
-
+ applySuperUserOverride(result);
return result;
}
@Override
public AuthzAuditEvent discardMostRecentEvent() {
AuthzAuditEvent result = _mostRecentEvent;
+ applySuperUserOverride(result);
_mostRecentEvent = null;
return result;
}
@@ -67,4 +69,21 @@ public class HbaseAuditHandlerImpl extends RangerDefaultAuditHandler implements
public void setMostRecentEvent(AuthzAuditEvent event) {
_mostRecentEvent = event;
}
+
+ @Override
+ public void setSuperUserOverride(boolean override) {
+ _superUserOverride = override;
+ }
+
+ void applySuperUserOverride(List<AuthzAuditEvent> events) {
+ for (AuthzAuditEvent event : events) {
+ applySuperUserOverride(event);
+ }
+ }
+
+ void applySuperUserOverride(AuthzAuditEvent event) {
+ if (event != null && _superUserOverride) {
+ event.setAccessResult((short)1);
+ }
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f8b4d4a9/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtilsImpl.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtilsImpl.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtilsImpl.java
index a94bf1e..d80a04a 100644
--- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtilsImpl.java
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseAuthUtilsImpl.java
@@ -21,7 +21,6 @@ package org.apache.ranger.authorization.hbase;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.hadoop.hbase.HRegionInfo;
-import org.apache.hadoop.hbase.NamespaceDescriptor;
import org.apache.hadoop.hbase.coprocessor.RegionCoprocessorEnvironment;
import org.apache.hadoop.hbase.security.access.Permission.Action;
import org.apache.hadoop.hbase.util.Bytes;
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f8b4d4a9/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseFactory.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseFactory.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseFactory.java
index 5b5690f..3488d70 100644
--- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseFactory.java
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseFactory.java
@@ -18,6 +18,8 @@
*/
package org.apache.ranger.authorization.hbase;
+import org.apache.hadoop.conf.Configuration;
+
// TODO remove this in favor of Guice DI
@@ -48,4 +50,8 @@ public class HbaseFactory {
HbaseAuditHandler getAuditHandler() {
return new HbaseAuditHandlerImpl();
}
+
+ static void initialize(Configuration conf) {
+ HbaseUserUtilsImpl.initiailize(conf);
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f8b4d4a9/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtils.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtils.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtils.java
index aa85994..05d67d6 100644
--- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtils.java
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtils.java
@@ -49,4 +49,11 @@ public interface HbaseUserUtils {
* @return
*/
String getUserAsString();
+
+ /**
+ * Returns true of specified user is configured to be a super user
+ * @param user
+ * @return
+ */
+ boolean isSuperUser(User user);
}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f8b4d4a9/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtilsImpl.java
----------------------------------------------------------------------
diff --git a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtilsImpl.java b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtilsImpl.java
index fd15aaa..ddc84d8 100644
--- a/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtilsImpl.java
+++ b/hbase-agent/src/main/java/org/apache/ranger/authorization/hbase/HbaseUserUtilsImpl.java
@@ -20,22 +20,49 @@ package org.apache.ranger.authorization.hbase;
import java.io.IOException;
import java.util.Arrays;
-import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
+import java.util.concurrent.atomic.AtomicReference;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
+import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.hbase.ipc.RpcServer;
import org.apache.hadoop.hbase.security.User;
public class HbaseUserUtilsImpl implements HbaseUserUtils {
private static final Log LOG = LogFactory.getLog(HbaseUserUtilsImpl.class.getName());
+ private static final String SUPERUSER_CONFIG_PROP = "hbase.superuser";
- static Set<String> _SuperUsers = Collections.synchronizedSet(new HashSet<String>());
- static AtomicBoolean initialized = new AtomicBoolean(false);
+ // only to detect problems with initialization order, not for thread-safety.
+ static final AtomicBoolean _Initialized = new AtomicBoolean(false);
+ // should never be null
+ static final AtomicReference<Set<String>> _SuperUsers = new AtomicReference<Set<String>>(new HashSet<String>());
+
+ public static void initiailize(Configuration conf) {
+
+ if (_Initialized.get()) {
+ LOG.warn("HbaseUserUtilsImpl.initialize: Unexpected: initialization called more than once!");
+ } else {
+ if (conf == null) {
+ LOG.error("HbaseUserUtilsImpl.initialize: Internal error: called with null conf value!");
+ } else {
+ String[] users = conf.getStrings(SUPERUSER_CONFIG_PROP);
+ if (users != null && users.length > 0) {
+ Set<String> superUsers = new HashSet<String>(users.length);
+ for (String user : users) {
+ user = user.trim();
+ LOG.info("HbaseUserUtilsImpl.initialize: Adding Super User(" + user + ")");
+ superUsers.add(user);
+ }
+ _SuperUsers.set(superUsers);
+ }
+ }
+ _Initialized.set(true);
+ }
+ }
@Override
public String getUserAsString(User user) {
@@ -84,4 +111,21 @@ public class HbaseUserUtilsImpl implements HbaseUserUtils {
return getUserAsString(user);
}
}
+
+ /**
+ * No user can be a superuser till the class is properly initialized. Once class is properly initialized, users specified in
+ * configuration would be reported as super users.
+ */
+ @Override
+ public boolean isSuperUser(User user) {
+ if (!_Initialized.get()) {
+ LOG.error("HbaseUserUtilsImpl.isSuperUser: Internal error: called before initialization was complete!");
+ }
+ Set<String> superUsers = _SuperUsers.get(); // can never be null
+ boolean isSuper = superUsers.contains(user.getShortName());
+ if (LOG.isDebugEnabled()) {
+ LOG.debug("IsSuperCheck on [" + user.getShortName() + "] returns [" + isSuper + "]");
+ }
+ return isSuper;
+ }
}
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f8b4d4a9/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 edc769b..2926bec 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
@@ -72,11 +72,11 @@ import org.apache.hadoop.hbase.protobuf.ResponseConverter;
import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos;
import org.apache.hadoop.hbase.protobuf.generated.AccessControlProtos.AccessControlService;
import org.apache.hadoop.hbase.protobuf.generated.HBaseProtos.SnapshotDescription;
+import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Quotas;
import org.apache.hadoop.hbase.protobuf.generated.SecureBulkLoadProtos.CleanupBulkLoadRequest;
import org.apache.hadoop.hbase.protobuf.generated.SecureBulkLoadProtos.PrepareBulkLoadRequest;
-import org.apache.hadoop.hbase.protobuf.generated.QuotaProtos.Quotas;
-import org.apache.hadoop.hbase.regionserver.Region;
import org.apache.hadoop.hbase.regionserver.InternalScanner;
+import org.apache.hadoop.hbase.regionserver.Region;
import org.apache.hadoop.hbase.regionserver.RegionScanner;
import org.apache.hadoop.hbase.regionserver.ScanType;
import org.apache.hadoop.hbase.regionserver.Store;
@@ -115,7 +115,6 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
private static boolean UpdateRangerPoliciesOnGrantRevoke = RangerHadoopConstants.HBASE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_DEFAULT_VALUE;
private static final String GROUP_PREFIX = "@";
- private static final String SUPERUSER_CONFIG_PROP = "hbase.superuser";
private static final String WILDCARD = "*";
private static final TimeZone gmtTimeZone = TimeZone.getTimeZone("GMT+0");
@@ -123,8 +122,6 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
private RegionCoprocessorEnvironment regionEnv;
private Map<InternalScanner, String> scannerOwners = new MapMaker().weakKeys().makeMap();
- private List<String> superUserList = null;
-
/*
* These are package level only for testability and aren't meant to be exposed outside via getters/setters or made available to derived classes.
*/
@@ -150,21 +147,12 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
if (user == null) {
throw new IOException("Unable to obtain the current user, authorization checks for internal operations will not work correctly!");
}
- String currentUser = user.getShortName();
- List<String> superusers = Lists.asList(currentUser, conf.getStrings(SUPERUSER_CONFIG_PROP, new String[0]));
+ String systemUser = user.getShortName();
User activeUser = getActiveUser();
- if (!(superusers.contains(activeUser.getShortName()))) {
+ if (!Objects.equal(systemUser, activeUser.getShortName()) && !_userUtils.isSuperUser(activeUser)) {
throw new AccessDeniedException("User '" + user.getShortName() + "is not system or super user.");
}
}
- private boolean isSuperUser(User user) {
- boolean isSuper = false;
- isSuper = (superUserList != null && superUserList.contains(user.getShortName()));
- if (LOG.isDebugEnabled()) {
- LOG.debug("IsSuperCheck on [" + user.getShortName() + "] returns [" + isSuper + "]");
- }
- return isSuper;
- }
protected boolean isSpecialTable(HRegionInfo regionInfo) {
return isSpecialTable(regionInfo.getTable().getName());
}
@@ -213,7 +201,6 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
throw new AccessDeniedException("User '"+ requestUserName +"' is not the scanner owner!");
}
}
-
/**
* @param families
* @return empty map if families is null, would never have empty or null keys, would never have null values, values could be empty (non-null) set
@@ -344,7 +331,7 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
// if authorized then pass captured events as access allowed set else as access denied set.
result = new ColumnFamilyAccessResult(authorized, authorized,
authorized ? Collections.singletonList(event) : null,
- authorized ? null : event, null, reason);
+ authorized ? null : event, null, reason);
if (LOG.isDebugEnabled()) {
String message = String.format(messageTemplate, operation, access, families.toString(), result.toString());
LOG.debug(message);
@@ -534,9 +521,6 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
String message = "Unexpeceted: User is null: access denied, not audited!";
LOG.warn("canSkipAccessCheck: exiting" + message);
throw new AccessDeniedException("No user associated with request (" + operation + ") for action: " + access + "on table:" + table);
- } else if (isSuperUser(user)) {
- LOG.debug("canSkipAccessCheck: true: superuser access allowed, not audited");
- result = true;
} else if (isAccessForMetadataRead(access, table)) {
LOG.debug("canSkipAccessCheck: true: metadata read access always allowed, not audited");
result = true;
@@ -913,19 +897,9 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
coprocessorType = REGIONAL_COPROCESSOR_TYPE;
appType = "hbaseRegional";
}
-
- if (superUserList == null) {
- superUserList = new ArrayList<String>();
- Configuration conf = env.getConfiguration();
- String[] users = conf.getStrings(SUPERUSER_CONFIG_PROP);
- if (users != null) {
- for (String user : users) {
- user = user.trim();
- LOG.info("Start() - Adding Super User(" + user + ")");
- superUserList.add(user);
- }
- }
- }
+
+ Configuration conf = env.getConfiguration();
+ HbaseFactory.initialize(conf);
// create and initialize the plugin class
RangerHBasePlugin plugin = hbasePlugin;
@@ -947,7 +921,7 @@ public class RangerAuthorizationCoprocessor extends RangerAuthorizationCoprocess
}
if (LOG.isDebugEnabled()) {
- LOG.debug("Start of Coprocessor: [" + coprocessorType + "] with superUserList [" + superUserList + "]");
+ LOG.debug("Start of Coprocessor: [" + coprocessorType + "]");
}
}
@Override
http://git-wip-us.apache.org/repos/asf/incubator-ranger/blob/f8b4d4a9/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
----------------------------------------------------------------------
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java b/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
index 1c076c5..a838d8e 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/AssetMgr.java
@@ -1694,7 +1694,7 @@ public class AssetMgr extends AssetMgrBase {
.getBooleanProperty(
"xa.log.SC_NOT_MODIFIED", false);
if (!logNotModified) {
- logger.info("Not logging HttpServletResponse."
+ logger.debug("Not logging HttpServletResponse."
+ "SC_NOT_MODIFIED, to enable, update "
+ ": xa.log.SC_NOT_MODIFIED");
return null;