You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@ranger.apache.org by rm...@apache.org on 2019/08/16 08:10:56 UTC

[ranger] branch master updated: RANGER-2536:Ranger Hive authorizer enhancement to enable Hive policies based on resource owners

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 35bc9c9  RANGER-2536:Ranger Hive authorizer enhancement to enable Hive policies based on resource owners
35bc9c9 is described below

commit 35bc9c935441b0680fe464c1f3df361c3551a5ca
Author: rmani <rm...@hortonworks.com>
AuthorDate: Fri Aug 16 01:10:40 2019 -0700

    RANGER-2536:Ranger Hive authorizer enhancement to enable Hive policies based on resource owners
---
 .../ranger/plugin/util/GrantRevokeRequest.java     |  23 +++
 .../service-defs/ranger-servicedef-hive.json       |   6 +-
 .../plugin/policyengine/TestPolicyEngine.java      |   7 +
 .../test_policyengine_hive_default_policies.json   | 187 +++++++++++++++++++++
 .../hive/authorizer/RangerHiveAuthorizer.java      |  80 ++++++++-
 .../ranger/services/hive/RangerServiceHive.java    |  83 ++++++++-
 pom.xml                                            |   2 +-
 .../java/org/apache/ranger/rest/ServiceREST.java   |  12 +-
 8 files changed, 380 insertions(+), 20 deletions(-)

