This is an automated email from the ASF dual-hosted git repository.
rmani pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/ranger.git
The following commit(s) were added to refs/heads/master by this push:
new cc3be69 RANGER-2389:Ranger Hive Plugin enhancement for KILL query and
Replication commands authorization
cc3be69 is described below
commit cc3be6945aa66af55a2c289ec3c447f760f48c0d
Author: rmani <[email protected]>
AuthorDate: Mon Apr 1 12:51:45 2019 -0700
RANGER-2389:Ranger Hive Plugin enhancement for KILL query and Replication
commands authorization
Signed-off-by: rmani <[email protected]>
---
.../service-defs/ranger-servicedef-hive.json | 35 ++-
.../policyengine/test_policyengine_hive.json | 37 ++-
.../hive/authorizer/RangerHiveAccessRequest.java | 2 -
.../hive/authorizer/RangerHiveAuditHandler.java | 59 ++++-
.../hive/authorizer/RangerHiveAuthorizer.java | 108 ++++++++-
.../hive/authorizer/RangerHiveResource.java | 50 +++--
.../services/hive/HIVERangerAuthorizerTest.java | 87 +++++++
.../services/hive/RangerHiveOperationType.java | 171 ++++++++++++++
.../hive/TestAllHiveOperationInRanger.java | 52 +++++
hive-agent/src/test/resources/hive-policies.json | 249 ++++++++++++++++++++-
.../org/apache/ranger/common/AppConstants.java | 25 ++-
.../java/org/apache/ranger/common/ServiceUtil.java | 13 +-
.../patch/PatchForHiveServiceDefUpdate_J10009.java | 226 +++++++++++++++++++
.../patch/PatchForHiveServiceDefUpdate_J10010.java | 213 ++++++++++++++++++
.../main/java/org/apache/ranger/view/VXPolicy.java | 25 +++
.../java/org/apache/ranger/view/VXResource.java | 26 +++
16 files changed, 1347 insertions(+), 31 deletions(-)
diff --git
a/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
b/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
index b0f877a..0b2f78d 100644
--- a/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
+++ b/agents-common/src/main/resources/service-defs/ranger-servicedef-hive.json
@@ -100,6 +100,25 @@
"uiHint":"",
"label": "URL",
"description": "URL"
+ },
+
+ {
+ "itemId": 6,
+ "name": "hiveservice",
+ "type": "string",
+ "level": 10,
+ "parent": "",
+ "mandatory": true,
+ "lookupSupported": false,
+ "recursiveSupported": false,
+ "excludesSupported": false,
+ "matcher":
"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+ "matcherOptions": { "wildCard":true, "ignoreCase":false
},
+ "validationRegEx":"",
+ "validationMessage": "",
+ "uiHint":"",
+ "label": "Hive Service",
+ "description": "Hive Service"
}
],
@@ -161,7 +180,9 @@
"index",
"lock",
"read",
- "write"
+ "write",
+ "repladmin",
+ "serviceadmin"
]
},
@@ -175,6 +196,18 @@
"itemId": 10,
"name": "write",
"label": "Write"
+ },
+
+ {
+ "itemId": 11,
+ "name": "repladmin",
+ "label": "ReplAdmin"
+ },
+
+ {
+ "itemId": 12,
+ "name": "serviceadmin",
+ "label": "Service Admin"
}
],
diff --git
a/agents-common/src/test/resources/policyengine/test_policyengine_hive.json
b/agents-common/src/test/resources/policyengine/test_policyengine_hive.json
index b7f9888..66b3644 100644
--- a/agents-common/src/test/resources/policyengine/test_policyengine_hive.json
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_hive.json
@@ -6,6 +6,8 @@
"id":3,
"resources":[
{"name":"database","level":1,"mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
"ignoreCase":true},"label":"Hive Database","description":"Hive Database"},
+
{"name":"url","level":1,"mandatory":true,"lookupSupported":false,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
"ignoreCase":true},"label":"URL","description":"URL"},
+
{"name":"hiveservice","level":1,"mandatory":true,"lookupSupported":false,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
"ignoreCase":true},"label":"HiveService","description":"HiveService"},
{"name":"table","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
"ignoreCase":true},"label":"Hive Table","description":"Hive Table"},
{"name":"udf","level":2,"parent":"database","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
"ignoreCase":true},"label":"Hive UDF","description":"Hive UDF"},
{"name":"column","level":3,"parent":"table","mandatory":true,"lookupSupported":true,"matcher":"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher","matcherOptions":{"wildCard":true,
"ignoreCase":true},"label":"Hive Column","description":"Hive Column"}
@@ -18,7 +20,25 @@
{"name":"alter","label":"Alter"},
{"name":"index","label":"Index"},
{"name":"lock","label":"Lock"},
- {"name":"all","label":"All"}
+ {"name":"read","label":"Read"},
+ {"name":"write","label":"Write"},
+ {"name":"repladmin","label":"ReplAdmin"},
+ {"name":"serviceadmin","label":"ServiceAdmin"},
+ {"name":"all","label":"All",
+ "impliedGrants": [
+ "select",
+ "update",
+ "create",
+ "drop",
+ "alter",
+ "index",
+ "lock",
+ "read",
+ "write",
+ "repladmin",
+ "serviceadmin"
+ ]
+ }
]
},
@@ -52,6 +72,13 @@
{"accesses":[{"type":"select","isAllowed":true}],"users":["user1","user2"],"groups":["group1","group2"],"delegateAdmin":false}
]
}
+ ,
+ {"id":5,"name":"hiveservice=*","isEnabled":true,"isAuditEnabled":true,
+ "resources":{"hiveservice":{"values":["*"]}},
+ "policyItems":[
+
{"accesses":[{"type":"serviceadmin","isAllowed":true}],"users":["user1"],"groups":[],"delegateAdmin":false}
+ ]
+ }
],
"tests":[
@@ -327,6 +354,14 @@
},
"result":{"isAudited":true,"isAllowed":true,"policyId":3}
}
+ ,
+ {"name":"ALLOW 'kill_query' for user1 on any cluster",
+ "request":{
+ "resource":{"elements":{"hiveservice":"testcluster"}},
+
"accessType":"serviceadmin","user":"user1","userGroups":["users"],"requestData":"kill
query 'dummyqueryid'"
+ },
+ "result":{"isAudited":true,"isAllowed":true,"policyId":5}
+ }
]
}
diff --git
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAccessRequest.java
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAccessRequest.java
index a8bf543..df379c3 100644
---
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAccessRequest.java
+++
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAccessRequest.java
@@ -89,8 +89,6 @@ public class RangerHiveAccessRequest extends
RangerAccessRequestImpl {
if(accessType == HiveAccessType.USE) {
this.setAccessType(RangerPolicyEngine.ANY_ACCESS);
- } else if(accessType == HiveAccessType.ADMIN) {
- this.setAccessType(RangerPolicyEngine.ADMIN_ACCESS);
} else {
this.setAccessType(accessType.name().toLowerCase());
}
diff --git
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
index ac35d77..8fd48f8 100644
---
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
+++
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuditHandler.java
@@ -21,6 +21,7 @@ package org.apache.ranger.authorization.hive.authorizer;
import java.util.*;
+import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.ranger.audit.model.AuthzAuditEvent;
import org.apache.ranger.plugin.audit.RangerDefaultAuditHandler;
@@ -55,11 +56,32 @@ public class RangerHiveAuditHandler extends
RangerDefaultAuditHandler {
if (request instanceof RangerHiveAccessRequest && resource
instanceof RangerHiveResource) {
RangerHiveAccessRequest hiveAccessRequest =
(RangerHiveAccessRequest) request;
RangerHiveResource hiveResource = (RangerHiveResource)
resource;
+ HiveAccessType hiveAccessType =
hiveAccessRequest.getHiveAccessType();
- if (hiveAccessRequest.getHiveAccessType() ==
HiveAccessType.USE && hiveResource.getObjectType() == HiveObjectType.DATABASE) {
- // this should happen only for SHOWDATABASES
and USE <db-name> commands
+ if (hiveAccessType == HiveAccessType.USE &&
hiveResource.getObjectType() == HiveObjectType.DATABASE &&
StringUtils.isBlank(hiveResource.getDatabase())) {
+ // this should happen only for SHOWDATABASES
auditEvent.setTags(null);
}
+
+ if (hiveAccessType == HiveAccessType.REPLADMIN ) {
+ // In case of REPL commands Audit should show
what REPL Command instead of REPLADMIN access type
+ String context = request.getRequestData();
+ String replAccessType =
getReplCmd(context);
+
auditEvent.setAccessType(replAccessType);
+ }
+
+ if (hiveAccessType == HiveAccessType.SERVICEADMIN) {
+ String commandStr = request.getRequestData();
+ String queryId =
getServiceAdminQueryId(commandStr);
+ if (!StringUtils.isEmpty(queryId)) {
+ auditEvent.setRequestData(queryId);
+ }
+ commandStr = getServiceAdminCmd(commandStr);
+ if (StringUtils.isEmpty(commandStr)) {
+ commandStr = hiveAccessType.name();
+ }
+ auditEvent.setAccessType(commandStr);
+ }
}
return auditEvent;
@@ -209,4 +231,37 @@ public class RangerHiveAuditHandler extends
RangerDefaultAuditHandler {
}
}
}
+
+ private String getReplCmd(String cmdString) {
+ String ret = "REPL";
+ if (cmdString != null) {
+ String[] cmd = cmdString.trim().split("\\s+");
+ if (!ArrayUtils.isEmpty(cmd) && cmd.length > 2) {
+ ret = cmd[0] + " " + cmd[1];
+ }
+ }
+ return ret;
+ }
+
+ private String getServiceAdminCmd(String cmdString) {
+ String ret = "SERVICE ADMIN";
+ if (cmdString != null) {
+ String[] cmd = cmdString.trim().split("\\s+");
+ if (!ArrayUtils.isEmpty(cmd) && cmd.length > 1) {
+ ret = cmd[0] + " " + cmd[1];
+ }
+ }
+ return ret;
+ }
+
+ private String getServiceAdminQueryId(String cmdString) {
+ String ret = "QUERY ID = ";
+ if (cmdString != null) {
+ String[] cmd = cmdString.trim().split("\\s+");
+ if (!ArrayUtils.isEmpty(cmd) && cmd.length > 2) {
+ ret = ret + cmd[2];
+ }
+ }
+ return ret;
+ }
}
diff --git
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
index be82639..88ecf5f 100644
---
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
+++
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveAuthorizer.java
@@ -30,6 +30,7 @@ import java.util.Set;
import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.collections.MapUtils;
+import org.apache.commons.lang.ArrayUtils;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
@@ -302,6 +303,22 @@ public class RangerHiveAuthorizer extends
RangerHiveAuthorizerBase {
RangerHiveResource resource = new
RangerHiveResource(HiveObjectType.DATABASE, null);
RangerHiveAccessRequest request = new
RangerHiveAccessRequest(resource, user, groups, hiveOpType.name(),
HiveAccessType.USE, context, sessionContext, clusterName);
requests.add(request);
+ } else if ( hiveOpType ==
HiveOperationType.REPLDUMP) {
+ // This happens when REPL DUMP command
with null inputHObjs is sent in checkPrivileges()
+ // following parsing is done for Audit
info
+ RangerHiveResource resource = null;
+ HiveObj hiveObj = new HiveObj(context);
+ String dbName =
hiveObj.getDatabaseName();
+ String tableName =
hiveObj.getTableName();
+ LOG.debug("Database: " + dbName + "
Table: " + tableName);
+ if (!StringUtil.isEmpty(tableName)) {
+ resource = new
RangerHiveResource(HiveObjectType.TABLE, dbName, tableName);
+ } else {
+ resource = new
RangerHiveResource(HiveObjectType.DATABASE, dbName, null);
+ }
+ //
+ RangerHiveAccessRequest request = new
RangerHiveAccessRequest(resource, user, groups, hiveOpType.name(),
HiveAccessType.REPLADMIN, context, sessionContext, clusterName);
+ requests.add(request);
} else {
if (LOG.isDebugEnabled()) {
LOG.debug("RangerHiveAuthorizer.checkPrivileges: Unexpected operation type[" +
hiveOpType + "] received with empty input objects list!");
@@ -342,6 +359,23 @@ public class RangerHiveAuthorizer extends
RangerHiveAuthorizerBase {
requests.add(request);
}
}
+ } else {
+ if (hiveOpType == HiveOperationType.REPLLOAD) {
+ // This happens when REPL LOAD command
with null inputHObjs is sent in checkPrivileges()
+ // following parsing is done for Audit
info
+ RangerHiveResource resource = null;
+ HiveObj hiveObj = new HiveObj(context);
+ String dbName =
hiveObj.getDatabaseName();
+ String tableName =
hiveObj.getTableName();
+ LOG.debug("Database: " + dbName + "
Table: " + tableName);
+ if (!StringUtil.isEmpty(tableName)) {
+ resource = new
RangerHiveResource(HiveObjectType.TABLE, dbName, tableName);
+ } else {
+ resource = new
RangerHiveResource(HiveObjectType.DATABASE, dbName, null);
+ }
+ RangerHiveAccessRequest request = new
RangerHiveAccessRequest(resource, user, groups, hiveOpType.name(),
HiveAccessType.REPLADMIN, context, sessionContext, clusterName);
+ requests.add(request);
+ }
}
buildRequestContextWithAllAccessedResources(requests);
@@ -828,6 +862,7 @@ public class RangerHiveAuthorizer extends
RangerHiveAuthorizerBase {
break;
case URI:
+ case SERVICE_NAME:
ret = new RangerHiveResource(objectType,
hiveObj.getObjectName());
break;
@@ -883,6 +918,10 @@ public class RangerHiveAuthorizer extends
RangerHiveAuthorizerBase {
case GLOBAL:
break;
+ case SERVICE_NAME:
+ objType = HiveObjectType.SERVICE_NAME;
+ break;
+
case COLUMN:
// Thejas: this value is unused in Hive; the
case should not be hit.
break;
@@ -930,12 +969,14 @@ public class RangerHiveAuthorizer extends
RangerHiveAuthorizerBase {
case CREATETABLE:
case CREATEVIEW:
case CREATETABLE_AS_SELECT:
+ case CREATE_MATERIALIZED_VIEW:
if(hiveObj.getType() ==
HivePrivilegeObjectType.TABLE_OR_VIEW) {
accessType = isInput ?
HiveAccessType.SELECT : HiveAccessType.CREATE;
}
break;
case ALTERDATABASE:
+ case ALTERDATABASE_LOCATION:
case ALTERDATABASE_OWNER:
case ALTERINDEX_PROPS:
case ALTERINDEX_REBUILD:
@@ -985,6 +1026,7 @@ public class RangerHiveAuthorizer extends
RangerHiveAuthorizerBase {
case DROPINDEX:
case DROPTABLE:
case DROPVIEW:
+ case DROP_MATERIALIZED_VIEW:
case DROPDATABASE:
accessType = HiveAccessType.DROP;
break;
@@ -1054,6 +1096,7 @@ public class RangerHiveAuthorizer extends
RangerHiveAuthorizerBase {
case SWITCHDATABASE:
case DESCDATABASE:
case SHOWTABLES:
+ case SHOWVIEWS:
accessType = HiveAccessType.USE;
break;
@@ -1066,6 +1109,16 @@ public class RangerHiveAuthorizer extends
RangerHiveAuthorizerBase {
accessType = HiveAccessType.NONE; //
access check will be performed at the ranger-admin side
break;
+ case REPLDUMP:
+ case REPLLOAD:
+ case REPLSTATUS:
+ accessType = HiveAccessType.REPLADMIN;
+ break;
+
+ case KILL_QUERY:
+ accessType =
HiveAccessType.SERVICEADMIN;
+ break;
+
case ADD:
case DELETE:
case COMPILE:
@@ -1114,6 +1167,7 @@ public class RangerHiveAuthorizer extends
RangerHiveAuthorizerBase {
case CREATETABLE:
case CREATETABLE_AS_SELECT:
case ALTERDATABASE:
+ case ALTERDATABASE_LOCATION:
case ALTERDATABASE_OWNER:
case ALTERTABLE_ADDCOLS:
case ALTERTABLE_REPLACECOLS:
@@ -1174,6 +1228,7 @@ public class RangerHiveAuthorizer extends
RangerHiveAuthorizerBase {
case SHOW_CREATEDATABASE:
case SHOW_CREATETABLE:
case SHOWFUNCTIONS:
+ case SHOWVIEWS:
case SHOWINDEXES:
case SHOWPARTITIONS:
case SHOWLOCKS:
@@ -1185,11 +1240,13 @@ public class RangerHiveAuthorizer extends
RangerHiveAuthorizerBase {
case DROPMACRO:
case CREATEVIEW:
case DROPVIEW:
+ case CREATE_MATERIALIZED_VIEW:
case CREATEINDEX:
case DROPINDEX:
case ALTERINDEX_REBUILD:
case ALTERVIEW_PROPERTIES:
case DROPVIEW_PROPERTIES:
+ case DROP_MATERIALIZED_VIEW:
case LOCKTABLE:
case UNLOCKTABLE:
case CREATEROLE:
@@ -1226,6 +1283,10 @@ public class RangerHiveAuthorizer extends
RangerHiveAuthorizerBase {
case GET_TABLES:
case GET_TABLETYPES:
case GET_TYPEINFO:
+ case REPLDUMP:
+ case REPLLOAD:
+ case REPLSTATUS:
+ case KILL_QUERY:
break;
}
@@ -1913,8 +1974,51 @@ public class RangerHiveAuthorizer extends
RangerHiveAuthorizerBase {
}
}
-enum HiveObjectType { NONE, DATABASE, TABLE, VIEW, PARTITION, INDEX, COLUMN,
FUNCTION, URI };
-enum HiveAccessType { NONE, CREATE, ALTER, DROP, INDEX, LOCK, SELECT, UPDATE,
USE, READ, WRITE, ALL, ADMIN };
+enum HiveObjectType { NONE, DATABASE, TABLE, VIEW, PARTITION, INDEX, COLUMN,
FUNCTION, URI, SERVICE_NAME };
+enum HiveAccessType { NONE, CREATE, ALTER, DROP, INDEX, LOCK, SELECT, UPDATE,
USE, READ, WRITE, ALL, REPLADMIN, SERVICEADMIN };
+
+class HiveObj {
+ String databaseName;
+ String tableName;
+
+ HiveObj(HiveAuthzContext context) {
+ fetchHiveObj(context);
+ }
+
+ public String getDatabaseName() {
+ return databaseName;
+ }
+
+ public String getTableName() {
+ return tableName;
+ }
+
+ private void fetchHiveObj(HiveAuthzContext context) {
+ if (context != null) {
+ String cmdString = context.getCommandString();
+ if (cmdString != null) {
+ String[] cmd = cmdString.trim().split("\\s+");
+ if (!ArrayUtils.isEmpty(cmd) && cmd.length > 2)
{
+ String dbName = cmd[2];
+ if (dbName.contains(".")) {
+ String[] result =
splitDBName(dbName);
+ databaseName = result[0];
+ tableName = result[1];
+ } else {
+ databaseName = dbName;
+ tableName = null;
+ }
+ }
+ }
+ }
+ }
+
+ private String[] splitDBName(String dbName) {
+ String[] ret = null;
+ ret = dbName.split("\\.");
+ return ret;
+ }
+}
class RangerHivePlugin extends RangerBasePlugin {
public static boolean UpdateXaPoliciesOnGrantRevoke =
RangerHadoopConstants.HIVE_UPDATE_RANGER_POLICIES_ON_GRANT_REVOKE_DEFAULT_VALUE;
diff --git
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveResource.java
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveResource.java
index 48b8cb2..bbddff5 100644
---
a/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveResource.java
+++
b/hive-agent/src/main/java/org/apache/ranger/authorization/hive/authorizer/RangerHiveResource.java
@@ -30,52 +30,60 @@ public class RangerHiveResource extends
RangerAccessResourceImpl {
public static final String KEY_UDF = "udf";
public static final String KEY_COLUMN = "column";
public static final String KEY_URL = "url";
+ public static final String KEY_HIVESERVICE = "hiveservice";
private HiveObjectType objectType = null;
- public RangerHiveResource(HiveObjectType objectType, String
databaseorUrl) {
- this(objectType, databaseorUrl, null, null);
+ //FirstLevelResource => Database or URL or Hive Service
+ //SecondLevelResource => Table or UDF
+ //ThirdLevelResource => column
+ public RangerHiveResource(HiveObjectType objectType, String
firstLevelResource) {
+ this(objectType, firstLevelResource, null, null);
}
- public RangerHiveResource(HiveObjectType objectType, String
databaseorUrl, String tableOrUdf) {
- this(objectType, databaseorUrl, tableOrUdf, null);
+ public RangerHiveResource(HiveObjectType objectType, String
firstLevelResource, String secondLevelResource) {
+ this(objectType, firstLevelResource, secondLevelResource, null);
}
- public RangerHiveResource(HiveObjectType objectType, String
databaseorUrl, String tableOrUdf, String column) {
+ public RangerHiveResource(HiveObjectType objectType, String
firstLevelResource, String secondLevelResource, String thirdLevelResource) {
this.objectType = objectType;
switch(objectType) {
case DATABASE:
- if (databaseorUrl == null) {
- databaseorUrl = "*";
- }
- setValue(KEY_DATABASE, databaseorUrl);
+ setValue(KEY_DATABASE, firstLevelResource);
break;
case FUNCTION:
- if (databaseorUrl == null) {
- databaseorUrl = "";
+ if (firstLevelResource == null) {
+ firstLevelResource = "";
}
- setValue(KEY_DATABASE, databaseorUrl);
- setValue(KEY_UDF, tableOrUdf);
+ setValue(KEY_DATABASE, firstLevelResource);
+ setValue(KEY_UDF, secondLevelResource);
break;
case COLUMN:
- setValue(KEY_DATABASE, databaseorUrl);
- setValue(KEY_TABLE, tableOrUdf);
- setValue(KEY_COLUMN, column);
+ setValue(KEY_DATABASE, firstLevelResource);
+ setValue(KEY_TABLE, secondLevelResource);
+ setValue(KEY_COLUMN, thirdLevelResource);
break;
case TABLE:
case VIEW:
case INDEX:
case PARTITION:
- setValue(KEY_DATABASE, databaseorUrl);
- setValue(KEY_TABLE, tableOrUdf);
+ setValue(KEY_DATABASE, firstLevelResource);
+ setValue(KEY_TABLE, secondLevelResource);
break;
case URI:
- setValue(KEY_URL,databaseorUrl);
+ setValue(KEY_URL,firstLevelResource);
+ break;
+
+ case SERVICE_NAME:
+ if (firstLevelResource == null) {
+ firstLevelResource = "";
+ }
+ setValue(KEY_HIVESERVICE,firstLevelResource);
break;
case NONE:
@@ -107,4 +115,8 @@ public class RangerHiveResource extends
RangerAccessResourceImpl {
public String getUrl() {
return (String) getValue(KEY_URL);
}
+
+ public String getHiveService() {
+ return (String) getValue(KEY_HIVESERVICE);
+ }
}
diff --git
a/hive-agent/src/test/java/org/apache/ranger/services/hive/HIVERangerAuthorizerTest.java
b/hive-agent/src/test/java/org/apache/ranger/services/hive/HIVERangerAuthorizerTest.java
index b04e8bc..e7bed94 100644
---
a/hive-agent/src/test/java/org/apache/ranger/services/hive/HIVERangerAuthorizerTest.java
+++
b/hive-agent/src/test/java/org/apache/ranger/services/hive/HIVERangerAuthorizerTest.java
@@ -80,6 +80,10 @@ public class HIVERangerAuthorizerTest {
File scratchDir = new
File("./target/hdfs/scratchdir").getAbsoluteFile();
conf.set("hive.exec.scratchdir", scratchDir.getPath());
+ // REPL DUMP target folder
+ File replRootDir = new File("./target/user/hive").getAbsoluteFile();
+ conf.set("hive.repl.rootdir", replRootDir.getPath());
+
// Create a temporary directory for the Hive metastore
File metastoreDir = new File("./metastore_db/").getAbsoluteFile();
conf.set(HiveConf.ConfVars.METASTORECONNECTURLKEY.varname,
@@ -102,6 +106,7 @@ public class HIVERangerAuthorizerTest {
Statement statement = connection.createStatement();
statement.execute("CREATE DATABASE IF NOT EXISTS rangerauthz");
+ statement.execute("CREATE DATABASE IF NOT EXISTS demo");
statement.close();
connection.close();
@@ -945,4 +950,86 @@ public class HIVERangerAuthorizerTest {
connection.close();
}
+ // test "dat_test_user", to do REPL DUMP
+ @Test
+ public void testREPLDUMPAuth() throws Exception {
+
+ String url = "jdbc:hive2://localhost:" + port + "/rangerauthz";
+ Connection connection = DriverManager.getConnection(url,
"da_test_user", "da_test_user");
+
+ Statement statement = connection.createStatement();
+ try {
+ statement.execute("repl dump rangerauthz");
+ } catch (SQLException ex) {
+ Assert.fail("access should have been granted to da_test_user");
+ }
+ statement.close();
+ connection.close();
+
+ connection = DriverManager.getConnection(url, "bob", "bob");
+ statement = connection.createStatement();
+ try {
+ statement.execute("repl dump rangerauthz");
+ Assert.fail("Failure expected on an unauthorized call");
+ } catch (SQLException ex) {
+ //Excepted
+ }
+ statement.close();
+ connection.close();
+ }
+
+ // test "dat_test_user", to do REPL DUMP
+ @Test
+ public void testREPLDUMPTableAuth() throws Exception {
+
+ String url = "jdbc:hive2://localhost:" + port + "/rangerauthz";
+ Connection connection = DriverManager.getConnection(url,
"da_test_user", "da_test_user");
+
+ Statement statement = connection.createStatement();
+ try {
+ statement.execute("repl dump rangerauthz.words");
+ } catch (SQLException ex) {
+ Assert.fail("access should have been granted to da_test_user");
+ }
+ statement.close();
+ connection.close();
+
+ connection = DriverManager.getConnection(url, "bob", "bob");
+ statement = connection.createStatement();
+ try {
+ statement.execute("repl dump rangerauthz.words");
+ Assert.fail("Failure expected on an unauthorized call");
+ } catch (SQLException ex) {
+ //Excepted
+ }
+ statement.close();
+ connection.close();
+ }
+
+ @Test
+ public void testKillQuery() throws Exception {
+
+ String url = "jdbc:hive2://localhost:" + port + "/rangerauthz";
+ Connection connection = DriverManager.getConnection(url,
"da_test_user", "da_test_user");
+
+ Statement statement = connection.createStatement();
+ try {
+ statement.execute("kill query 'dummyQueryId'");
+ } catch (SQLException ex) {
+ Assert.fail("access should have been granted to da_test_user");
+ }
+ statement.close();
+ connection.close();
+
+ connection = DriverManager.getConnection(url, "bob", "bob");
+ statement = connection.createStatement();
+ try {
+ statement.execute("kill query 'dummyQueryId'");
+ Assert.fail("Failure expected on an unauthorized call");
+ } catch (SQLException ex) {
+ //Excepted
+ }
+ statement.close();
+ connection.close();
+ }
}
diff --git
a/hive-agent/src/test/java/org/apache/ranger/services/hive/RangerHiveOperationType.java
b/hive-agent/src/test/java/org/apache/ranger/services/hive/RangerHiveOperationType.java
new file mode 100644
index 0000000..e0142c9
--- /dev/null
+++
b/hive-agent/src/test/java/org/apache/ranger/services/hive/RangerHiveOperationType.java
@@ -0,0 +1,171 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ranger.services.hive;
+
+public enum RangerHiveOperationType {
+ CREATEDATABASE,
+ CREATEFUNCTION,
+ CREATETABLE,
+ CREATEVIEW,
+ CREATE_MATERIALIZED_VIEW,
+ CREATETABLE_AS_SELECT,
+ CREATE_MAPPING,
+ CREATE_RESOURCEPLAN,
+ CREATE_TRIGGER,
+ CREATE_POOL,
+ ALTERDATABASE,
+ ALTERDATABASE_OWNER,
+ ALTERINDEX_PROPS,
+ ALTERINDEX_REBUILD,
+ ALTERDATABASE_LOCATION,
+ ALTERPARTITION_BUCKETNUM,
+ ALTERPARTITION_FILEFORMAT,
+ ALTERPARTITION_LOCATION,
+ ALTERPARTITION_MERGEFILES,
+ ALTERPARTITION_PROTECTMODE,
+ ALTERPARTITION_SERDEPROPERTIES,
+ ALTERPARTITION_SERIALIZER,
+ ALTERTABLE_ADDCOLS,
+ ALTERTABLE_ADDPARTS,
+ ALTERTABLE_ARCHIVE,
+ ALTERTABLE_BUCKETNUM,
+ ALTERTABLE_CLUSTER_SORT,
+ ALTERTABLE_COMPACT,
+ ALTERTABLE_DROPPARTS,
+ ALTERTABLE_DROPCONSTRAINT,
+ ALTERTABLE_ADDCONSTRAINT,
+ ALTERTABLE_FILEFORMAT,
+ ALTERTABLE_LOCATION,
+ ALTERTABLE_MERGEFILES,
+ ALTERTABLE_PARTCOLTYPE,
+ ALTERTABLE_PROPERTIES,
+ ALTERTABLE_PROTECTMODE,
+ ALTERTABLE_RENAME,
+ ALTERTABLE_RENAMECOL,
+ ALTERTABLE_RENAMEPART,
+ ALTERTABLE_REPLACECOLS,
+ ALTERTABLE_SERDEPROPERTIES,
+ ALTERTABLE_SERIALIZER,
+ ALTERTABLE_SKEWED,
+ ALTERTABLE_TOUCH,
+ ALTERTABLE_UNARCHIVE,
+ ALTERTABLE_UPDATEPARTSTATS,
+ ALTERTABLE_UPDATETABLESTATS,
+ ALTERTABLE_UPDATECOLUMNS,
+ ALTERTABLE_EXCHANGEPARTITION,
+ ALTER_RESOURCEPLAN,
+ ALTER_MATERIALIZED_VIEW_REWRITE,
+ ALTER_MAPPING,
+ ALTER_TRIGGER,
+ ALTER_POOL,
+ ALTERTABLE_OWNER,
+ ALTERTBLPART_SKEWED_LOCATION,
+ ALTERVIEW_AS,
+ ALTERVIEW_PROPERTIES,
+ ALTERVIEW_RENAME,
+ DROPVIEW_PROPERTIES,
+ MSCK,
+ DROPFUNCTION,
+ DROPINDEX,
+ DROPTABLE,
+ DROPVIEW,
+ DROP_MATERIALIZED_VIEW,
+ DROPDATABASE,
+ DROP_RESOURCEPLAN,
+ DROP_TRIGGER,
+ DROP_POOL,
+ DROP_MAPPING,
+ CREATEINDEX,
+ INDEX,
+ IMPORT,
+ EXPORT,
+ LOAD,
+ LOCKDB,
+ LOCKTABLE,
+ UNLOCKDB,
+ UNLOCKTABLE,
+ LOCK,
+ QUERY,
+ CACHE_METADATA,
+ ANALYZE_TABLE,
+ SHOWCOLUMNS,
+ DESCTABLE,
+ SHOWDATABASES,
+ SWITCHDATABASE,
+ DESCDATABASE,
+ SHOWTABLES,
+ TRUNCATETABLE,
+ GRANT_PRIVILEGE,
+ REVOKE_PRIVILEGE,
+ SHOW_TABLESTATUS,
+ SHOW_TBLPROPERTIES,
+ SHOW_CREATEDATABASE,
+ SHOW_CREATETABLE,
+ SHOW_RESOURCEPLAN,
+ SHOWMATERIALIZEDVIEWS,
+ SHOWVIEWS,
+ SHOWINDEXES,
+ SHOWPARTITIONS,
+ ADD,
+ DELETE,
+ COMPILE,
+ CREATEMACRO,
+ CREATEROLE,
+ DESCFUNCTION,
+ DFS,
+ RELOADFUNCTION,
+ DROPMACRO,
+ DROPROLE,
+ EXPLAIN,
+ GRANT_ROLE,
+ REVOKE_ROLE,
+ RESET,
+ SET,
+ COMMIT,
+ ROLLBACK,
+ SET_AUTOCOMMIT,
+ GET_CATALOGS,
+ GET_COLUMNS,
+ GET_FUNCTIONS,
+ GET_SCHEMAS,
+ GET_TABLES,
+ GET_TABLETYPES,
+ GET_TYPEINFO,
+ SHOWCONF,
+ SHOWFUNCTIONS,
+ SHOWLOCKS,
+ SHOW_COMPACTIONS,
+ SHOW_GRANT,
+ SHOW_ROLES,
+ SHOW_ROLE_GRANT,
+ SHOW_ROLE_PRINCIPALS,
+ SHOW_TRANSACTIONS,
+ ABORT_TRANSACTIONS,
+ START_TRANSACTION,
+ REPLDUMP,
+ REPLLOAD,
+ REPLSTATUS,
+ KILL_QUERY,
+ LLAP_CLUSTER_INFO,
+ LLAP_CACHE_PURGE;
+
+ private RangerHiveOperationType() {
+ }
+}
+
diff --git
a/hive-agent/src/test/java/org/apache/ranger/services/hive/TestAllHiveOperationInRanger.java
b/hive-agent/src/test/java/org/apache/ranger/services/hive/TestAllHiveOperationInRanger.java
new file mode 100644
index 0000000..d424bb4
--- /dev/null
+++
b/hive-agent/src/test/java/org/apache/ranger/services/hive/TestAllHiveOperationInRanger.java
@@ -0,0 +1,52 @@
+package org.apache.ranger.services.hive;
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+import
org.apache.hadoop.hive.ql.security.authorization.plugin.HiveOperationType;
+import org.junit.Test;
+
+import java.util.ArrayList;
+import java.util.List;
+
+import static org.junit.Assert.fail;
+
+public class TestAllHiveOperationInRanger{
+
+ /**
+ * test that all enums in {@link HiveOperationType} match one map entry in
+ * RangerHiveOperationType Map
+ */
+ @Test
+ public void checkHiveOperationTypeMatch() {
+
+ List<String> rangerHiveOperationList = new ArrayList<>();
+ for (RangerHiveOperationType rangerHiveOperationType :
RangerHiveOperationType.values()) {
+ String rangerOpType = rangerHiveOperationType.name();
+ rangerHiveOperationList.add(rangerOpType);
+ }
+ for (HiveOperationType operationType : HiveOperationType.values()) {
+ String hiveOperationType = operationType.name();
+ if (!rangerHiveOperationList.contains(hiveOperationType)) {
+ fail("Unable to find corresponding HiveOperationType in
RangerHiveOperation map.Please check this new operation.. "
+ + operationType);
+ }
+ }
+ assert(true);
+ }
+
+}
\ No newline at end of file
diff --git a/hive-agent/src/test/resources/hive-policies.json
b/hive-agent/src/test/resources/hive-policies.json
index 3613206..473381c 100644
--- a/hive-agent/src/test/resources/hive-policies.json
+++ b/hive-agent/src/test/resources/hive-policies.json
@@ -716,7 +716,216 @@
"id": 15,
"isEnabled": true,
"version": 2
- }
+ },
+ {
+ "service": "HIVETest",
+ "name": "Test Admin permission REPL DUMP command",
+ "policyType": 0,
+ "isAuditEnabled": true,
+ "resources": {
+ "database": {
+ "values": [
+ "rangerauthz"
+ ],
+ "isExcludes": false,
+ "isRecursive": false
+ },
+ "column": {
+ "values": [
+ "*"
+ ],
+ "isExcludes": false,
+ "isRecursive": false
+ },
+ "table": {
+ "values": [
+ "*"
+ ],
+ "isExcludes": false,
+ "isRecursive": false
+ }
+ },
+ "policyItems": [
+ {
+ "accesses": [
+ {
+ "type": "select",
+ "isAllowed": true
+ },
+ {
+ "type": "update",
+ "isAllowed": true
+ },
+ {
+ "type": "create",
+ "isAllowed": true
+ },
+ {
+ "type": "drop",
+ "isAllowed": true
+ },
+ {
+ "type": "alter",
+ "isAllowed": true
+ },
+ {
+ "type": "index",
+ "isAllowed": true
+ },
+ {
+ "type": "lock",
+ "isAllowed": true
+ },
+ {
+ "type": "repladmin",
+ "isAllowed": true
+ },
+ {
+ "type": "all",
+ "isAllowed": true
+ }
+ ],
+ "users": [
+ "da_test_user"
+ ],
+ "groups": [],
+ "conditions": [],
+ "delegateAdmin": true
+ }
+ ],
+ "denyPolicyItems": [],
+ "allowExceptions": [],
+ "denyExceptions": [],
+ "dataMaskPolicyItems": [],
+ "rowFilterPolicyItems": [],
+ "id": 16,
+ "isEnabled": true,
+ "version": 1
+ },
+ {
+ "service": "HIVETest",
+ "name": "Test KILL QUERY command",
+ "policyType": 0,
+ "isAuditEnabled": true,
+ "resources": {
+ "hiveservice": {
+ "values": [
+ "*"
+ ],
+ "isExcludes": false,
+ "isRecursive": false
+ }
+ },
+ "policyItems": [
+ {
+ "accesses": [
+ {
+ "type": "serviceadmin",
+ "isAllowed": true
+ }
+ ],
+ "users": [
+ "da_test_user"
+ ],
+ "groups": [],
+ "conditions": [],
+ "delegateAdmin": true
+ }
+ ],
+ "denyPolicyItems": [],
+ "allowExceptions": [],
+ "denyExceptions": [],
+ "dataMaskPolicyItems": [],
+ "rowFilterPolicyItems": [],
+ "id": 16,
+ "isEnabled": true,
+ "version": 1
+ },
+ {
+ "service": "HIVETest",
+ "name": "Test Admin permission REPL DUMP command on table",
+ "policyType": 0,
+ "isAuditEnabled": true,
+ "resources": {
+ "database": {
+ "values": [
+ "rangerauthz"
+ ],
+ "isExcludes": false,
+ "isRecursive": false
+ },
+ "column": {
+ "values": [
+ "*"
+ ],
+ "isExcludes": false,
+ "isRecursive": false
+ },
+ "table": {
+ "values": [
+ "words"
+ ],
+ "isExcludes": false,
+ "isRecursive": false
+ }
+ },
+ "policyItems": [
+ {
+ "accesses": [
+ {
+ "type": "select",
+ "isAllowed": true
+ },
+ {
+ "type": "update",
+ "isAllowed": true
+ },
+ {
+ "type": "create",
+ "isAllowed": true
+ },
+ {
+ "type": "drop",
+ "isAllowed": true
+ },
+ {
+ "type": "alter",
+ "isAllowed": true
+ },
+ {
+ "type": "index",
+ "isAllowed": true
+ },
+ {
+ "type": "lock",
+ "isAllowed": true
+ },
+ {
+ "type": "repladmin",
+ "isAllowed": true
+ },
+ {
+ "type": "all",
+ "isAllowed": true
+ }
+ ],
+ "users": [
+ "da_test_user"
+ ],
+ "groups": [],
+ "conditions": [],
+ "delegateAdmin": true
+ }
+ ],
+ "denyPolicyItems": [],
+ "allowExceptions": [],
+ "denyExceptions": [],
+ "dataMaskPolicyItems": [],
+ "rowFilterPolicyItems": [],
+ "id": 16,
+ "isEnabled": true,
+ "version": 1
+ }
],
"serviceDef": {
"name": "hive",
@@ -877,6 +1086,28 @@
"uiHint":"",
"label": "URL",
"description": "URL"
+ },
+ {
+ "itemId": 6,
+ "name": "hiveservice",
+ "type": "string",
+ "level": 10,
+ "mandatory": true,
+ "lookupSupported": false,
+ "recursiveSupported": false,
+ "excludesSupported": false,
+ "matcher":
"org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher",
+ "matcherOptions": {
+ "wildCard": "true",
+ "ignoreCase": "false"
+ },
+ "validationRegEx": "",
+ "validationMessage": "",
+ "uiHint": "",
+ "label": "Hive Service",
+ "description": "Hive Service",
+ "accessTypeRestrictions": [],
+ "isValidLeaf": true
}
],
"accessTypes": [
@@ -933,7 +1164,9 @@
"drop",
"alter",
"index",
- "lock"
+ "lock",
+ "repladmin",
+ "serviceadmin"
]
},
{
@@ -947,6 +1180,18 @@
"name": "write",
"label": "Write",
"impliedGrants": []
+ },
+ {
+ "itemId": 11,
+ "name": "repladmin",
+ "label": "ReplAdmin",
+ "impliedGrants": []
+ },
+ {
+ "itemId": 12,
+ "name": "serviceadmin",
+ "label": "Service Admin",
+ "impliedGrants": []
}
],
"policyConditions": [],
diff --git
a/security-admin/src/main/java/org/apache/ranger/common/AppConstants.java
b/security-admin/src/main/java/org/apache/ranger/common/AppConstants.java
index 09ed06a..d28f3de 100644
--- a/security-admin/src/main/java/org/apache/ranger/common/AppConstants.java
+++ b/security-admin/src/main/java/org/apache/ranger/common/AppConstants.java
@@ -343,11 +343,19 @@ public class AppConstants extends RangerCommonEnums {
* XA_PERM_TYPE_UPLOAD_NEW_CREDENTIAL is an element of enum XAPermType.
Its value is "XA_PERM_TYPE_UPLOAD_NEW_CREDENTIAL".
*/
public static final int XA_PERM_TYPE_UPLOAD_NEW_CREDENTIAL = 31;
+ /**
+ * XA_PERM_TYPE_REPLADMIN is an element of enum XAPermType. Its value is
"XA_PERM_TYPE_REPLADMIN".
+ */
+ public static final int XA_PERM_TYPE_REPLADMIN = 32;
+ /**
+ * XA_PERM_TYPE_SERVICEADMIN is an element of enum XAPermType. Its
value is "XA_PERM_TYPE_HIVE_SERVICE".
+ */
+ public static final int XA_PERM_TYPE_SERVICEADMIN = 33;
/**
* Max value for enum XAPermType_MAX
*/
- public static final int XAPermType_MAX = 31;
+ public static final int XAPermType_MAX = 33;
/***************************************************************
* Enum values for DatabaseFavor
@@ -861,6 +869,14 @@ public class AppConstants extends RangerCommonEnums {
// return "Upload New Credential";
//XA_PERM_TYPE_UPLOAD_NEW_CREDENTIAL
return "uploadNewCredentials";
}
+ if( elementValue == 32 ) {
+ // return "Repl Admin"; //XA_PERM_TYPE_REPL_ADMIN
+ return "repladmin";
+ }
+ if( elementValue == 33 ) {
+ // return "serviceadmin"; //XA_PERM_TYPE_SERVICEADMIN
+ return "serviceadmin";
+ }
return null;
}
@@ -1168,6 +1184,13 @@ public class AppConstants extends RangerCommonEnums {
if("uploadNewCredentials".equalsIgnoreCase(label)) {
return AppConstants.XA_PERM_TYPE_UPLOAD_NEW_CREDENTIAL;
//XA_PERM_TYPE_UPLOAD_NEW_CREDENTIAL
}
+ if(label.equalsIgnoreCase("repladmin")) {
+ return AppConstants.XA_PERM_TYPE_REPLADMIN;
//XA_PERM_TYPE_REPLADMIN
+ }
+ if(label.equalsIgnoreCase("serviceadmin")) {
+ return AppConstants.XA_PERM_TYPE_SERVICEADMIN;
//XA_PERM_TYPE_SERVICEADMIN
+ }
+
return 0;
}
diff --git
a/security-admin/src/main/java/org/apache/ranger/common/ServiceUtil.java
b/security-admin/src/main/java/org/apache/ranger/common/ServiceUtil.java
index c82636a..1afe20e 100644
--- a/security-admin/src/main/java/org/apache/ranger/common/ServiceUtil.java
+++ b/security-admin/src/main/java/org/apache/ranger/common/ServiceUtil.java
@@ -126,6 +126,8 @@ public class ServiceUtil {
mapAccessTypeToPermType.put("getUserTopology", 29);
mapAccessTypeToPermType.put("getTopologyInfo", 30);
mapAccessTypeToPermType.put("uploadNewCredentials", 31);
+ mapAccessTypeToPermType.put("repladmin",32);
+ mapAccessTypeToPermType.put("serviceadmin",33);
version = "0";
}
@@ -245,6 +247,7 @@ public class ServiceUtil {
toRangerResourceList(resource.getUdfs(), "udf", Boolean.FALSE,
Boolean.FALSE, ret.getResources());
toRangerResourceList(resource.getTopologies(), "topology",
Boolean.FALSE, Boolean.FALSE, ret.getResources());
toRangerResourceList(resource.getServices(), "service",
Boolean.FALSE, Boolean.FALSE, ret.getResources());
+ toRangerResourceList(resource.getHiveServices(), "hiveservice",
Boolean.FALSE, Boolean.FALSE, ret.getResources());
HashMap<String, List<VXPermMap>> sortedPermMap = new
HashMap<String, List<VXPermMap>>();
@@ -371,6 +374,8 @@ public class ServiceUtil {
ret.setTopologies(resString);
} else if("service".equalsIgnoreCase(resType)) {
ret.setServices(resString);
+ } else if(resType.equalsIgnoreCase("hiveservice")) {
+ ret.setHiveServices(resString);
}
}
updateResourceName(ret);
@@ -833,6 +838,8 @@ public class ServiceUtil {
ret.setTopologies(resString);
} else if("service".equalsIgnoreCase(resType)) {
ret.setServices(resString);
+ } else if(resType.equalsIgnoreCase("hiveservice")) {
+ ret.setHiveServices(resString);
}
}
updateResourceName(ret);
@@ -1057,7 +1064,11 @@ public class ServiceUtil {
if (vXPolicy.getServices() != null) {
toRangerResourceList(vXPolicy.getServices(), "service",
Boolean.FALSE, isRecursive, ret.getResources());
}
-
+
+ if (vXPolicy.getHiveServices() != null) {
+ toRangerResourceList(vXPolicy.getHiveServices(),
"hiveservice", Boolean.FALSE, isRecursive, ret.getResources());
+ }
+
if ( vXPolicy.getPermMapList() != null) {
List<VXPermObj> vXPermObjList =
vXPolicy.getPermMapList();
diff --git
a/security-admin/src/main/java/org/apache/ranger/patch/PatchForHiveServiceDefUpdate_J10009.java
b/security-admin/src/main/java/org/apache/ranger/patch/PatchForHiveServiceDefUpdate_J10009.java
new file mode 100644
index 0000000..3e5d1f9
--- /dev/null
+++
b/security-admin/src/main/java/org/apache/ranger/patch/PatchForHiveServiceDefUpdate_J10009.java
@@ -0,0 +1,226 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ranger.patch;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.apache.ranger.biz.RangerBizUtil;
+import org.apache.ranger.biz.ServiceDBStore;
+import org.apache.ranger.common.JSONUtil;
+import org.apache.ranger.common.RangerValidatorFactory;
+import org.apache.ranger.common.StringUtil;
+import org.apache.ranger.db.RangerDaoManager;
+import org.apache.ranger.entity.XXServiceDef;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.validation.RangerServiceDefValidator;
+import org.apache.ranger.plugin.model.validation.RangerValidator.Action;
+import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
+import org.apache.ranger.service.RangerPolicyService;
+import org.apache.ranger.service.XPermMapService;
+import org.apache.ranger.service.XPolicyService;
+import org.apache.ranger.util.CLIUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+@Component
+public class PatchForHiveServiceDefUpdate_J10009 extends BaseLoader {
+ private static final Logger logger =
Logger.getLogger(PatchForHiveServiceDefUpdate_J10009.class);
+ public static final String SERVICEDBSTORE_SERVICEDEFBYNAME_HIVE_NAME =
"hive";
+ public static final String URL_RESOURCE_NAME ="url";
+
+ @Autowired
+ RangerDaoManager daoMgr;
+
+ @Autowired
+ ServiceDBStore svcDBStore;
+
+ @Autowired
+ JSONUtil jsonUtil;
+
+ @Autowired
+ RangerPolicyService policyService;
+
+ @Autowired
+ StringUtil stringUtil;
+
+ @Autowired
+ XPolicyService xPolService;
+
+ @Autowired
+ XPermMapService xPermMapService;
+
+ @Autowired
+ RangerBizUtil bizUtil;
+
+ @Autowired
+ RangerValidatorFactory validatorFactory;
+
+ @Autowired
+ ServiceDBStore svcStore;
+
+ public static void main(String[] args) {
+ logger.info("main()");
+ try {
+ PatchForHiveServiceDefUpdate_J10009 loader =
(PatchForHiveServiceDefUpdate_J10009)
CLIUtil.getBean(PatchForHiveServiceDefUpdate_J10009.class);
+ loader.init();
+ while (loader.isMoreToProcess()) {
+ loader.load();
+ }
+ logger.info("Load complete. Exiting!!!");
+ System.exit(0);
+ } catch (Exception e) {
+ logger.error("Error loading", e);
+ System.exit(1);
+ }
+ }
+
+ @Override
+ public void init() throws Exception {
+ // Do Nothing
+ }
+
+ @Override
+ public void execLoad() {
+ logger.info("==> PatchForHiveServiceDefUpdate.execLoad()");
+ try {
+ updateHiveServiceDef();
+ } catch (Exception e) {
+ logger.error("Error whille
updateHiveServiceDef()data.", e);
+ }
+ logger.info("<== PatchForHiveServiceDefUpdate.execLoad()");
+ }
+
+ @Override
+ public void printStats() {
+ logger.info("PatchForHiveServiceDefUpdate data ");
+ }
+
+ private void updateHiveServiceDef(){
+ RangerServiceDef ret = null;
+ RangerServiceDef embeddedHiveServiceDef = null;
+ RangerServiceDef dbHiveServiceDef = null;
+ List<RangerServiceDef.RangerAccessTypeDef>
embeddedHiveAccessTypes = null;
+ XXServiceDef xXServiceDefObj = null;
+ try{
+
embeddedHiveServiceDef=EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(SERVICEDBSTORE_SERVICEDEFBYNAME_HIVE_NAME);
+ if(embeddedHiveServiceDef!=null){
+
+ xXServiceDefObj =
daoMgr.getXXServiceDef().findByName(SERVICEDBSTORE_SERVICEDEFBYNAME_HIVE_NAME);
+ Map<String, String>
serviceDefOptionsPreUpdate=null;
+ String jsonStrPreUpdate=null;
+ if(xXServiceDefObj!=null) {
+
jsonStrPreUpdate=xXServiceDefObj.getDefOptions();
+
serviceDefOptionsPreUpdate=jsonStringToMap(jsonStrPreUpdate);
+ xXServiceDefObj=null;
+ }
+
dbHiveServiceDef=svcDBStore.getServiceDefByName(SERVICEDBSTORE_SERVICEDEFBYNAME_HIVE_NAME);
+
+ if(dbHiveServiceDef!=null){
+ embeddedHiveAccessTypes =
embeddedHiveServiceDef.getAccessTypes();
+ if
(checkHiveAccessType(embeddedHiveAccessTypes)) {
+ // This is to check if
HiveServiceDef AccessType has the new AccessType and if Present update the
dbHiveServiceDef along with new Admin accessType.
+
dbHiveServiceDef.setAccessTypes(embeddedHiveAccessTypes);
+ }
+
+ RangerServiceDefValidator validator =
validatorFactory.getServiceDefValidator(svcStore);
+ validator.validate(dbHiveServiceDef,
Action.UPDATE);
+
+ ret =
svcStore.updateServiceDef(dbHiveServiceDef);
+ if(ret==null){
+ logger.error("Error while
updating "+SERVICEDBSTORE_SERVICEDEFBYNAME_HIVE_NAME+"service-def");
+ throw new
RuntimeException("Error while updating
"+SERVICEDBSTORE_SERVICEDEFBYNAME_HIVE_NAME+"service-def");
+ }
+ xXServiceDefObj =
daoMgr.getXXServiceDef().findByName(SERVICEDBSTORE_SERVICEDEFBYNAME_HIVE_NAME);
+ if(xXServiceDefObj!=null) {
+ String
jsonStrPostUpdate=xXServiceDefObj.getDefOptions();
+ Map<String, String>
serviceDefOptionsPostUpdate=jsonStringToMap(jsonStrPostUpdate);
+ if (serviceDefOptionsPostUpdate
!= null &&
serviceDefOptionsPostUpdate.containsKey(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES))
{
+
if(serviceDefOptionsPreUpdate == null ||
!serviceDefOptionsPreUpdate.containsKey(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES))
{
+ String
preUpdateValue = serviceDefOptionsPreUpdate == null ? null :
serviceDefOptionsPreUpdate.get(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES);
+ if
(preUpdateValue == null) {
+
serviceDefOptionsPostUpdate.remove(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES);
+ } else {
+
serviceDefOptionsPostUpdate.put(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES,
preUpdateValue);
+ }
+
xXServiceDefObj.setDefOptions(mapToJsonString(serviceDefOptionsPostUpdate));
+
daoMgr.getXXServiceDef().update(xXServiceDefObj);
+ }
+ }
+ }
+ }
+ }
+ }catch(Exception e)
+ {
+ logger.error("Error while updating
"+SERVICEDBSTORE_SERVICEDEFBYNAME_HIVE_NAME+"service-def", e);
+ }
+ }
+
+ private boolean
checkHiveAccessType(List<RangerServiceDef.RangerAccessTypeDef>
embeddedHiveAccessTypes) {
+ boolean ret = false;
+ for (RangerServiceDef.RangerAccessTypeDef
embeddedHiveAccessType : embeddedHiveAccessTypes) {
+ if (
embeddedHiveAccessType.getName().equals("repladmin") ) {
+ ret = true;
+ break;
+ }
+ }
+ return ret;
+ }
+
+ private String mapToJsonString(Map<String, String> map) {
+ String ret = null;
+ if(map != null) {
+ try {
+ ret = jsonUtil.readMapToString(map);
+ } catch(Exception excp) {
+ logger.warn("mapToJsonString() failed to
convert map: " + map, excp);
+ }
+ }
+ return ret;
+ }
+
+ protected Map<String, String> jsonStringToMap(String jsonStr) {
+ Map<String, String> ret = null;
+ if(!StringUtils.isEmpty(jsonStr)) {
+ try {
+ ret = jsonUtil.jsonToMap(jsonStr);
+ } catch(Exception excp) {
+ // fallback to earlier format:
"name1=value1;name2=value2"
+ for(String optionString : jsonStr.split(";")) {
+ if(StringUtils.isEmpty(optionString)) {
+ continue;
+ }
+ String[] nvArr =
optionString.split("=");
+ String name = (nvArr != null &&
nvArr.length > 0) ? nvArr[0].trim() : null;
+ String value = (nvArr != null &&
nvArr.length > 1) ? nvArr[1].trim() : null;
+ if(StringUtils.isEmpty(name)) {
+ continue;
+ }
+ if(ret == null) {
+ ret = new HashMap<String,
String>();
+ }
+ ret.put(name, value);
+ }
+ }
+ }
+ return ret;
+ }
+}
\ No newline at end of file
diff --git
a/security-admin/src/main/java/org/apache/ranger/patch/PatchForHiveServiceDefUpdate_J10010.java
b/security-admin/src/main/java/org/apache/ranger/patch/PatchForHiveServiceDefUpdate_J10010.java
new file mode 100644
index 0000000..bd9e2f8
--- /dev/null
+++
b/security-admin/src/main/java/org/apache/ranger/patch/PatchForHiveServiceDefUpdate_J10010.java
@@ -0,0 +1,213 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership.
+ * The ASF licenses this file to You under the Apache License, Version 2.0
+ * (the "License"); you may not use this file except in compliance with
+ * the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.apache.ranger.patch;
+
+import org.apache.commons.lang.StringUtils;
+import org.apache.log4j.Logger;
+import org.apache.ranger.biz.RangerBizUtil;
+import org.apache.ranger.biz.ServiceDBStore;
+import org.apache.ranger.common.JSONUtil;
+import org.apache.ranger.common.RangerValidatorFactory;
+import org.apache.ranger.common.StringUtil;
+import org.apache.ranger.db.RangerDaoManager;
+import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.model.validation.RangerServiceDefValidator;
+import org.apache.ranger.plugin.model.validation.RangerValidator.Action;
+import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
+import org.apache.ranger.service.RangerPolicyService;
+import org.apache.ranger.service.XPermMapService;
+import org.apache.ranger.service.XPolicyService;
+import org.apache.ranger.util.CLIUtil;
+import org.springframework.beans.factory.annotation.Autowired;
+import org.springframework.stereotype.Component;
+import org.apache.ranger.entity.XXServiceDef;
+
+import java.util.List;
+import java.util.Map;
+
+@Component
+public class PatchForHiveServiceDefUpdate_J10010 extends BaseLoader {
+ private static final Logger logger =
Logger.getLogger(PatchForHiveServiceDefUpdate_J10010.class);
+ public static final String SERVICEDBSTORE_SERVICEDEFBYNAME_HIVE_NAME =
"hive";
+ public static final String HIVE_SERVICE_RESOURCE_NAME ="hiveservice";
+
+ @Autowired
+ RangerDaoManager daoMgr;
+
+ @Autowired
+ ServiceDBStore svcDBStore;
+
+ @Autowired
+ JSONUtil jsonUtil;
+
+ @Autowired
+ RangerPolicyService policyService;
+
+ @Autowired
+ StringUtil stringUtil;
+
+ @Autowired
+ XPolicyService xPolService;
+
+ @Autowired
+ XPermMapService xPermMapService;
+
+ @Autowired
+ RangerBizUtil bizUtil;
+
+ @Autowired
+ RangerValidatorFactory validatorFactory;
+
+ @Autowired
+ ServiceDBStore svcStore;
+
+ public static void main(String[] args) {
+ logger.info("main()");
+ try {
+ PatchForHiveServiceDefUpdate_J10010 loader =
(PatchForHiveServiceDefUpdate_J10010)
CLIUtil.getBean(PatchForHiveServiceDefUpdate_J10010.class);
+ loader.init();
+ while (loader.isMoreToProcess()) {
+ loader.load();
+ }
+ logger.info("Load complete. Exiting!!!");
+ System.exit(0);
+ } catch (Exception e) {
+ logger.error("Error loading", e);
+ System.exit(1);
+ }
+ }
+
+ @Override
+ public void init() throws Exception {
+ // Do Nothing
+ }
+
+ @Override
+ public void execLoad() {
+ logger.info("==>
PatchForHiveServiceDefUpdateForResourceSpecificAccesses.execLoad()");
+ try {
+ updateHiveServiceDef();
+ } catch (Exception e) {
+ logger.error("Error whille
updateHiveServiceDef()data.", e);
+ }
+ logger.info("<==
PatchForHiveServiceDefUpdateForResourceSpecificAccesses.execLoad()");
+ }
+
+ @Override
+ public void printStats() {
+
logger.info("PatchForHiveServiceDefUpdateForResourceSpecificAccesses data ");
+ }
+
+ private void updateHiveServiceDef(){
+ RangerServiceDef embeddedHiveServiceDef = null;
+ RangerServiceDef dbHiveServiceDef = null;
+ XXServiceDef xXServiceDefObj = null;
+ try{
+ embeddedHiveServiceDef =
EmbeddedServiceDefsUtil.instance().getEmbeddedServiceDef(SERVICEDBSTORE_SERVICEDEFBYNAME_HIVE_NAME);
+
+ if (embeddedHiveServiceDef != null) {
+ xXServiceDefObj =
daoMgr.getXXServiceDef().findByName(SERVICEDBSTORE_SERVICEDEFBYNAME_HIVE_NAME);
+ if (xXServiceDefObj == null) {
+ logger.error("Service def for " +
SERVICEDBSTORE_SERVICEDEFBYNAME_HIVE_NAME + " is not found!!");
+ return;
+ }
+
+ String jsonStrPreUpdate =
xXServiceDefObj.getDefOptions();
+ Map<String, String> serviceDefOptionsPreUpdate
= jsonUtil.jsonToMap(jsonStrPreUpdate);
+ String valueBeforeUpdate =
serviceDefOptionsPreUpdate.get(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES);
+
+ dbHiveServiceDef =
svcDBStore.getServiceDefByName(SERVICEDBSTORE_SERVICEDEFBYNAME_HIVE_NAME);
+
+ if(dbHiveServiceDef != null) {
+ boolean isServiceDefUpdated =
updateServiceDef(dbHiveServiceDef, embeddedHiveServiceDef);
+
+ if (isServiceDefUpdated) {
+ xXServiceDefObj =
daoMgr.getXXServiceDef().findByName(SERVICEDBSTORE_SERVICEDEFBYNAME_HIVE_NAME);
+
+ if (xXServiceDefObj != null) {
+ String
jsonStrPostUpdate = xXServiceDefObj.getDefOptions();
+ Map<String, String>
serviceDefOptionsPostUpdate = jsonUtil.jsonToMap(jsonStrPostUpdate);
+ String valueAfterUpdate
=
serviceDefOptionsPostUpdate.get(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES);
+
+ if
(!StringUtils.equals(valueBeforeUpdate, valueAfterUpdate)) {
+ if
(StringUtils.isEmpty(valueBeforeUpdate)) {
+
serviceDefOptionsPostUpdate.remove(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES);
+ } else {
+
serviceDefOptionsPostUpdate.put(RangerServiceDef.OPTION_ENABLE_DENY_AND_EXCEPTIONS_IN_POLICIES,
valueBeforeUpdate);
+ }
+
xXServiceDefObj.setDefOptions(mapToJsonString(serviceDefOptionsPostUpdate));
+
daoMgr.getXXServiceDef().update(xXServiceDefObj);
+ }
+ }
+ }
+ }
+ }
+ } catch(Exception e) {
+ logger.error("Error while updating
"+SERVICEDBSTORE_SERVICEDEFBYNAME_HIVE_NAME+"service-def", e);
+ }
+ }
+
+ private boolean updateServiceDef(RangerServiceDef serviceDef,
RangerServiceDef embeddedHiveServiceDef ) throws Exception {
+ boolean ret = false;
+
+ List<RangerServiceDef.RangerResourceDef>
embeddedHiveResourceDefs = null;
+ List<RangerServiceDef.RangerAccessTypeDef>
embeddedHiveAccessTypes = null;
+
+ embeddedHiveResourceDefs =
embeddedHiveServiceDef.getResources();
+ embeddedHiveAccessTypes =
embeddedHiveServiceDef.getAccessTypes();
+
+ if (checkHiveServiceresourcePresent(embeddedHiveResourceDefs)) {
+ // This is to check if HIVESERVICE def is added to the
resource definition, if so update the resource def and accessType def
+ if (embeddedHiveResourceDefs != null) {
+
serviceDef.setResources(embeddedHiveResourceDefs);
+ }
+ if (embeddedHiveAccessTypes != null) {
+
if(!embeddedHiveAccessTypes.toString().equalsIgnoreCase(serviceDef.getAccessTypes().toString()))
{
+
serviceDef.setAccessTypes(embeddedHiveAccessTypes);
+ }
+ }
+ ret = true;
+ }
+
+ RangerServiceDefValidator validator =
validatorFactory.getServiceDefValidator(svcStore);
+ validator.validate(serviceDef, Action.UPDATE);
+ svcStore.updateServiceDef(serviceDef);
+
+ return ret;
+ }
+
+ private boolean
checkHiveServiceresourcePresent(List<RangerServiceDef.RangerResourceDef>
resourceDefs) {
+ boolean ret = false;
+ for(RangerServiceDef.RangerResourceDef resourceDef :
resourceDefs) {
+ if
(HIVE_SERVICE_RESOURCE_NAME.equals(resourceDef.getName()) ) {
+ ret = true ;
+ break;
+ }
+ }
+ return ret;
+ }
+
+ private String mapToJsonString(Map<String, String> map) throws
Exception {
+ String ret = null;
+ if(map != null) {
+ ret = jsonUtil.readMapToString(map);
+ }
+ return ret;
+ }
+}
+
diff --git a/security-admin/src/main/java/org/apache/ranger/view/VXPolicy.java
b/security-admin/src/main/java/org/apache/ranger/view/VXPolicy.java
index da7082d..df9b9c3 100644
--- a/security-admin/src/main/java/org/apache/ranger/view/VXPolicy.java
+++ b/security-admin/src/main/java/org/apache/ranger/view/VXPolicy.java
@@ -102,6 +102,11 @@ public class VXPolicy extends VXDataObject implements
java.io.Serializable {
*/
protected String services;
/**
+ * Hive Services
+ */
+ protected String hiveservices;
+
+ /**
* Resource/Policy Status, boolean values : true/false
*
*/
@@ -433,6 +438,26 @@ public class VXPolicy extends VXDataObject implements
java.io.Serializable {
}
/**
+ * Returns the value for the member attribute <b>hiveservices</b>
+ *
+ * @return String - value of member attribute <b>hiveservices</b>.
+ */
+ public String getHiveServices() {
+ return hiveservices;
+ }
+
+ /**
+ * This method sets the value to the member attribute
<b>hiveservices</b>. You
+ * cannot set null to the attribute.
+ *
+ * @param hiveservices
+ * Value to set member attribute <b>hiveservices</b>
+ */
+ public void setHiveServices(String hiveservices) {
+ this.hiveservices = hiveservices;
+ }
+
+ /**
* This method sets the value to the member attribute
<b>resourceStatus</b>.
* You cannot set null to the attribute.
*
diff --git
a/security-admin/src/main/java/org/apache/ranger/view/VXResource.java
b/security-admin/src/main/java/org/apache/ranger/view/VXResource.java
index 8ce0ebe..a1420b9 100644
--- a/security-admin/src/main/java/org/apache/ranger/view/VXResource.java
+++ b/security-admin/src/main/java/org/apache/ranger/view/VXResource.java
@@ -146,6 +146,11 @@ public class VXResource extends VXDataObject implements
java.io.Serializable {
protected String services;
/**
+ * Hive Services
+ */
+ protected String hiveServices;
+
+ /**
* guid
*/
protected String guid;
@@ -565,6 +570,27 @@ public class VXResource extends VXDataObject implements
java.io.Serializable {
this.services = services;
}
+
+ /**
+ * This method sets the value to the member attribute
<b>hiveservices</b>. You
+ * cannot set null to the attribute.
+ *
+ * @param hiveServices
+ * Value to set member attribute <b>hiveservices</b>
+ */
+ public void setHiveServices(String hiveServices) {
+ this.hiveServices = hiveServices;
+ }
+
+ /**
+ * Returns the value for the member attribute <b>hiveservices</b>
+ *
+ * @return String - value of member attribute <b>hiveservices</b>.
+ */
+ public String getHiveServices() {
+ return hiveServices;
+ }
+
/**
* This method sets the value to the member attribute
<b>checkParentPermission</b>.
* You cannot set null to the attribute.