diff --git a/agents-common/src/main/java/org/apache/ranger/plugin/util/GrantRevokeRequest.java b/agents-common/src/main/java/org/apache/ranger/plugin/util/GrantRevokeRequest.java
index 2795906..870ec96 100644
--- a/agents-common/src/main/java/org/apache/ranger/plugin/util/GrantRevokeRequest.java
+++ b/agents-common/src/main/java/org/apache/ranger/plugin/util/GrantRevokeRequest.java
@@ -60,6 +60,7 @@ public class GrantRevokeRequest implements Serializable {
 	private String              sessionId;
 	private String              clusterName;
 	private String              zoneName;
+	private String 				ownerUser;
 
 	public GrantRevokeRequest() {
 		this(null, null, null, null, null, null, null, null, null, null, null, null, null, null, null, null);
@@ -76,6 +77,13 @@ public class GrantRevokeRequest implements Serializable {
 							  Set<String> groups, Set<String> roles, Set<String> accessTypes, Boolean delegateAdmin, Boolean enableAudit,
 							  Boolean replaceExistingPermissions, Boolean isRecursive, String clientIPAddress,
 							  String clientType, String requestData, String sessionId, String clusterName, String zoneName) {
+		this(grantor, grantorGroups, resource, users, groups, roles, accessTypes, delegateAdmin, enableAudit, replaceExistingPermissions, isRecursive, clientIPAddress, clientType, requestData, sessionId, clusterName, zoneName, null);
+	}
+
+	public GrantRevokeRequest(String grantor, Set<String> grantorGroups, Map<String, String> resource, Set<String> users,
+							  Set<String> groups, Set<String> roles, Set<String> accessTypes, Boolean delegateAdmin, Boolean enableAudit,
+							  Boolean replaceExistingPermissions, Boolean isRecursive, String clientIPAddress,
+							  String clientType, String requestData, String sessionId, String clusterName, String zoneName, String ownerUser) {
 		setGrantor(grantor);
 		setGrantorGroups(grantorGroups);
 		setResource(resource);
@@ -93,6 +101,7 @@ public class GrantRevokeRequest implements Serializable {
 		setSessionId(sessionId);
 		setClusterName(clusterName);
 		setZoneName(zoneName);
+		setOwnerUser(ownerUser);
 	}
 
 	/**
@@ -222,6 +231,20 @@ public class GrantRevokeRequest implements Serializable {
 	}
 
 	/**
+	 * @return the ownerUser
+	 */
+	public String getOwnerUser() {
+		return ownerUser;
+	}
+
+	/**
+	 * @param ownerUser the ownerUser to set
+	 */
+	public void setOwnerUser(String ownerUser) {
+		this.ownerUser = ownerUser;
+	}
+
+	/**
 	 * @return the replaceExistingPermissions
 	 */
 	public Boolean getReplaceExistingPermissions() {
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 7408cbc..5722e09 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
@@ -23,7 +23,8 @@
 			"validationMessage": "",
 			"uiHint":"",
 			"label": "Hive Database",
-			"description": "Hive Database"
+			"description": "Hive Database",
+			"isValidLeaf": true
 		},
 
 		{
@@ -42,7 +43,8 @@
 			"validationMessage": "",
 			"uiHint":"",
 			"label": "Hive Table",
-			"description": "Hive Table"
+			"description": "Hive Table",
+			"isValidLeaf": true
 		},
 
 		{
diff --git a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
index d1e0c23..7180675 100644
--- a/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
+++ b/agents-common/src/test/java/org/apache/ranger/plugin/policyengine/TestPolicyEngine.java
@@ -383,6 +383,13 @@ public class TestPolicyEngine {
 		runTestsFromResourceFiles(conditionsTestResourceFiles);
 	}
 
+	@Test
+	public void testPolicyEngine_with_owner() {
+		String[] conditionsTestResourceFiles = { "/policyengine/test_policyengine_hive_default_policies.json" };
+
+		runTestsFromResourceFiles(conditionsTestResourceFiles);
+	}
+
 	private void runTestsFromResourceFiles(String[] resourceNames) {
 		for(String resourceName : resourceNames) {
 			InputStream inStream = this.getClass().getResourceAsStream(resourceName);
diff --git a/agents-common/src/test/resources/policyengine/test_policyengine_hive_default_policies.json b/agents-common/src/test/resources/policyengine/test_policyengine_hive_default_policies.json
new file mode 100644
index 0000000..aec8a75
--- /dev/null
+++ b/agents-common/src/test/resources/policyengine/test_policyengine_hive_default_policies.json
@@ -0,0 +1,187 @@
+{
+  "serviceName":"hivedev",
+
+  "original-serviceDef":{
+    "name":"hive",
+    "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"}
+    ],
+    "accessTypes":[
+      {"name":"select","label":"Select"},
+      {"name":"update","label":"Update"},
+      {"name":"create","label":"Create"},
+      {"name":"drop","label":"Drop"},
+      {"name":"alter","label":"Alter"},
+      {"name":"index","label":"Index"},
+      {"name":"lock","label":"Lock"},
+      {"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"]
+      }
+    ]
+  },
+
+  "serviceDef": {
+    "id":3,
+    "name": "hive",
+    "implClass": "org.apache.ranger.services.hive.RangerServiceHive",
+    "label": "Hive Server2",
+    "description": "Hive Server2",
+    "guid": "3e1afb5a-184a-4e82-9d9c-87a5cacc243c",
+
+    "resources": [
+      {"itemId": 1, "name": "database", "type": "string", "level": 10, "parent": "", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard":true, "ignoreCase":true }, "validationRegEx":"", "validationMessage": "", "uiHint":"", "label": "Hive Database", "description": "Hive Database", "isValidLeaf": true},
+      {"itemId": 2, "name": "table", "type": "string", "level": 20, "parent": "database", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard":true, "ignoreCase":true }, "validationRegEx":"", "validationMessage": "", "uiHint":"", "label": "Hive Table", "description": "Hive Table", "isValidLeaf": true},
+      {"itemId": 3, "name": "udf", "type": "string", "level": 20, "parent": "database", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard":true, "ignoreCase":true }, "validationRegEx":"", "validationMessage": "", "uiHint":"", "label": "Hive UDF", "description": "Hive UDF", "isValidLeaf": true},
+      {"itemId": 4, "name": "column", "type": "string", "level": 30, "parent": "table", "mandatory": true, "lookupSupported": true, "recursiveSupported": false, "excludesSupported": true, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerDefaultResourceMatcher", "matcherOptions": { "wildCard":true, "ignoreCase":true }, "validationRegEx":"", "validationMessage": "", "uiHint":"", "label": "Hive Column", "description": "Hive Column", "isValidLeaf": true},
+      {"itemId": 5, "name": "url", "type": "string", "level": 10, "parent": "", "mandatory": true, "lookupSupported": false, "recursiveSupported": true, "excludesSupported": false, "matcher": "org.apache.ranger.plugin.resourcematcher.RangerPathResourceMatcher", "matcherOptions": { "wildCard":true, "ignoreCase":false }, "validationRegEx":"", "validationMessage": "", "uiHint":"", "label": "URL", "description": "URL", "isValidLeaf": true}
+    ],
+
+    "accessTypes": [
+      {"itemId": 1, "name": "select", "label": "select"},
+      {"itemId": 2, "name": "update", "label": "update"},
+      {"itemId": 3, "name": "create", "label": "Create"},
+      {"itemId": 4, "name": "drop", "label": "Drop"},
+      {"itemId": 5, "name": "alter", "label": "Alter"},
+      {"itemId": 6, "name": "index", "label": "Index"},
+      {"itemId": 7, "name": "lock", "label": "Lock"},
+      {"itemId": 8, "name": "all", "label": "All",
+        "impliedGrants": ["select", "update", "create", "drop", "alter", "index", "lock", "read", "write"]},
+      {"itemId": 9, "name": "read", "label": "Read"},
+      {"itemId": 10, "name": "write", "label": "Write"}
+    ],
+
+    "configs": [
+      {"itemId": 1, "name": "username", "type": "string", "mandatory": true, "validationRegEx":"", "validationMessage": "", "uiHint":"", "label": "Username"},
+      {"itemId": 2, "name": "password", "type": "password", "mandatory": true, "validationRegEx":"", "validationMessage": "", "uiHint":"", "label": "Password"},
+      {"itemId": 3, "name": "jdbc.driverClassName", "type": "string", "mandatory": true, "validationRegEx":"", "validationMessage": "", "uiHint":"", "defaultValue": "org.apache.hive.jdbc.HiveDriver"},
+      {"itemId": 4, "name": "jdbc.url", "type": "string", "mandatory": true, "defaultValue": "", "validationRegEx":"", "validationMessage": "", "uiHint":""},
+      {"itemId": 5, "name": "commonNameForCertificate", "type": "string", "mandatory": false, "validationRegEx":"", "validationMessage": "", "uiHint":"", "label": "Common Name for Certificate"}
+    ],
+
+    "enums": [
+    ],
+
+    "contextEnrichers": [
+      {"itemId":1, "name" : "GeolocationEnricher_format_long", "enricher" : "org.apache.ranger.plugin.contextenricher.RangerFileBasedGeolocationProvider", "enricherOptions" : {"FilePath":"/etc/ranger/geo/geo_long.txt", "ForceRead":"false", "IPInDotFormat":"false","geolocation.meta.prefix": "FORMAT_LONG_"}},
+      {"itemId":2, "name" : "GeolocationEnricher_format_dot", "enricher" : "org.apache.ranger.plugin.contextenricher.RangerFileBasedGeolocationProvider", "enricherOptions" : {"FilePath":"/etc/ranger/geo/geo.txt", "ForceRead":"false", "IPInDotFormat":"true","geolocation.meta.prefix": "FORMAT_DOT_"}}
+    ],
+
+    "policyConditions": [
+      {"itemId":1, "name":"ScriptConditionEvaluator", "evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerScriptConditionEvaluator", "evaluatorOptions" : {"engineName":"JavaScript"}, "label":"Script", "description": "Script to execute"},
+      { "itemId": 2, "name":"country", "evaluator":"org.apache.ranger.plugin.conditionevaluator.RangerSimpleMatcher", "evaluatorOptions":{"CONTEXT_NAME":"country"}},
+      {"itemId":3, "name":"not-accessed-together", "evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerHiveResourcesNotAccessedTogetherCondition", "evaluatorOptions" : {}, "label":"Not Accessed Together?", "description": "List of Hive resources"},
+      {"itemId":4, "name":"accessed-together", "evaluator": "org.apache.ranger.plugin.conditionevaluator.RangerHiveResourcesAccessedTogetherCondition", "evaluatorOptions" : {"ui.isMultiline":"false" }, "label":"Accessed Together?", "description": "List of Hive resources"}
+    ],
+
+    "dataMaskDef": {
+      "accessTypes": [
+        {"name": "select"}
+      ],
+      "resources": [
+        {"itemId": 1, "name": "database", "type": "string", "level": 10, "parent": "", "mandatory": true, "lookupSupported": true, "matcherOptions": {"wildCard": "false"}, "uiHint":"{ \"singleValue\":true }", "isValidLeaf": false},
+        {"itemId": 2, "name": "table", "type": "string", "level": 20, "parent": "database", "mandatory": true, "lookupSupported": true, "matcherOptions": {"wildCard": "false"}, "uiHint":"{ \"singleValue\":true }", "isValidLeaf": false},
+        {"itemId": 4, "name": "column", "type": "string", "level": 30, "parent": "table", "mandatory": true, "lookupSupported": true, "matcherOptions": {"wildCard": "false"}, "uiHint":"{ \"singleValue\":true }", "isValidLeaf": true}
+      ],
+      "maskTypes": [
+        {"itemId": 1, "name": "MASK", "label": "Redact", "description": "Replace lowercase with 'x', uppercase with 'X', digits with '0'", "transformer": "mask({col})", "dataMaskOptions": {}},
+        {"itemId": 2, "name": "MASK_SHOW_LAST_4", "label": "Partial mask: show last 4", "description": "Show last 4 characters; replace rest with 'x'", "transformer": "mask_show_last_n({col}, 4, 'x', 'x', 'x', -1, '1')"},
+        {"itemId": 3, "name": "MASK_SHOW_FIRST_4", "label": "Partial mask: show first 4", "description": "Show first 4 characters; replace rest with 'x'", "transformer": "mask_show_first_n({col}, 4, 'x', 'x', 'x', -1, '1')"},
+        {"itemId": 4, "name": "MASK_HASH", "label": "Hash", "description": "Hash the value", "transformer": "mask_hash({col})"},
+        {"itemId": 5, "name": "MASK_NULL", "label": "Nullify", "description": "Replace with NULL"},
+        {"itemId": 6, "name": "MASK_NONE", "label": "Unmasked (retain original value)", "description": "No masking"},
+        {"itemId": 12, "name": "MASK_DATE_SHOW_YEAR", "label": "Date: show only year", "description": "Date: show only year", "transformer": "mask({col}, 'x', 'x', 'x', -1, '1', 1, 0, -1)"},
+        {"itemId": 13, "name": "CUSTOM", "label": "Custom", "description": "Custom"}
+      ]
+    },
+
+    "rowFilterDef": {
+      "accessTypes": [
+        {"name": "select"}
+      ],
+      "resources": [
+        {"itemId": 1, "name": "database", "type": "string", "level": 10, "parent": "", "mandatory": true, "lookupSupported": true, "matcherOptions": {"wildCard": "false"}, "uiHint": "{ \"singleValue\":true }", "isValidLeaf": false},
+        {"itemId": 2, "name": "table", "type": "string", "level": 20, "parent": "database", "mandatory": true, "lookupSupported": true, "matcherOptions": {"wildCard": "false"}, "uiHint": "{ \"singleValue\":true }", "isValidLeaf": true}
+      ]
+    }
+  },
+
+  "policies":[
+    {"id":1,"name":"database=*,table=*,column=* - audit-all-access","isEnabled":true,"isAuditEnabled":true,
+     "resources":{"database":{"values":["*"]},"table":{"values":["*"]},"column":{"values":["*"]}},
+     "policyItems":[
+       {"accesses":[],"users":[],"groups":["public"],"delegateAdmin":false}
+     ]
+    }
+    ,
+    {"id":2,"name":"database=* - allow anyone to create database; grant owner all access ","isEnabled":true,"isAuditEnabled":true,
+      "resources":{"database":{"values":["*"]}},
+      "policyItems":[
+        {"accesses":[{"type":"create","isAllowed":true}],"groups":["public"],"delegateAdmin":false},
+        {"accesses":[{"type":"all","isAllowed":true}],"users":["{OWNER}"],"delegateAdmin":false}
+      ]
+    },
+    {"id":3,"name":"database=*,table=* - allow owner all access to table","isEnabled":true,"isAuditEnabled":true,
+      "resources":{"database":{"values":["*"]},"table":{"values":["*"]}},
+      "policyItems":[
+        {"accesses":[{"type":"all","isAllowed":true}],"users":["{OWNER}"],"delegateAdmin":false}
+      ]
+    },
+    {"id":4,"name":"database=*;table=*;column=* - allow owner all access to column","isEnabled":true,"isAuditEnabled":true,
+      "resources":{"database":{"values":["*"]},"table":{"values":["*"]},"column":{"values":["*"]}},
+      "policyItems":[
+        {"accesses":[{"type":"all","isAllowed":true}],"users":["{OWNER}"],"delegateAdmin":false}
+      ]
+    }
+  ],
+
+  "tests":[
+    {"name":"ALLOW 'create db-1;' for user1",
+      "request":{
+        "resource":{"elements":{"database":"db-1"}},
+        "accessType":"create","user":"user1","userGroups":["users"],"requestData":"create db-1 for user1"
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":2}
+    }
+    ,
+    {"name":"ALLOW 'create db-1.tbl-1;' for user1 with ownerUser=user1",
+      "request":{
+        "resource":{"elements":{"database":"db-1", "table":"tbl-1"},"ownerUser":"user1"},
+        "accessType":"create","user":"user1","userGroups":["users"],"requestData":"create db-1.tbl-1;' for user1 - ownerUser=user1"
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":3}
+    }
+  ,
+    {"name":"DENY 'create db-1.tbl-1;' for user2 with ownerUser=user1",
+      "request":{
+        "resource":{"elements":{"database":"db-1", "table":"tbl-1"},"ownerUser":"user1"},
+        "accessType":"create","user":"user2","userGroups":["users"],"requestData":"create db-1.tbl-1;' for user2 - ownerUser=user1"
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":-1}
+    },
+    {"name":"ALLOW 'select db-1.tbl-1.col-1;' for user1 with ownerUser=user1",
+      "request":{
+        "resource":{"elements":{"database":"db-1", "table":"tbl-1", "column":"col-1"},"ownerUser":"user1"},
+        "accessType":"select","user":"user1","userGroups":["users"],"requestData":"select db-1.tbl-1.col-1;' for user1 - ownerUser=user1"
+      },
+      "result":{"isAudited":true,"isAllowed":true,"policyId":4}
+    },
+    {"name":"DENY 'select db-1.tbl-1.col-1;' for user2 with ownerUser=user1",
+      "request":{
+        "resource":{"elements":{"database":"db-1", "table":"tbl-1", "column":"col-1"},"ownerUser":"user1"},
+        "accessType":"select","user":"user2","userGroups":["users"],"requestData":"select db-1.tbl-1.col-1;' for user2 - ownerUser=user1"
+      },
+      "result":{"isAudited":true,"isAllowed":false,"policyId":-1}
+    }
+  ]
+}
+
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 7c3e3ab..ff6f6a7 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
@@ -487,6 +487,10 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 								HivePrincipal       grantorPrincipal,
 								boolean             grantOption)
 										throws HiveAuthzPluginException, HiveAccessControlException {
+		if (LOG.isDebugEnabled()) {
+				LOG.debug("grantPrivileges() => HivePrivilegeObject:" + toString(hivePrivObject, new StringBuilder()) + "grantorPrincipal: " + grantorPrincipal + "hivePrincipals" + hivePrincipals + "hivePrivileges" + hivePrivileges);
+		}
+
 		if(! RangerHivePlugin.UpdateXaPoliciesOnGrantRevoke) {
 			throw new HiveAuthzPluginException("GRANT/REVOKE not supported in Ranger HiveAuthorizer. Please use Ranger Security Admin to setup access control.");
 		}
@@ -494,7 +498,8 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 		RangerHiveAuditHandler auditHandler = new RangerHiveAuditHandler();
 
 		try {
-			RangerHiveResource resource = getHiveResource(HiveOperationType.GRANT_PRIVILEGE, hivePrivObject);
+			List<HivePrivilegeObject> outputs = new ArrayList<>(Arrays.asList(hivePrivObject));
+			RangerHiveResource resource = getHiveResource(HiveOperationType.GRANT_PRIVILEGE, hivePrivObject, null, outputs);
 			GrantRevokeRequest request  = createGrantRevokeData(resource, hivePrincipals, hivePrivileges, grantorPrincipal, grantOption);
 
 			LOG.info("grantPrivileges(): " + request);
@@ -534,7 +539,8 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 		RangerHiveAuditHandler auditHandler = new RangerHiveAuditHandler();
 
 		try {
-			RangerHiveResource resource = getHiveResource(HiveOperationType.REVOKE_PRIVILEGE, hivePrivObject);
+			List<HivePrivilegeObject> outputs = new ArrayList<>(Arrays.asList(hivePrivObject));
+			RangerHiveResource resource = getHiveResource(HiveOperationType.REVOKE_PRIVILEGE, hivePrivObject, null, outputs);
 			GrantRevokeRequest request  = createGrantRevokeData(resource, hivePrincipals, hivePrivileges, grantorPrincipal, grantOption);
 
 			LOG.info("revokePrivileges(): " + request);
@@ -598,7 +604,7 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 
 			if(!CollectionUtils.isEmpty(inputHObjs)) {
 				for(HivePrivilegeObject hiveObj : inputHObjs) {
-					RangerHiveResource resource = getHiveResource(hiveOpType, hiveObj);
+					RangerHiveResource resource = getHiveResource(hiveOpType, hiveObj, inputHObjs, outputHObjs);
 
 					if (resource == null) { // possible if input object/object is of a kind that we don't currently authorize
 						continue;
@@ -659,7 +665,7 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 
 			if(!CollectionUtils.isEmpty(outputHObjs)) {
 				for(HivePrivilegeObject hiveObj : outputHObjs) {
-					RangerHiveResource resource = getHiveResource(hiveOpType, hiveObj);
+					RangerHiveResource resource = getHiveResource(hiveOpType, hiveObj, inputHObjs, outputHObjs);
 
 					if (resource == null) { // possible if input object/object is of a kind that we don't currently authorize
 						continue;
@@ -1168,7 +1174,9 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 
 
 	private RangerHiveResource getHiveResource(HiveOperationType   hiveOpType,
-											   HivePrivilegeObject hiveObj) {
+											   HivePrivilegeObject hiveObj,
+											   List<HivePrivilegeObject> inputs,
+											   List<HivePrivilegeObject> outputs) {
 		RangerHiveResource ret = null;
 
 		HiveObjectType objectType = getObjectType(hiveObj, hiveOpType);
@@ -1176,18 +1184,36 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 		switch(objectType) {
 			case DATABASE:
 				ret = new RangerHiveResource(objectType, hiveObj.getDbname());
+				if (!isCreateOperation(hiveOpType)) {
+					ret.setOwnerUser(hiveObj.getOwnerName());
+				}
 			break;
 	
 			case TABLE:
 			case VIEW:
+			case FUNCTION:
+				ret = new RangerHiveResource(objectType, hiveObj.getDbname(), hiveObj.getObjectName());
+
+				String ownerName = hiveObj.getOwnerName();
+
+				if (isCreateOperation(hiveOpType)) {
+					HivePrivilegeObject dbObject = getDatabaseObject(hiveObj.getDbname(), inputs, outputs);
+					if (dbObject != null) {
+						ownerName = dbObject.getOwnerName();
+					}
+				}
+
+				ret.setOwnerUser(ownerName);
+			break;
+
 			case PARTITION:
 			case INDEX:
-			case FUNCTION:
 				ret = new RangerHiveResource(objectType, hiveObj.getDbname(), hiveObj.getObjectName());
 			break;
 	
 			case COLUMN:
 				ret = new RangerHiveResource(objectType, hiveObj.getDbname(), hiveObj.getObjectName(), StringUtils.join(hiveObj.getColumns(), COLUMN_SEP));
+				ret.setOwnerUser(hiveObj.getOwnerName());
 			break;
 
             case URI:
@@ -1210,6 +1236,44 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 		return ret;
 	}
 
+	private boolean isCreateOperation(HiveOperationType hiveOpType){
+		boolean ret = false;
+		switch (hiveOpType) {
+			case CREATETABLE:
+			case CREATEVIEW:
+			case CREATETABLE_AS_SELECT:
+			case CREATE_MATERIALIZED_VIEW:
+			case CREATEFUNCTION:
+				ret = true;
+			break;
+		}
+		return ret;
+	}
+
+	private HivePrivilegeObject getDatabaseObject(String dbName, List<HivePrivilegeObject> inputs, List<HivePrivilegeObject> outputs) {
+		HivePrivilegeObject ret = null;
+
+		if (CollectionUtils.isNotEmpty(outputs)) {
+			for (HivePrivilegeObject hiveOutPrivObj : outputs) {
+				if (hiveOutPrivObj.getType() == HivePrivilegeObjectType.DATABASE
+						&& dbName.equalsIgnoreCase(hiveOutPrivObj.getDbname())) {
+					ret = hiveOutPrivObj;
+				}
+			}
+		}
+
+		if (ret == null && CollectionUtils.isNotEmpty(inputs)) {
+			for (HivePrivilegeObject hiveInPrivObj : inputs) {
+				if (hiveInPrivObj.getType() == HivePrivilegeObjectType.DATABASE
+						&& dbName.equalsIgnoreCase(hiveInPrivObj.getDbname())) {
+					ret = hiveInPrivObj;
+				}
+			}
+		}
+
+		return ret;
+	}
+
 	private HiveObjectType getObjectType(HivePrivilegeObject hiveObj, HiveOperationType hiveOpType) {
 		HiveObjectType objType = HiveObjectType.NONE;
 		String hiveOpTypeName  = hiveOpType.name().toLowerCase();
@@ -1859,7 +1923,7 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 		mapResource.put(RangerHiveResource.KEY_DATABASE, database);
 		mapResource.put(RangerHiveResource.KEY_TABLE, table);
 		mapResource.put(RangerHiveResource.KEY_COLUMN, column);
-
+		ret.setOwnerUser(resource.getOwnerUser());
 		ret.setResource(mapResource);
 
 		SessionState ss = SessionState.get();
@@ -2368,7 +2432,6 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 
 		sb.append(", 'user':").append(this.getCurrentUserGroupInfo().getUserName());
 		sb.append(", 'groups':[").append(StringUtil.toString(this.getCurrentUserGroupInfo().getGroupNames())).append("]");
-
 		sb.append("}");
 
 		return sb.toString();
@@ -2396,6 +2459,7 @@ public class RangerHiveAuthorizer extends RangerHiveAuthorizerBase {
 		sb.append(", 'partKeys':[").append(StringUtil.toString(privObj.getPartKeys())).append("]");
 		sb.append(", 'commandParams':[").append(StringUtil.toString(privObj.getCommandParams())).append("]");
 		sb.append(", 'actionType':").append(privObj.getActionType().toString());
+		sb.append(", 'owner':").append(privObj.getOwnerName());
 		sb.append("}");
 
 		return sb;
diff --git a/hive-agent/src/main/java/org/apache/ranger/services/hive/RangerServiceHive.java b/hive-agent/src/main/java/org/apache/ranger/services/hive/RangerServiceHive.java
index a2bd5f7..89b8100 100644
--- a/hive-agent/src/main/java/org/apache/ranger/services/hive/RangerServiceHive.java
+++ b/hive-agent/src/main/java/org/apache/ranger/services/hive/RangerServiceHive.java
@@ -19,13 +19,19 @@
 package org.apache.ranger.services.hive;
 
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 
 import org.apache.ranger.plugin.client.HadoopException;
+import org.apache.ranger.plugin.model.RangerPolicy;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyResource;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItem;
+import org.apache.ranger.plugin.model.RangerPolicy.RangerPolicyItemAccess;
 import org.apache.ranger.plugin.model.RangerService;
 import org.apache.ranger.plugin.model.RangerServiceDef;
+import org.apache.ranger.plugin.policyengine.RangerPolicyEngine;
 import org.apache.ranger.plugin.service.RangerBaseService;
 import org.apache.ranger.plugin.service.ResourceLookupContext;
 import org.apache.ranger.services.hive.client.HiveResourceMgr;
@@ -35,11 +41,20 @@ import org.apache.commons.logging.LogFactory;
 public class RangerServiceHive extends RangerBaseService {
 
 	private static final Log LOG = LogFactory.getLog(RangerServiceHive.class);
-	
+
+	public static final String RESOURCE_DATABASE  = "database";
+	public static final String RESOURCE_TABLE     = "table";
+	public static final String RESOURCE_UDF       = "udf";
+	public static final String RESOURCE_COLUMN    = "column";
+	public static final String ACCESS_TYPE_CREATE = "create";
+	public static final String ACCESS_TYPE_ALL    = "all";
+	public static final String WILDCARD_ASTERISK  = "*";
+
+
 	public RangerServiceHive() {
 		super();
 	}
-	
+
 	@Override
 	public void init(RangerServiceDef serviceDef, RangerService service) {
 		super.init(serviceDef, service);
@@ -68,7 +83,7 @@ public class RangerServiceHive extends RangerBaseService {
 
 	@Override
 	public List<String> lookupResource(ResourceLookupContext context) throws Exception {
-		
+
 		List<String> ret 		   = new ArrayList<String>();
 		String 	serviceName  	   = getServiceName();
 		String	serviceType		   = getServiceType();
@@ -80,8 +95,8 @@ public class RangerServiceHive extends RangerBaseService {
 			try {
 				ret  = HiveResourceMgr.getHiveResources(serviceName, serviceType, configs,context);
 			} catch (Exception e) {
-			  LOG.error( "<==RangerServiceHive.lookupResource Error : " + e);
-			  throw e;
+				LOG.error( "<==RangerServiceHive.lookupResource Error : " + e);
+				throw e;
 			}
 		}
 		if(LOG.isDebugEnabled()) {
@@ -89,5 +104,63 @@ public class RangerServiceHive extends RangerBaseService {
 		}
 		return ret;
 	}
+
+	@Override
+	public List<RangerPolicy> getDefaultRangerPolicies() throws Exception {
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("==> RangerServiceHive.getDefaultRangerPolicies()");
+		}
+
+		List<RangerPolicy> ret = super.getDefaultRangerPolicies();
+
+		for (RangerPolicy defaultPolicy : ret) {
+			final Map<String, RangerPolicyResource> policyResources = defaultPolicy.getResources();
+
+			if (policyResources.size() == 1 && hasWildcardAsteriskResource(policyResources, RESOURCE_DATABASE)) { // policy for all databases
+				RangerPolicyItem policyItemPublic = new RangerPolicyItem();
+
+				policyItemPublic.setGroups(Collections.singletonList(RangerPolicyEngine.GROUP_PUBLIC));
+				policyItemPublic.setAccesses(Collections.singletonList(new RangerPolicyItemAccess(ACCESS_TYPE_CREATE)));
+
+				RangerPolicyItem policyItemOwner = new RangerPolicyItem();
+
+				policyItemOwner.setUsers(Collections.singletonList(RangerPolicyEngine.RESOURCE_OWNER));
+				policyItemOwner.setAccesses(Collections.singletonList(new RangerPolicyItemAccess(ACCESS_TYPE_ALL)));
+				policyItemOwner.setDelegateAdmin(true);
+
+				defaultPolicy.getPolicyItems().add(policyItemPublic);
+				defaultPolicy.getPolicyItems().add(policyItemOwner);
+			} else if ((policyResources.size() == 2 && hasWildcardAsteriskResource(policyResources, RESOURCE_DATABASE, RESOURCE_TABLE)) ||                  // policy for all tables
+					(policyResources.size() == 2 && hasWildcardAsteriskResource(policyResources, RESOURCE_DATABASE, RESOURCE_UDF))   ||                  // policy for all UDFs
+					(policyResources.size() == 3 && hasWildcardAsteriskResource(policyResources, RESOURCE_DATABASE, RESOURCE_TABLE, RESOURCE_COLUMN))) { // policy for all columns
+				RangerPolicyItem policyItemOwner = new RangerPolicyItem();
+
+				policyItemOwner.setUsers(Collections.singletonList(RangerPolicyEngine.RESOURCE_OWNER));
+				policyItemOwner.setAccesses(Collections.singletonList(new RangerPolicyItemAccess(ACCESS_TYPE_ALL)));
+				policyItemOwner.setDelegateAdmin(true);
+
+				defaultPolicy.getPolicyItems().add(policyItemOwner);
+			}
+		}
+
+		if (LOG.isDebugEnabled()) {
+			LOG.debug("<== RangerServiceHive.getDefaultRangerPolicies()");
+		}
+
+		return ret;
+	}
+
+	private boolean hasWildcardAsteriskResource(Map<String, RangerPolicyResource> policyResources, String... resourceNames) {
+		for (String resourceName : resourceNames) {
+			RangerPolicyResource resource = policyResources.get(resourceName);
+			List<String>         values   = resource != null ? resource.getValues() : null;
+
+			if (values == null || !values.contains(WILDCARD_ASTERISK)) {
+				return false;
+			}
+		}
+
+		return true;
+	}
 }
 
diff --git a/pom.xml b/pom.xml
index 13d5a5b..8e3a92c 100644
--- a/pom.xml
+++ b/pom.xml
@@ -119,7 +119,7 @@
 	<ozone.version>0.4.0-alpha</ozone.version>
         <hamcrest.all.version>1.3</hamcrest.all.version>
         <hbase.version>2.0.2</hbase.version>
-        <hive.version>3.1.0</hive.version>
+        <hive.version>4.0.0-SNAPSHOT</hive.version>
         <hbase-shaded-protobuf>2.0.0</hbase-shaded-protobuf>
         <hbase-shaded-netty>2.0.0</hbase-shaded-netty>
         <hbase-shaded-miscellaneous>2.0.0</hbase-shaded-miscellaneous>
diff --git a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
index af74daf..e7b3172 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/ServiceREST.java
@@ -1204,7 +1204,8 @@ public class ServiceREST {
 					validateGrantRevokeRequest(grantRequest);
 					String               userName   = grantRequest.getGrantor();
 					Set<String>          userGroups = CollectionUtils.isNotEmpty(grantRequest.getGrantorGroups()) ? grantRequest.getGrantorGroups() : userMgr.getGroupsForUser(userName);
-					RangerAccessResource resource   = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(grantRequest.getResource()));
+					String				 ownerUser  = grantRequest.getOwnerUser();
+					RangerAccessResource resource   = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(grantRequest.getResource()), ownerUser);
                                         VXUser vxUser = xUserService.getXUserByUserName(userName);
                                         if(vxUser.getUserRoleList().contains(RangerConstants.ROLE_ADMIN_AUDITOR) || vxUser.getUserRoleList().contains(RangerConstants.ROLE_KEY_ADMIN_AUDITOR)){
                                                  VXResponse vXResponse = new VXResponse();
@@ -1314,7 +1315,8 @@ public class ServiceREST {
 
 					String               userName   = grantRequest.getGrantor();
 					Set<String>          userGroups = CollectionUtils.isNotEmpty(grantRequest.getGrantorGroups()) ? grantRequest.getGrantorGroups() : userMgr.getGroupsForUser(userName);
-					RangerAccessResource resource   = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(grantRequest.getResource()));
+					String				 ownerUser  = grantRequest.getOwnerUser();
+					RangerAccessResource resource   = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(grantRequest.getResource()), ownerUser);
 					boolean isAdmin = hasAdminAccess(serviceName, userName, userGroups, resource);
 
 					XXService xService = daoManager.getXXService().findByName(serviceName);
@@ -1431,7 +1433,8 @@ public class ServiceREST {
 
 					String               userName   = revokeRequest.getGrantor();
 					Set<String>          userGroups = CollectionUtils.isNotEmpty(revokeRequest.getGrantorGroups()) ? revokeRequest.getGrantorGroups() : userMgr.getGroupsForUser(userName);
-					RangerAccessResource resource   = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(revokeRequest.getResource()));
+					String				 ownerUser  = revokeRequest.getOwnerUser();
+					RangerAccessResource resource   = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(revokeRequest.getResource()), ownerUser);
                                         VXUser vxUser = xUserService.getXUserByUserName(userName);
                                         if(vxUser.getUserRoleList().contains(RangerConstants.ROLE_ADMIN_AUDITOR) || vxUser.getUserRoleList().contains(RangerConstants.ROLE_KEY_ADMIN_AUDITOR)){
                                                  VXResponse vXResponse = new VXResponse();
@@ -1502,7 +1505,8 @@ public class ServiceREST {
 
 					String               userName   = revokeRequest.getGrantor();
 					Set<String>          userGroups = CollectionUtils.isNotEmpty(revokeRequest.getGrantorGroups()) ? revokeRequest.getGrantorGroups() : userMgr.getGroupsForUser(userName);
-					RangerAccessResource resource   = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(revokeRequest.getResource()));
+					String				 ownerUser  = revokeRequest.getOwnerUser();
+					RangerAccessResource resource   = new RangerAccessResourceImpl(StringUtil.toStringObjectMap(revokeRequest.getResource()), ownerUser);
 					boolean isAdmin = hasAdminAccess(serviceName, userName, userGroups, resource);
 					boolean isAllowed = false;
 					boolean isKeyAdmin = bizUtil.isKeyAdmin();