This is an automated email from the ASF dual-hosted git repository.

madhan 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 04cb1dc5b RANGER-4274: updated security-zones to support admin-roles 
and audit-roles
04cb1dc5b is described below

commit 04cb1dc5bd01d1772b4fc42e01a164333c43a1d7
Author: Madhan Neethiraj <mad...@apache.org>
AuthorDate: Tue Jun 6 07:14:36 2023 -0700

    RANGER-4274: updated security-zones to support admin-roles and audit-roles
---
 .../ranger/plugin/errors/ValidationErrorCode.java  |   2 +-
 .../ranger/plugin/model/RangerSecurityZone.java    |  24 ++-
 .../validation/RangerSecurityZoneValidator.java    |  16 +-
 .../apache_ranger/model/ranger_security_zone.py    |   2 +
 .../optimized/current/ranger_core_db_mysql.sql     |  18 ++
 .../mysql/patches/075-create-sz-role-ref-table.sql |  32 ++++
 .../optimized/current/ranger_core_db_oracle.sql    |  19 +++
 .../patches/075-create-sz-ref-role-table.sql       |  33 ++++
 .../optimized/current/ranger_core_db_postgres.sql  |  21 +++
 .../patches/075-create-sz-ref-role-table.sql       |  37 +++++
 .../current/ranger_core_db_sqlanywhere.sql         |  24 +++
 .../patches/075-create-sz-ref-role-table.sql       |  40 +++++
 .../optimized/current/ranger_core_db_sqlserver.sql |  49 ++++++
 .../patches/075-create-sz-ref-role-table.sql       |  66 ++++++++
 .../java/org/apache/ranger/biz/RoleDBStore.java    |  18 ++
 .../apache/ranger/biz/SecurityZoneRefUpdater.java  | 144 +++++++---------
 .../java/org/apache/ranger/biz/ServiceMgr.java     |  65 +++++++-
 .../org/apache/ranger/db/RangerDaoManagerBase.java |   2 +
 .../apache/ranger/db/XXSecurityZoneRefRoleDao.java | 105 ++++++++++++
 .../ranger/entity/XXSecurityZoneRefRole.java       | 185 +++++++++++++++++++++
 .../org/apache/ranger/rest/SecurityZoneREST.java   |   9 +
 .../service/RangerSecurityZoneServiceService.java  |   2 +
 .../main/resources/META-INF/jpa_named_queries.xml  |  18 ++
 23 files changed, 835 insertions(+), 96 deletions(-)

diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
index f44b9d9a1..85c42bcc8 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/errors/ValidationErrorCode.java
@@ -111,7 +111,7 @@ public enum ValidationErrorCode {
     SECURITY_ZONE_VALIDATION_ERR_MISSING_FIELD(3035, "Internal error: missing 
field[{0}]"),
     SECURITY_ZONE_VALIDATION_ERR_ZONE_NAME_CONFLICT(3036, "Another security 
zone already exists for this name: zone-id=[{0}]]"),
     SECURITY_ZONE_VALIDATION_ERR_INVALID_ZONE_ID(3037, "No security zone found 
for [{0}]"),
-    SECURITY_ZONE_VALIDATION_ERR_MISSING_USER_AND_GROUPS(3038, "both users and 
user-groups collections for the security zone were null/empty"),
+    SECURITY_ZONE_VALIDATION_ERR_MISSING_USER_AND_GROUPS_AND_ROLES(3038, 
"users, user-groups and roles collections for the security zone were 
null/empty"),
     SECURITY_ZONE_VALIDATION_ERR_MISSING_RESOURCES(3039, "No resources 
specified for service [{0}]"),
     SECURITY_ZONE_VALIDATION_ERR_INVALID_SERVICE_NAME(3040, "Invalid service 
[{0}]"),
     SECURITY_ZONE_VALIDATION_ERR_INVALID_SERVICE_TYPE(3041, "Invalid 
service-type [{0}]"),
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerSecurityZone.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerSecurityZone.java
index 7327f3fe2..ea79b69e8 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerSecurityZone.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/RangerSecurityZone.java
@@ -44,21 +44,29 @@ public class RangerSecurityZone extends 
RangerBaseModelObject implements java.io
     private List<String>                                                       
tagServices;
     private List<String>                            adminUsers;
     private List<String>                            adminUserGroups;
+    private List<String>                            adminRoles;
     private List<String>                            auditUsers;
     private List<String>                            auditUserGroups;
+    private List<String>                            auditRoles;
     private String                                  description;
 
     public RangerSecurityZone() {
-        this(null, null, null, null, null, null, null,null);
+        this(null, null, null, null, null, null, null,null, null, null);
     }
 
     public RangerSecurityZone(String name, Map<String, 
RangerSecurityZoneService> services,List<String> tagServices, List<String> 
adminUsers, List<String> adminUserGroups, List<String> auditUsers, List<String> 
auditUserGroups, String description) {
+        this(name, services, tagServices, adminUsers, adminUserGroups, null, 
adminUsers, adminUserGroups, null, description);
+    }
+
+    public RangerSecurityZone(String name, Map<String, 
RangerSecurityZoneService> services,List<String> tagServices, List<String> 
adminUsers, List<String> adminUserGroups, List<String> adminRoles, List<String> 
auditUsers, List<String> auditUserGroups, List<String> auditRoles, String 
description) {
         setName(name);
         setServices(services);
         setAdminUsers(adminUsers);
         setAdminUserGroups(adminUserGroups);
+        setAdminRoles(adminRoles);
         setAuditUsers(auditUsers);
         setAuditUserGroups(auditUserGroups);
+        setAuditRoles(auditRoles);
         setDescription(description);
         setTagServices(tagServices);
     }
@@ -92,6 +100,12 @@ public class RangerSecurityZone extends 
RangerBaseModelObject implements java.io
         this.adminUserGroups = adminUserGroups == null ? new ArrayList<>() : 
adminUserGroups;
     }
 
+    public List<String> getAdminRoles() { return adminRoles; }
+
+    public void setAdminRoles(List<String> adminRoles) {
+        this.adminRoles = adminRoles == null ? new ArrayList<>() : adminRoles;
+    }
+
     public List<String> getAuditUsers() { return auditUsers; }
 
     public void setAuditUsers(List<String> auditUsers) {
@@ -104,6 +118,12 @@ public class RangerSecurityZone extends 
RangerBaseModelObject implements java.io
         this.auditUserGroups = auditUserGroups == null ? new ArrayList<>() : 
auditUserGroups;
     }
 
+    public List<String> getAuditRoles() { return auditRoles; }
+
+    public void setAuditRoles(List<String> auditRoles) {
+        this.auditRoles = auditRoles == null ? new ArrayList<>() : auditRoles;
+    }
+
     public List<String> getTagServices() {
                 return tagServices;
         }
@@ -119,8 +139,10 @@ public class RangerSecurityZone extends 
RangerBaseModelObject implements java.io
                 + ", tagServices=" + tagServices
                 + ", adminUsers=" + adminUsers
                 + ", adminUserGroups=" + adminUserGroups
+                + ", adminRoles=" + adminRoles
                 + ", auditUsers=" + auditUsers
                 + ", auditUserGroups=" + auditUserGroups
+                + ", auditRoles=" + auditRoles
                 + ", description="+ description
                 +"}";
     }
diff --git 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidator.java
 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidator.java
index ca899979a..cb4f37cc0 100644
--- 
a/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidator.java
+++ 
b/agents-common/src/main/java/org/apache/ranger/plugin/model/validation/RangerSecurityZoneValidator.java
@@ -233,18 +233,18 @@ public class RangerSecurityZoneValidator extends 
RangerValidator {
             failures.add(new 
ValidationFailureDetailsBuilder().becauseOf("security zone 
services").isMissing().field("services").errorCode(error.getErrorCode()).becauseOf(error.getMessage(securityZone.getName())).build());
             ret = false;
         }
-        // both admin users and user-groups collections can't be empty
-        if (CollectionUtils.isEmpty(securityZone.getAdminUsers()) && 
CollectionUtils.isEmpty(securityZone.getAdminUserGroups())) {
-            ValidationErrorCode error = 
ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_MISSING_USER_AND_GROUPS;
+        // admin users, user-groups and roles collections can't be empty
+        if (CollectionUtils.isEmpty(securityZone.getAdminUsers()) && 
CollectionUtils.isEmpty(securityZone.getAdminUserGroups()) && 
CollectionUtils.isEmpty(securityZone.getAdminRoles())) {
+            ValidationErrorCode error = 
ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_MISSING_USER_AND_GROUPS_AND_ROLES;
 
-            failures.add(new ValidationFailureDetailsBuilder().field("security 
zone admin 
users/user-groups").isMissing().becauseOf(error.getMessage()).errorCode(error.getErrorCode()).build());
+            failures.add(new ValidationFailureDetailsBuilder().field("security 
zone admin 
users/user-groups/roles").isMissing().becauseOf(error.getMessage()).errorCode(error.getErrorCode()).build());
             ret = false;
         }
-        // both audit users and user-groups collections can't be empty
-        if (CollectionUtils.isEmpty(securityZone.getAuditUsers()) && 
CollectionUtils.isEmpty(securityZone.getAuditUserGroups())) {
-            ValidationErrorCode error = 
ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_MISSING_USER_AND_GROUPS;
+        // audit users, user-groups and roles collections can't be empty
+        if (CollectionUtils.isEmpty(securityZone.getAuditUsers()) && 
CollectionUtils.isEmpty(securityZone.getAuditUserGroups()) && 
CollectionUtils.isEmpty(securityZone.getAuditRoles())) {
+            ValidationErrorCode error = 
ValidationErrorCode.SECURITY_ZONE_VALIDATION_ERR_MISSING_USER_AND_GROUPS_AND_ROLES;
 
-            failures.add(new ValidationFailureDetailsBuilder().field("security 
zone audit 
users/user-groups").isMissing().becauseOf(error.getMessage()).errorCode(error.getErrorCode()).build());
+            failures.add(new ValidationFailureDetailsBuilder().field("security 
zone audit 
users/user-groups/roles").isMissing().becauseOf(error.getMessage()).errorCode(error.getErrorCode()).build());
             ret = false;
         }
 
diff --git a/intg/src/main/python/apache_ranger/model/ranger_security_zone.py 
b/intg/src/main/python/apache_ranger/model/ranger_security_zone.py
index 9b3eec623..6faa15744 100644
--- a/intg/src/main/python/apache_ranger/model/ranger_security_zone.py
+++ b/intg/src/main/python/apache_ranger/model/ranger_security_zone.py
@@ -47,8 +47,10 @@ class RangerSecurityZone(RangerBaseModelObject):
         self.tagServices     = attrs.get('tagServices')
         self.adminUsers      = attrs.get('adminUsers')
         self.adminUserGroups = attrs.get('adminUserGroups')
+        self.adminRoles      = attrs.get('adminRoles')
         self.auditUsers      = attrs.get('auditUsers')
         self.auditUserGroups = attrs.get('auditUserGroups')
+        self.auditRoles      = attrs.get('auditRoles')
         self.description     = attrs.get('description')
 
     def type_coerce_attrs(self):
diff --git a/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql 
b/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql
index 66ae5060a..ac1fa1509 100644
--- a/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql
+++ b/security-admin/db/mysql/optimized/current/ranger_core_db_mysql.sql
@@ -67,6 +67,7 @@ DROP TABLE IF EXISTS `x_service_config_def`;
 DROP TABLE IF EXISTS `x_policy`;
 DROP TABLE IF EXISTS `x_security_zone_ref_group`;
 DROP TABLE IF EXISTS `x_security_zone_ref_user`;
+DROP TABLE IF EXISTS `x_security_zone_ref_role`;
 DROP TABLE IF EXISTS `x_security_zone_ref_tag_srvc`;
 DROP TABLE IF EXISTS `x_security_zone_ref_service`;
 DROP TABLE IF EXISTS `x_ranger_global_state`;
@@ -1542,6 +1543,22 @@ CREATE TABLE IF NOT EXISTS `x_role_ref_role`(
  CONSTRAINT `x_role_ref_role_FK_role_ref_id` FOREIGN KEY (`role_ref_id`) 
REFERENCES `x_role` (`id`)
 )ROW_FORMAT=DYNAMIC;
 
+CREATE TABLE IF NOT EXISTS `x_security_zone_ref_role`(
+`id` bigint(20) NOT NULL AUTO_INCREMENT,
+`create_time` datetime NULL DEFAULT NULL,
+`update_time` datetime NULL DEFAULT NULL,
+`added_by_id` bigint(20) NULL DEFAULT NULL,
+`upd_by_id` bigint(20) NULL DEFAULT NULL,
+`zone_id` bigint(20) NULL DEFAULT NULL,
+`role_id` bigint(20) NULL DEFAULT NULL,
+`role_name` varchar(255) NULL DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ CONSTRAINT `x_sz_ref_role_FK_added_by_id` FOREIGN KEY (`added_by_id`) 
REFERENCES `x_portal_user` (`id`),
+ CONSTRAINT `x_sz_ref_role_FK_upd_by_id` FOREIGN KEY (`upd_by_id`) REFERENCES 
`x_portal_user` (`id`),
+ CONSTRAINT `x_sz_ref_role_FK_zone_id` FOREIGN KEY (`zone_id`) REFERENCES 
`x_security_zone` (`id`),
+ CONSTRAINT `x_sz_ref_role_FK_role_id` FOREIGN KEY (`role_id`) REFERENCES 
`x_role` (`id`)
+ )ROW_FORMAT=DYNAMIC;
+
 CREATE TABLE IF NOT EXISTS `x_tag_change_log` (
 `id` bigint(20) NOT NULL AUTO_INCREMENT,
 `create_time` datetime NULL DEFAULT NULL,
@@ -1814,6 +1831,7 @@ INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active
 INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('059',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
 INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('060',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
 INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('065',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
+INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('075',UTC_TIMESTAMP(),'Ranger 3.0.0',UTC_TIMESTAMP(),'localhost','Y');
 INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('DB_PATCHES',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
 
 INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('J10001',UTC_TIMESTAMP(),'Ranger 1.0.0',UTC_TIMESTAMP(),'localhost','Y');
diff --git a/security-admin/db/mysql/patches/075-create-sz-role-ref-table.sql 
b/security-admin/db/mysql/patches/075-create-sz-role-ref-table.sql
new file mode 100644
index 000000000..d09bf6422
--- /dev/null
+++ b/security-admin/db/mysql/patches/075-create-sz-role-ref-table.sql
@@ -0,0 +1,32 @@
+-- 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.
+
+DROP TABLE IF EXISTS `x_security_zone_ref_role`;
+
+CREATE TABLE IF NOT EXISTS `x_security_zone_ref_role`(
+`id` bigint(20) NOT NULL AUTO_INCREMENT,
+`create_time` datetime NULL DEFAULT NULL,
+`update_time` datetime NULL DEFAULT NULL,
+`added_by_id` bigint(20) NULL DEFAULT NULL,
+`upd_by_id` bigint(20) NULL DEFAULT NULL,
+`zone_id` bigint(20) NULL DEFAULT NULL,
+`role_id` bigint(20) NULL DEFAULT NULL,
+`role_name` varchar(255) NULL DEFAULT NULL,
+ PRIMARY KEY (`id`),
+ CONSTRAINT `x_sz_ref_role_FK_added_by_id` FOREIGN KEY (`added_by_id`) 
REFERENCES `x_portal_user` (`id`),
+ CONSTRAINT `x_sz_ref_role_FK_upd_by_id` FOREIGN KEY (`upd_by_id`) REFERENCES 
`x_portal_user` (`id`),
+ CONSTRAINT `x_sz_ref_role_FK_zone_id` FOREIGN KEY (`zone_id`) REFERENCES 
`x_security_zone` (`id`),
+ CONSTRAINT `x_sz_ref_role_FK_role_id` FOREIGN KEY (`role_id`) REFERENCES 
`x_role` (`id`)
+ )ROW_FORMAT=DYNAMIC;
diff --git 
a/security-admin/db/oracle/optimized/current/ranger_core_db_oracle.sql 
b/security-admin/db/oracle/optimized/current/ranger_core_db_oracle.sql
index bfa6dd572..a4d145de0 100644
--- a/security-admin/db/oracle/optimized/current/ranger_core_db_oracle.sql
+++ b/security-admin/db/oracle/optimized/current/ranger_core_db_oracle.sql
@@ -257,6 +257,7 @@ call spdroptable('x_service_config_def');
 call spdroptable('x_policy');
 call spdroptable('x_security_zone_ref_group');
 call spdroptable('x_security_zone_ref_user');
+call spdroptable('x_security_zone_ref_role');
 call spdroptable('x_security_zone_ref_tag_srvc');
 call spdroptable('x_security_zone_ref_service');
 call spdroptable('x_ranger_global_state');
@@ -1641,6 +1642,23 @@ CONSTRAINT x_sz_ref_res_FK_res_def_id FOREIGN KEY 
(resource_def_id) REFERENCES x
 );
 commit;
 
+CREATE TABLE x_security_zone_ref_role (
+id NUMBER(20) NOT NULL,
+create_time DATE DEFAULT NULL NULL,
+update_time DATE DEFAULT NULL NULL,
+added_by_id NUMBER(20) DEFAULT NULL NULL,
+upd_by_id NUMBER(20) DEFAULT NULL NULL,
+zone_id NUMBER(20)  DEFAULT NULL NULL,
+role_id NUMBER(20)  DEFAULT NULL NULL,
+role_name varchar(255) DEFAULT NULL NULL,
+primary key (id),
+CONSTRAINT x_sz_ref_role_FK_added_by_id FOREIGN KEY (added_by_id) REFERENCES 
x_portal_user (id),
+CONSTRAINT x_sz_ref_role_FK_upd_by_id FOREIGN KEY (upd_by_id) REFERENCES 
x_portal_user (id),
+CONSTRAINT x_sz_ref_role_FK_zone_id FOREIGN KEY (zone_id) REFERENCES 
x_security_zone (id),
+CONSTRAINT x_sz_ref_role_FK_role_id FOREIGN KEY (role_id) REFERENCES x_role 
(id)
+);
+commit;
+
 CREATE VIEW vx_trx_log AS select x_trx_log.id AS id,x_trx_log.create_time AS 
create_time,x_trx_log.update_time AS update_time,x_trx_log.added_by_id AS 
added_by_id,x_trx_log.upd_by_id AS upd_by_id,x_trx_log.class_type AS 
class_type,x_trx_log.object_id AS object_id,x_trx_log.parent_object_id AS 
parent_object_id,x_trx_log.parent_object_class_type AS 
parent_object_class_type,x_trx_log.attr_name AS 
attr_name,x_trx_log.parent_object_name AS 
parent_object_name,x_trx_log.object_name AS object_na [...]
 commit;
 
@@ -1974,6 +1992,7 @@ INSERT INTO x_db_version_h 
(id,version,inst_at,inst_by,updated_at,updated_by,act
 INSERT INTO x_db_version_h 
(id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
(X_DB_VERSION_H_SEQ.nextval, '059',sys_extract_utc(systimestamp),'Ranger 
1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
 INSERT INTO x_db_version_h 
(id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
(X_DB_VERSION_H_SEQ.nextval, '060',sys_extract_utc(systimestamp),'Ranger 
1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
 INSERT INTO x_db_version_h 
(id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
(X_DB_VERSION_H_SEQ.nextval, '065',sys_extract_utc(systimestamp),'Ranger 
1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
+INSERT INTO x_db_version_h 
(id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
(X_DB_VERSION_H_SEQ.nextval, '075',sys_extract_utc(systimestamp),'Ranger 
3.0.0',sys_extract_utc(systimestamp),'localhost','Y');
 INSERT INTO x_db_version_h 
(id,version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
(X_DB_VERSION_H_SEQ.nextval, 'DB_PATCHES',sys_extract_utc(systimestamp),'Ranger 
1.0.0',sys_extract_utc(systimestamp),'localhost','Y');
 
 INSERT INTO x_user_module_perm 
(id,user_id,module_id,create_time,update_time,added_by_id,upd_by_id,is_allowed) 
VALUES 
(X_USER_MODULE_PERM_SEQ.nextval,getXportalUIdByLoginId('admin'),getModulesIdByName('Reports'),sys_extract_utc(systimestamp),sys_extract_utc(systimestamp),getXportalUIdByLoginId('admin'),getXportalUIdByLoginId('admin'),1);
diff --git a/security-admin/db/oracle/patches/075-create-sz-ref-role-table.sql 
b/security-admin/db/oracle/patches/075-create-sz-ref-role-table.sql
new file mode 100644
index 000000000..990c8fd29
--- /dev/null
+++ b/security-admin/db/oracle/patches/075-create-sz-ref-role-table.sql
@@ -0,0 +1,33 @@
+-- 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.
+
+call spdroptable('x_security_zone_ref_role');
+
+CREATE TABLE x_security_zone_ref_role (
+id NUMBER(20) NOT NULL,
+create_time DATE DEFAULT NULL NULL,
+update_time DATE DEFAULT NULL NULL,
+added_by_id NUMBER(20) DEFAULT NULL NULL,
+upd_by_id NUMBER(20) DEFAULT NULL NULL,
+zone_id NUMBER(20)  DEFAULT NULL NULL,
+role_id NUMBER(20)  DEFAULT NULL NULL,
+role_name varchar(255) DEFAULT NULL NULL,
+primary key (id),
+CONSTRAINT x_sz_ref_role_FK_added_by_id FOREIGN KEY (added_by_id) REFERENCES 
x_portal_user (id),
+CONSTRAINT x_sz_ref_role_FK_upd_by_id FOREIGN KEY (upd_by_id) REFERENCES 
x_portal_user (id),
+CONSTRAINT x_sz_ref_role_FK_zone_id FOREIGN KEY (zone_id) REFERENCES 
x_security_zone (id),
+CONSTRAINT x_sz_ref_role_FK_role_id FOREIGN KEY (role_id) REFERENCES x_role 
(id)
+);
+commit;
diff --git 
a/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql 
b/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql
index 8dd90c1b8..e3273497e 100644
--- a/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql
+++ b/security-admin/db/postgres/optimized/current/ranger_core_db_postgres.sql
@@ -66,6 +66,7 @@ DROP TABLE IF EXISTS x_service_config_def CASCADE;
 DROP TABLE IF EXISTS x_policy CASCADE;
 DROP TABLE IF EXISTS x_security_zone_ref_group CASCADE;
 DROP TABLE IF EXISTS x_security_zone_ref_user CASCADE;
+DROP TABLE IF EXISTS x_security_zone_ref_role CASCADE;
 DROP TABLE IF EXISTS x_security_zone_ref_tag_srvc CASCADE;
 DROP TABLE IF EXISTS x_security_zone_ref_service CASCADE;
 DROP TABLE IF EXISTS x_ranger_global_state CASCADE;
@@ -92,6 +93,7 @@ DROP TABLE IF EXISTS x_db_version_h CASCADE;
 
 DROP SEQUENCE IF EXISTS x_sec_zone_ref_group_seq;
 DROP SEQUENCE IF EXISTS x_sec_zone_ref_user_seq;
+DROP SEQUENCE IF EXISTS x_sec_zone_ref_role_seq;
 DROP SEQUENCE IF EXISTS x_sec_zone_ref_resource_seq;
 DROP SEQUENCE IF EXISTS x_sec_zone_ref_service_seq;
 DROP SEQUENCE IF EXISTS x_sec_zone_ref_tag_srvc_SEQ;
@@ -1573,6 +1575,24 @@ priv_type INT DEFAULT NULL NULL,
 );
 commit;
 
+CREATE SEQUENCE x_sec_zone_ref_role_seq;
+CREATE TABLE x_security_zone_ref_role (
+id BIGINT DEFAULT nextval('x_sec_zone_ref_role_seq'::regclass),
+create_time TIMESTAMP DEFAULT NULL NULL,
+update_time TIMESTAMP DEFAULT NULL NULL,
+added_by_id BIGINT DEFAULT NULL NULL,
+upd_by_id BIGINT DEFAULT NULL NULL,
+zone_id BIGINT DEFAULT NULL NULL,
+role_id BIGINT DEFAULT NULL NULL,
+role_name varchar(255) NULL DEFAULT NULL::character varying,
+primary key (id),
+CONSTRAINT x_sz_ref_role_FK_added_by_id FOREIGN KEY (added_by_id) REFERENCES 
x_portal_user (id),
+CONSTRAINT x_sz_ref_role_FK_upd_by_id FOREIGN KEY (upd_by_id) REFERENCES 
x_portal_user (id),
+CONSTRAINT x_sz_ref_role_FK_zone_id FOREIGN KEY (zone_id) REFERENCES 
x_security_zone (id),
+CONSTRAINT x_sz_ref_role_FK_role_id FOREIGN KEY (role_id) REFERENCES x_role 
(id)
+);
+commit;
+
 CREATE SEQUENCE x_tag_change_log_seq;
 
 CREATE TABLE x_tag_change_log (
@@ -1897,6 +1917,7 @@ INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active
 INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('059',current_timestamp,'Ranger 1.0.0',current_timestamp,'localhost','Y');
 INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('060',current_timestamp,'Ranger 1.0.0',current_timestamp,'localhost','Y');
 INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('065',current_timestamp,'Ranger 1.0.0',current_timestamp,'localhost','Y');
+INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('075',current_timestamp,'Ranger 3.0.0',current_timestamp,'localhost','Y');
 INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('DB_PATCHES',current_timestamp,'Ranger 
1.0.0',current_timestamp,'localhost','Y');
 
 INSERT INTO x_user_module_perm 
(user_id,module_id,create_time,update_time,added_by_id,upd_by_id,is_allowed) 
VALUES
diff --git 
a/security-admin/db/postgres/patches/075-create-sz-ref-role-table.sql 
b/security-admin/db/postgres/patches/075-create-sz-ref-role-table.sql
new file mode 100644
index 000000000..ab4e5748c
--- /dev/null
+++ b/security-admin/db/postgres/patches/075-create-sz-ref-role-table.sql
@@ -0,0 +1,37 @@
+-- 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.
+
+DROP TABLE IF EXISTS x_security_zone_ref_role CASCADE;
+
+DROP SEQUENCE IF EXISTS x_sec_zone_ref_role_seq;
+
+CREATE SEQUENCE x_sec_zone_ref_role_seq;
+CREATE TABLE x_security_zone_ref_role (
+id BIGINT DEFAULT nextval('x_sec_zone_ref_role_seq'::regclass),
+create_time TIMESTAMP DEFAULT NULL NULL,
+update_time TIMESTAMP DEFAULT NULL NULL,
+added_by_id BIGINT DEFAULT NULL NULL,
+upd_by_id BIGINT DEFAULT NULL NULL,
+zone_id BIGINT DEFAULT NULL NULL,
+role_id BIGINT DEFAULT NULL NULL,
+role_name varchar(255) NULL DEFAULT NULL::character varying,
+primary key (id),
+CONSTRAINT x_sz_ref_role_FK_added_by_id FOREIGN KEY (added_by_id) REFERENCES 
x_portal_user (id),
+CONSTRAINT x_sz_ref_role_FK_upd_by_id FOREIGN KEY (upd_by_id) REFERENCES 
x_portal_user (id),
+CONSTRAINT x_sz_ref_role_FK_zone_id FOREIGN KEY (zone_id) REFERENCES 
x_security_zone (id),
+CONSTRAINT x_sz_ref_role_FK_role_id FOREIGN KEY (role_id) REFERENCES x_role 
(id)
+);
+commit;
+
diff --git 
a/security-admin/db/sqlanywhere/optimized/current/ranger_core_db_sqlanywhere.sql
 
b/security-admin/db/sqlanywhere/optimized/current/ranger_core_db_sqlanywhere.sql
index 3a614e44e..8fe9dbf5f 100644
--- 
a/security-admin/db/sqlanywhere/optimized/current/ranger_core_db_sqlanywhere.sql
+++ 
b/security-admin/db/sqlanywhere/optimized/current/ranger_core_db_sqlanywhere.sql
@@ -144,6 +144,8 @@ call 
dbo.removeForeignKeysAndTable('x_security_zone_ref_group')
 GO
 call dbo.removeForeignKeysAndTable('x_security_zone_ref_user')
 GO
+call dbo.removeForeignKeysAndTable('x_security_zone_ref_role')
+GO
 call dbo.removeForeignKeysAndTable('x_security_zone_ref_tag_srvc')
 GO
 call dbo.removeForeignKeysAndTable('x_security_zone_ref_service')
@@ -1224,6 +1226,18 @@ CREATE TABLE dbo.x_security_zone_ref_group(
         CONSTRAINT x_sz_ref_agroup_PK_id PRIMARY KEY CLUSTERED(id)
 )
 GO
+CREATE TABLE dbo.x_security_zone_ref_role(
+        id bigint IDENTITY NOT NULL,
+        create_time datetime DEFAULT NULL NULL,
+        update_time datetime DEFAULT NULL NULL,
+        added_by_id bigint DEFAULT NULL NULL,
+        upd_by_id bigint DEFAULT NULL NULL,
+        zone_id bigint DEFAULT NULL NULL,
+        role_id bigint DEFAULT NULL NULL,
+        role_name varchar(767) DEFAULT NULL NULL
+        CONSTRAINT x_sz_ref_arole_PK_id PRIMARY KEY CLUSTERED(id)
+)
+GO
 CREATE TABLE dbo.x_policy_change_log(
         id bigint IDENTITY NOT NULL,
         create_time datetime DEFAULT NULL NULL,
@@ -1709,6 +1723,14 @@ ALTER TABLE dbo.x_security_zone_ref_group ADD CONSTRAINT 
x_sz_ref_grp_FK_zone_id
 GO
 ALTER TABLE dbo.x_security_zone_ref_group ADD CONSTRAINT 
x_sz_ref_grp_FK_group_id FOREIGN KEY(group_id) REFERENCES dbo.x_group (id)
 GO
+ALTER TABLE dbo.x_security_zone_ref_role ADD CONSTRAINT 
x_sz_ref_role_FK_added_by_id FOREIGN KEY(added_by_id) REFERENCES 
dbo.x_portal_user (id)
+GO
+ALTER TABLE dbo.x_security_zone_ref_role ADD CONSTRAINT 
x_sz_ref_role_FK_upd_by_id FOREIGN KEY(upd_by_id) REFERENCES dbo.x_portal_user 
(id)
+GO
+ALTER TABLE dbo.x_security_zone_ref_role ADD CONSTRAINT 
x_sz_ref_role_FK_zone_id FOREIGN KEY(zone_id) REFERENCES dbo.x_security_zone 
(id)
+GO
+ALTER TABLE dbo.x_security_zone_ref_role ADD CONSTRAINT 
x_sz_ref_role_FK_role_id FOREIGN KEY(role_id) REFERENCES dbo.x_role (id)
+GO
 
 ALTER TABLE dbo.x_role_ref_role ADD CONSTRAINT x_role_ref_role_FK_added_by_id 
FOREIGN KEY (added_by_id) REFERENCES dbo.x_portal_user (id)
 GO
@@ -2269,6 +2291,8 @@ INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active
 GO
 INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('065',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
 GO
+INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('075',CURRENT_TIMESTAMP,'Ranger 3.0.0',CURRENT_TIMESTAMP,'localhost','Y');
+GO
 INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('DB_PATCHES',CURRENT_TIMESTAMP,'Ranger 
1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
 GO
 INSERT INTO x_user_module_perm 
(user_id,module_id,create_time,update_time,added_by_id,upd_by_id,is_allowed) 
VALUES 
(dbo.getXportalUIdByLoginId('admin'),dbo.getModulesIdByName('Reports'),CURRENT_TIMESTAMP,CURRENT_TIMESTAMP,dbo.getXportalUIdByLoginId('admin'),dbo.getXportalUIdByLoginId('admin'),1);
diff --git 
a/security-admin/db/sqlanywhere/patches/075-create-sz-ref-role-table.sql 
b/security-admin/db/sqlanywhere/patches/075-create-sz-ref-role-table.sql
new file mode 100644
index 000000000..dce6fe6a3
--- /dev/null
+++ b/security-admin/db/sqlanywhere/patches/075-create-sz-ref-role-table.sql
@@ -0,0 +1,40 @@
+-- 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.
+
+call dbo.removeForeignKeysAndTable('x_security_zone_ref_role')
+GO
+
+CREATE TABLE dbo.x_security_zone_ref_role(
+        id bigint IDENTITY NOT NULL,
+        create_time datetime DEFAULT NULL NULL,
+        update_time datetime DEFAULT NULL NULL,
+        added_by_id bigint DEFAULT NULL NULL,
+        upd_by_id bigint DEFAULT NULL NULL,
+        zone_id bigint DEFAULT NULL NULL,
+        role_id bigint DEFAULT NULL NULL,
+        role_name varchar(767) DEFAULT NULL NULL
+        CONSTRAINT x_sz_ref_arole_PK_id PRIMARY KEY CLUSTERED(id)
+)
+GO
+
+ALTER TABLE dbo.x_security_zone_ref_role ADD CONSTRAINT 
x_sz_ref_role_FK_added_by_id FOREIGN KEY(added_by_id) REFERENCES 
dbo.x_portal_user (id)
+GO
+ALTER TABLE dbo.x_security_zone_ref_role ADD CONSTRAINT 
x_sz_ref_role_FK_upd_by_id FOREIGN KEY(upd_by_id) REFERENCES dbo.x_portal_user 
(id)
+GO
+ALTER TABLE dbo.x_security_zone_ref_role ADD CONSTRAINT 
x_sz_ref_role_FK_zone_id FOREIGN KEY(zone_id) REFERENCES dbo.x_security_zone 
(id)
+GO
+ALTER TABLE dbo.x_security_zone_ref_role ADD CONSTRAINT 
x_sz_ref_role_FK_role_id FOREIGN KEY(role_id) REFERENCES dbo.x_role (id)
+GO
+EXIT
\ No newline at end of file
diff --git 
a/security-admin/db/sqlserver/optimized/current/ranger_core_db_sqlserver.sql 
b/security-admin/db/sqlserver/optimized/current/ranger_core_db_sqlserver.sql
index bbef08859..465500814 100644
--- a/security-admin/db/sqlserver/optimized/current/ranger_core_db_sqlserver.sql
+++ b/security-admin/db/sqlserver/optimized/current/ranger_core_db_sqlserver.sql
@@ -545,6 +545,23 @@ IF (OBJECT_ID('x_sz_ref_user_FK_user_name') IS NOT NULL)
 BEGIN
     ALTER TABLE [dbo].[x_security_zone_ref_user] DROP CONSTRAINT 
x_sz_ref_user_FK_user_name
 END
+IF (OBJECT_ID('x_sz_ref_admin_role_FK_added_by_id') IS NOT NULL)
+BEGIN
+    ALTER TABLE [dbo].[x_security_zone_ref_role] DROP CONSTRAINT 
x_sz_ref_role_FK_added_by_id
+END
+IF (OBJECT_ID('x_sz_ref_role_FK_upd_by_id') IS NOT NULL)
+BEGIN
+    ALTER TABLE [dbo].[x_security_zone_ref_role] DROP CONSTRAINT 
x_sz_ref_role_FK_upd_by_id
+END
+IF (OBJECT_ID('x_sz_ref_role_FK_zone_id') IS NOT NULL)
+BEGIN
+    ALTER TABLE [dbo].[x_security_zone_ref_role] DROP CONSTRAINT 
x_sz_ref_role_FK_zone_id
+END
+IF (OBJECT_ID('x_sz_ref_role_FK_role_id') IS NOT NULL)
+BEGIN
+    ALTER TABLE [dbo].[x_security_zone_ref_role] DROP CONSTRAINT 
x_sz_ref_role_FK_role_id
+END
+
 IF (OBJECT_ID('x_sz_ref_resource_FK_added_by_id') IS NOT NULL)
 BEGIN
     ALTER TABLE [dbo].[x_security_zone_ref_resource] DROP CONSTRAINT 
x_sz_ref_resource_FK_added_by_id
@@ -837,6 +854,10 @@ IF (OBJECT_ID('x_security_zone_ref_user') IS NOT NULL)
 BEGIN
     DROP TABLE [dbo].[x_security_zone_ref_user]
 END
+IF (OBJECT_ID('x_security_zone_ref_role') IS NOT NULL)
+BEGIN
+    DROP TABLE [dbo].[x_security_zone_ref_role]
+END
 IF (OBJECT_ID('x_security_zone_ref_tag_srvc') IS NOT NULL)
 BEGIN
     DROP TABLE [dbo].[x_security_zone_ref_tag_srvc]
@@ -2597,6 +2618,33 @@ GO
 ALTER TABLE [dbo].[x_role_ref_role] WITH CHECK ADD CONSTRAINT 
[x_role_ref_role_FK_role_ref_id] FOREIGN KEY([role_ref_id]) REFERENCES 
[dbo].[x_role] ([id])
 GO
 
+SET ANSI_NULLS ON
+SET QUOTED_IDENTIFIER ON
+SET ANSI_PADDING ON
+CREATE TABLE [dbo].[x_security_zone_ref_role](
+        [id] [bigint] IDENTITY(1,1) NOT NULL,
+        [create_time] [datetime2] DEFAULT NULL NULL,
+        [update_time] [datetime2] DEFAULT NULL NULL,
+        [added_by_id] [bigint] DEFAULT NULL NULL,
+        [upd_by_id] [bigint] DEFAULT NULL NULL,
+        [zone_id] [bigint] DEFAULT NULL NULL,
+        [role_id] [bigint] DEFAULT NULL NULL,
+        [role_name] [nvarchar](767) DEFAULT NULL NULL
+        PRIMARY KEY CLUSTERED
+(
+        [id] ASC
+)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
+) ON [PRIMARY]
+GO
+ALTER TABLE [dbo].[x_security_zone_ref_role] WITH CHECK ADD CONSTRAINT 
[x_sz_ref_role_FK_added_by_id] FOREIGN KEY([added_by_id]) REFERENCES 
[dbo].[x_portal_user] ([id])
+GO
+ALTER TABLE [dbo].[x_security_zone_ref_role] WITH CHECK ADD CONSTRAINT 
[x_sz_ref_role_FK_upd_by_id] FOREIGN KEY([upd_by_id]) REFERENCES 
[dbo].[x_portal_user] ([id])
+GO
+ALTER TABLE [dbo].[x_security_zone_ref_role] WITH CHECK ADD CONSTRAINT 
[x_sz_ref_role_FK_zone_id] FOREIGN KEY([zone_id]) REFERENCES 
[dbo].[x_security_zone] ([id])
+GO
+ALTER TABLE [dbo].[x_security_zone_ref_role] WITH CHECK ADD CONSTRAINT 
[x_sz_ref_role_FK_role_id] FOREIGN KEY([role_id]) REFERENCES [dbo].[x_role] 
([id])
+GO
+
 SET ANSI_NULLS ON
 SET QUOTED_IDENTIFIER ON
 SET ANSI_PADDING ON
@@ -4113,6 +4161,7 @@ INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active
 INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('059',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
 INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('060',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
 INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('065',CURRENT_TIMESTAMP,'Ranger 1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
+INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('075',CURRENT_TIMESTAMP,'Ranger 3.0.0',CURRENT_TIMESTAMP,'localhost','Y');
 INSERT INTO x_db_version_h 
(version,inst_at,inst_by,updated_at,updated_by,active) VALUES 
('DB_PATCHES',CURRENT_TIMESTAMP,'Ranger 
1.0.0',CURRENT_TIMESTAMP,'localhost','Y');
 INSERT INTO x_user_module_perm 
(user_id,module_id,create_time,update_time,added_by_id,upd_by_id,is_allowed) 
VALUES 
(dbo.getXportalUIdByLoginId('admin'),dbo.getModulesIdByName('Reports'),CURRENT_TIMESTAMP,CURRENT_TIMESTAMP,dbo.getXportalUIdByLoginId('admin'),dbo.getXportalUIdByLoginId('admin'),1);
 INSERT INTO x_user_module_perm 
(user_id,module_id,create_time,update_time,added_by_id,upd_by_id,is_allowed) 
VALUES (dbo.getXportalUIdByLoginId('admin'),dbo.getModulesIdByName('Resource 
Based 
Policies'),CURRENT_TIMESTAMP,CURRENT_TIMESTAMP,dbo.getXportalUIdByLoginId('admin'),dbo.getXportalUIdByLoginId('admin'),1);
diff --git 
a/security-admin/db/sqlserver/patches/075-create-sz-ref-role-table.sql 
b/security-admin/db/sqlserver/patches/075-create-sz-ref-role-table.sql
new file mode 100644
index 000000000..6b4071865
--- /dev/null
+++ b/security-admin/db/sqlserver/patches/075-create-sz-ref-role-table.sql
@@ -0,0 +1,66 @@
+-- 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.
+
+IF (OBJECT_ID('x_sz_ref_admin_role_FK_added_by_id') IS NOT NULL)
+BEGIN
+    ALTER TABLE [dbo].[x_security_zone_ref_role] DROP CONSTRAINT 
x_sz_ref_role_FK_added_by_id
+END
+IF (OBJECT_ID('x_sz_ref_role_FK_upd_by_id') IS NOT NULL)
+BEGIN
+    ALTER TABLE [dbo].[x_security_zone_ref_role] DROP CONSTRAINT 
x_sz_ref_role_FK_upd_by_id
+END
+IF (OBJECT_ID('x_sz_ref_role_FK_zone_id') IS NOT NULL)
+BEGIN
+    ALTER TABLE [dbo].[x_security_zone_ref_role] DROP CONSTRAINT 
x_sz_ref_role_FK_zone_id
+END
+IF (OBJECT_ID('x_sz_ref_role_FK_role_id') IS NOT NULL)
+BEGIN
+    ALTER TABLE [dbo].[x_security_zone_ref_role] DROP CONSTRAINT 
x_sz_ref_role_FK_role_id
+END
+
+IF (OBJECT_ID('x_security_zone_ref_role') IS NOT NULL)
+BEGIN
+    DROP TABLE [dbo].[x_security_zone_ref_role]
+END
+
+CREATE TABLE [dbo].[x_security_zone_ref_role](
+        [id] [bigint] IDENTITY(1,1) NOT NULL,
+        [create_time] [datetime2] DEFAULT NULL NULL,
+        [update_time] [datetime2] DEFAULT NULL NULL,
+        [added_by_id] [bigint] DEFAULT NULL NULL,
+        [upd_by_id] [bigint] DEFAULT NULL NULL,
+        [zone_id] [bigint] DEFAULT NULL NULL,
+        [role_id] [bigint] DEFAULT NULL NULL,
+        [role_name] [nvarchar](767) DEFAULT NULL NULL
+        PRIMARY KEY CLUSTERED
+(
+        [id] ASC
+)WITH (PAD_INDEX = OFF, STATISTICS_NORECOMPUTE = OFF, IGNORE_DUP_KEY = OFF, 
ALLOW_ROW_LOCKS = ON, ALLOW_PAGE_LOCKS = ON) ON [PRIMARY],
+) ON [PRIMARY]
+GO
+ALTER TABLE [dbo].[x_security_zone_ref_role] WITH CHECK ADD CONSTRAINT 
[x_sz_ref_role_FK_added_by_id] FOREIGN KEY([added_by_id]) REFERENCES 
[dbo].[x_portal_user] ([id])
+GO
+ALTER TABLE [dbo].[x_security_zone_ref_role] WITH CHECK ADD CONSTRAINT 
[x_sz_ref_role_FK_upd_by_id] FOREIGN KEY([upd_by_id]) REFERENCES 
[dbo].[x_portal_user] ([id])
+GO
+ALTER TABLE [dbo].[x_security_zone_ref_role] WITH CHECK ADD CONSTRAINT 
[x_sz_ref_role_FK_zone_id] FOREIGN KEY([zone_id]) REFERENCES 
[dbo].[x_security_zone] ([id])
+GO
+ALTER TABLE [dbo].[x_security_zone_ref_role] WITH CHECK ADD CONSTRAINT 
[x_sz_ref_role_FK_role_id] FOREIGN KEY([role_id]) REFERENCES [dbo].[x_role] 
([id])
+GO
+
+SET ANSI_NULLS ON
+SET QUOTED_IDENTIFIER ON
+SET ANSI_PADDING ON
+
+exit
\ No newline at end of file
diff --git 
a/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java 
b/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java
index c19e3e1a1..12983688b 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/RoleDBStore.java
@@ -185,6 +185,12 @@ public class RoleDBStore implements RoleStore {
                        throw new Exception("Rolename for '" + roleName
                                        + "' can not be updated as it is 
referenced in one or more other roles");
                }
+
+               boolean rleNotInZone = ensureRoleNotInZone(roleName);
+
+               if(!rleNotInZone) {
+                       throw new Exception("Rolename for '"+ roleName + "' can 
not be updated as it is referenced in one or more security zones");
+               }
        }
 
        @Override
@@ -236,6 +242,12 @@ public class RoleDBStore implements RoleStore {
         if(!roleNotInOtherRole) {
             throw new Exception("Role '"+ roleName + "' can not be deleted as 
it is referenced in one or more other roles");
         }
+
+        boolean rleNotInZone = ensureRoleNotInZone(roleName);
+
+        if(!rleNotInZone) {
+            throw new Exception("Role '"+ roleName + "' can not be deleted as 
it is referenced in one or more security zones");
+        }
     }
 
        private boolean ensureRoleNotInPolicy(String roleName) {
@@ -250,6 +262,12 @@ public class RoleDBStore implements RoleStore {
                return roleRefRoleCount < 1;
        }
 
+    private boolean ensureRoleNotInZone(String roleName) {
+        Long roleRefZoneCount = 
daoMgr.getXXSecurityZoneRefRole().findRoleRefZoneCount(roleName);
+
+        return roleRefZoneCount < 1;
+    }
+
     @Override
     public RangerRole getRole(Long id) throws Exception {
         return roleService.read(id);
diff --git 
a/security-admin/src/main/java/org/apache/ranger/biz/SecurityZoneRefUpdater.java
 
b/security-admin/src/main/java/org/apache/ranger/biz/SecurityZoneRefUpdater.java
index ebc26528c..10bbfcd32 100644
--- 
a/security-admin/src/main/java/org/apache/ranger/biz/SecurityZoneRefUpdater.java
+++ 
b/security-admin/src/main/java/org/apache/ranger/biz/SecurityZoneRefUpdater.java
@@ -31,14 +31,17 @@ import org.apache.ranger.common.RangerConstants;
 import org.apache.ranger.db.RangerDaoManager;
 import org.apache.ranger.db.XXSecurityZoneRefGroupDao;
 import org.apache.ranger.db.XXSecurityZoneRefResourceDao;
+import org.apache.ranger.db.XXSecurityZoneRefRoleDao;
 import org.apache.ranger.db.XXSecurityZoneRefServiceDao;
 import org.apache.ranger.db.XXSecurityZoneRefTagServiceDao;
 import org.apache.ranger.db.XXSecurityZoneRefUserDao;
 import org.apache.ranger.entity.XXGroup;
 import org.apache.ranger.entity.XXPolicy;
 import org.apache.ranger.entity.XXResourceDef;
+import org.apache.ranger.entity.XXRole;
 import org.apache.ranger.entity.XXSecurityZoneRefGroup;
 import org.apache.ranger.entity.XXSecurityZoneRefResource;
+import org.apache.ranger.entity.XXSecurityZoneRefRole;
 import org.apache.ranger.entity.XXSecurityZoneRefService;
 import org.apache.ranger.entity.XXSecurityZoneRefTagService;
 import org.apache.ranger.entity.XXSecurityZoneRefUser;
@@ -94,18 +97,19 @@ public class SecurityZoneRefUpdater {
                final Long zoneId = rangerSecurityZone == null ? null : 
rangerSecurityZone.getId();
                final Map<String, RangerSecurityZoneService> zoneServices = 
rangerSecurityZone.getServices();
 
-               final Set<String> adminUsers = new HashSet<>();
-               final Set<String> adminUserGroups = new HashSet<>();
-               final Set<String> auditUsers = new HashSet<>();
-               final Set<String> auditUserGroups = new HashSet<>();
-                final Set<String> tagServices = new HashSet<>();
-               XXServiceDef xServiceDef = new XXServiceDef();
-
-               adminUsers.addAll(rangerSecurityZone.getAdminUsers());
-               adminUserGroups.addAll(rangerSecurityZone.getAdminUserGroups());
-               auditUsers.addAll(rangerSecurityZone.getAuditUsers());
-               auditUserGroups.addAll(rangerSecurityZone.getAuditUserGroups());
-                tagServices.addAll(rangerSecurityZone.getTagServices());
+               final Set<String> users = new HashSet<>();
+               final Set<String> userGroups = new HashSet<>();
+               final Set<String> roles = new HashSet<>();
+               final Set<String> tagServices = new HashSet<>();
+
+               users.addAll(rangerSecurityZone.getAdminUsers());
+               userGroups.addAll(rangerSecurityZone.getAdminUserGroups());
+               roles.addAll(rangerSecurityZone.getAdminRoles());
+               users.addAll(rangerSecurityZone.getAuditUsers());
+               userGroups.addAll(rangerSecurityZone.getAuditUserGroups());
+               roles.addAll(rangerSecurityZone.getAuditRoles());
+               tagServices.addAll(rangerSecurityZone.getTagServices());
+
                for(Map.Entry<String, RangerSecurityZoneService> service : 
zoneServices.entrySet()) {
                        String serviceName = service.getKey();
 
@@ -115,8 +119,7 @@ public class SecurityZoneRefUpdater {
 
                        XXService xService = 
daoMgr.getXXService().findByName(serviceName);
                        RangerService rService = 
svcService.getPopulatedViewObject(xService);
-                       xServiceDef = 
daoMgr.getXXServiceDef().findByName(rService.getType());
-
+                       XXServiceDef xServiceDef = 
daoMgr.getXXServiceDef().findByName(rService.getType());
                        XXSecurityZoneRefService xZoneService = 
rangerAuditFields.populateAuditFieldsForCreate(new XXSecurityZoneRefService());
 
                        xZoneService.setZoneId(zoneId);
@@ -174,102 +177,76 @@ public class SecurityZoneRefUpdater {
                         }
                 }
 
-               if(CollectionUtils.isNotEmpty(adminUsers)) {
-                       for(String adminUser : adminUsers) {
+               if(CollectionUtils.isNotEmpty(users)) {
+                       for(String user : users) {
 
-                               if (StringUtils.isBlank(adminUser)) {
+                               if (StringUtils.isBlank(user)) {
                                        continue;
                                }
 
-                               XXUser xUser = 
daoMgr.getXXUser().findByUserName(adminUser);
+                               XXUser xUser = 
daoMgr.getXXUser().findByUserName(user);
 
                                if (xUser == null) {
-                                       throw 
restErrorUtil.createRESTException("user with name: " + adminUser + " does not 
exist ",
+                                       throw 
restErrorUtil.createRESTException("user with name: " + user + " does not exist 
",
                                                        
MessageEnums.INVALID_INPUT_DATA);
                                }
 
-                               XXSecurityZoneRefUser xZoneAdminUser = 
rangerAuditFields.populateAuditFieldsForCreate(new XXSecurityZoneRefUser());
+                               XXSecurityZoneRefUser xZoneUser = 
rangerAuditFields.populateAuditFieldsForCreate(new XXSecurityZoneRefUser());
 
-                               xZoneAdminUser.setZoneId(zoneId);
-                               xZoneAdminUser.setUserId(xUser.getId());
-                               xZoneAdminUser.setUserName(adminUser);
-                               xZoneAdminUser.setUserType(1);
+                               xZoneUser.setZoneId(zoneId);
+                               xZoneUser.setUserId(xUser.getId());
+                               xZoneUser.setUserName(user);
+                               xZoneUser.setUserType(1);
 
-                               
daoMgr.getXXSecurityZoneRefUser().create(xZoneAdminUser);
+                               
daoMgr.getXXSecurityZoneRefUser().create(xZoneUser);
                        }
                }
 
-               if(CollectionUtils.isNotEmpty(adminUserGroups)) {
-                       for(String adminUserGroup : adminUserGroups) {
+               if(CollectionUtils.isNotEmpty(userGroups)) {
+                       for(String userGroup : userGroups) {
 
-                               if (StringUtils.isBlank(adminUserGroup)) {
+                               if (StringUtils.isBlank(userGroup)) {
                                        continue;
                                }
 
-                               XXGroup xGroup = 
daoMgr.getXXGroup().findByGroupName(adminUserGroup);
+                               XXGroup xGroup = 
daoMgr.getXXGroup().findByGroupName(userGroup);
 
                                if (xGroup == null) {
-                                       throw 
restErrorUtil.createRESTException("group with name: " + adminUserGroup + " does 
not exist ",
-                                                       
MessageEnums.INVALID_INPUT_DATA);
-                               }
-
-                               XXSecurityZoneRefGroup xZoneAdminGroup = 
rangerAuditFields.populateAuditFieldsForCreate(new XXSecurityZoneRefGroup());
-
-                               xZoneAdminGroup.setZoneId(zoneId);
-                               xZoneAdminGroup.setGroupId(xGroup.getId());
-                               xZoneAdminGroup.setGroupName(adminUserGroup);
-                               xZoneAdminGroup.setGroupType(1);
-
-                               
daoMgr.getXXSecurityZoneRefGroup().create(xZoneAdminGroup);
-                       }
-               }
-
-               if(CollectionUtils.isNotEmpty(auditUsers)) {
-                       for(String auditUser : auditUsers) {
-
-                               if (StringUtils.isBlank(auditUser)) {
-                                       continue;
-                               }
-
-                               XXUser xUser = 
daoMgr.getXXUser().findByUserName(auditUser);
-
-                               if (xUser == null) {
-                                       throw 
restErrorUtil.createRESTException("user with name: " + auditUser + " does not 
exist ",
+                                       throw 
restErrorUtil.createRESTException("group with name: " + userGroup + " does not 
exist ",
                                                        
MessageEnums.INVALID_INPUT_DATA);
                                }
 
-                               XXSecurityZoneRefUser xZoneAuditUser = 
rangerAuditFields.populateAuditFieldsForCreate(new XXSecurityZoneRefUser());
+                               XXSecurityZoneRefGroup xZoneGroup = 
rangerAuditFields.populateAuditFieldsForCreate(new XXSecurityZoneRefGroup());
 
-                               xZoneAuditUser.setZoneId(zoneId);
-                               xZoneAuditUser.setUserId(xUser.getId());
-                               xZoneAuditUser.setUserName(auditUser);
-                               xZoneAuditUser.setUserType(0);
+                               xZoneGroup.setZoneId(zoneId);
+                               xZoneGroup.setGroupId(xGroup.getId());
+                               xZoneGroup.setGroupName(userGroup);
+                               xZoneGroup.setGroupType(1);
 
-                               
daoMgr.getXXSecurityZoneRefUser().create(xZoneAuditUser);
+                               
daoMgr.getXXSecurityZoneRefGroup().create(xZoneGroup);
                        }
                }
 
-               if(CollectionUtils.isNotEmpty(auditUserGroups)) {
-                       for(String auditUserGroup : auditUserGroups) {
-                               if (StringUtils.isBlank(auditUserGroup)) {
+               if(CollectionUtils.isNotEmpty(roles)) {
+                       for(String role : roles) {
+                               if (StringUtils.isBlank(role)) {
                                        continue;
                                }
 
-                               XXGroup xGroup = 
daoMgr.getXXGroup().findByGroupName(auditUserGroup);
+                               XXRole xRole = 
daoMgr.getXXRole().findByRoleName(role);
 
-                               if (xGroup == null) {
-                                       throw 
restErrorUtil.createRESTException("group with name: " + auditUserGroup + " does 
not exist ",
+                               if (xRole == null) {
+                                       throw 
restErrorUtil.createRESTException("role with name: " + role + " does not exist 
",
                                                        
MessageEnums.INVALID_INPUT_DATA);
                                }
 
-                               XXSecurityZoneRefGroup xZoneAuditGroup = 
rangerAuditFields.populateAuditFieldsForCreate(new XXSecurityZoneRefGroup());
+                               XXSecurityZoneRefRole xZoneRole = 
rangerAuditFields.populateAuditFieldsForCreate(new XXSecurityZoneRefRole());
 
-                               xZoneAuditGroup.setZoneId(zoneId);
-                               xZoneAuditGroup.setGroupId(xGroup.getId());
-                               xZoneAuditGroup.setGroupName(auditUserGroup);
-                               xZoneAuditGroup.setGroupType(0);
+                               xZoneRole.setZoneId(zoneId);
+                               xZoneRole.setRoleId(xRole.getId());
+                               xZoneRole.setRoleName(role);
 
-                               
daoMgr.getXXSecurityZoneRefGroup().create(xZoneAuditGroup);
+                               
daoMgr.getXXSecurityZoneRefRole().create(xZoneRole);
                        }
                }
        }
@@ -282,19 +259,20 @@ public class SecurityZoneRefUpdater {
                        return false;
                }
 
-               XXSecurityZoneRefServiceDao     xZoneServiceDao      = 
daoMgr.getXXSecurityZoneRefService();
-                XXSecurityZoneRefTagServiceDao     xZoneTagServiceDao      = 
daoMgr.getXXSecurityZoneRefTagService();
-               XXSecurityZoneRefResourceDao        xZoneResourceDao    = 
daoMgr.getXXSecurityZoneRefResource();
-               XXSecurityZoneRefUserDao         xZoneUserDao     = 
daoMgr.getXXSecurityZoneRefUser();
-               XXSecurityZoneRefGroupDao   xZoneGroupDao   = 
daoMgr.getXXSecurityZoneRefGroup();
+               XXSecurityZoneRefServiceDao    xZoneServiceDao    = 
daoMgr.getXXSecurityZoneRefService();
+               XXSecurityZoneRefTagServiceDao xZoneTagServiceDao = 
daoMgr.getXXSecurityZoneRefTagService();
+               XXSecurityZoneRefResourceDao   xZoneResourceDao   = 
daoMgr.getXXSecurityZoneRefResource();
+               XXSecurityZoneRefUserDao       xZoneUserDao       = 
daoMgr.getXXSecurityZoneRefUser();
+               XXSecurityZoneRefGroupDao      xZoneGroupDao      = 
daoMgr.getXXSecurityZoneRefGroup();
+               XXSecurityZoneRefRoleDao       xZoneRoleDao      = 
daoMgr.getXXSecurityZoneRefRole();
 
                for (XXSecurityZoneRefService service : 
xZoneServiceDao.findByZoneId(zoneId)) {
                        xZoneServiceDao.remove(service);
                }
 
-                for (XXSecurityZoneRefTagService service : 
xZoneTagServiceDao.findByZoneId(zoneId)) {
-                        xZoneTagServiceDao.remove(service);
-                }
+               for (XXSecurityZoneRefTagService service : 
xZoneTagServiceDao.findByZoneId(zoneId)) {
+                       xZoneTagServiceDao.remove(service);
+               }
 
                for(XXSecurityZoneRefResource resource : 
xZoneResourceDao.findByZoneId(zoneId)) {
                        xZoneResourceDao.remove(resource);
@@ -308,6 +286,10 @@ public class SecurityZoneRefUpdater {
                        xZoneGroupDao.remove(group);
                }
 
+               for(XXSecurityZoneRefRole role : 
xZoneRoleDao.findByZoneId(zoneId)) {
+                       xZoneRoleDao.remove(role);
+               }
+
                return true;
        }
 
diff --git a/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java 
b/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java
index 77f86a0ad..be360a66e 100644
--- a/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java
+++ b/security-admin/src/main/java/org/apache/ranger/biz/ServiceMgr.java
@@ -23,10 +23,13 @@ import java.io.File;
 import java.net.URL;
 import java.net.URLClassLoader;
 import java.util.ArrayList;
+import java.util.Collections;
 import java.util.Date;
 import java.util.HashMap;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
+import java.util.Set;
 import java.util.concurrent.Callable;
 import java.util.concurrent.TimeUnit;
 
@@ -46,6 +49,8 @@ import org.apache.ranger.plugin.service.RangerBaseService;
 import org.apache.ranger.plugin.service.ResourceLookupContext;
 import org.apache.ranger.plugin.store.EmbeddedServiceDefsUtil;
 import org.apache.ranger.plugin.store.ServiceStore;
+import org.apache.ranger.plugin.util.RangerRoles;
+import org.apache.ranger.plugin.util.RangerRolesUtil;
 import org.apache.ranger.service.RangerServiceService;
 import org.apache.ranger.services.tag.RangerServiceTag;
 import org.apache.ranger.view.VXMessage;
@@ -81,6 +86,9 @@ public class ServiceMgr {
        @Autowired
        TagDBStore tagStore;
 
+       @Autowired
+       RoleDBStore rolesStore;
+
        @Autowired
        TimedExecutor timedExecutor;
 
@@ -224,9 +232,14 @@ public class ServiceMgr {
 
                        if (securityZone.getAdminUsers() != null && 
securityZone.getAdminUsers().contains(userId)) {
                                isZoneAdmin = true;
-                       } else if (securityZone.getAdminUserGroups() != null) {
+                       }
+
+                       Set<String> loggedInUsersGroups = 
Collections.emptySet();
+
+                       if (!isZoneAdmin && securityZone.getAdminUserGroups() 
!= null) {
                                List<XXGroupUser> groupUsers          = 
groupUserDao.findByUserId(rangerBizUtil.getXUserId());
-                               List<String>      loggedInUsersGroups = new 
ArrayList<>();
+
+                               loggedInUsersGroups = new HashSet<>();
 
                                loggedInUsersGroups.add(GROUP_PUBLIC);
 
@@ -238,6 +251,10 @@ public class ServiceMgr {
 
                                isZoneAdmin = 
CollectionUtils.containsAny(securityZone.getAdminUserGroups(), 
loggedInUsersGroups);
                        }
+
+                       if (!isZoneAdmin && securityZone.getAdminRoles() != 
null) {
+                               isZoneAdmin = isUserOrUserGroupsInRole(userId, 
loggedInUsersGroups, securityZone.getAdminRoles());
+                       }
                }
 
                return isZoneAdmin;
@@ -258,9 +275,14 @@ public class ServiceMgr {
 
                        if (securityZone.getAuditUsers() != null && 
securityZone.getAuditUsers().contains(userId)) {
                                isZoneAuditor = true;
-                       } else if (securityZone.getAuditUserGroups() != null) {
+                       }
+
+                       Set<String> loggedInUsersGroups = 
Collections.emptySet();
+
+                       if (!isZoneAuditor && securityZone.getAuditUserGroups() 
!= null) {
                                List<XXGroupUser> groupUsers          = 
groupUserDao.findByUserId(rangerBizUtil.getXUserId());
-                               List<String>      loggedInUsersGroups = new 
ArrayList<>();
+
+                               loggedInUsersGroups = new HashSet<>();
 
                                loggedInUsersGroups.add(GROUP_PUBLIC);
 
@@ -272,6 +294,10 @@ public class ServiceMgr {
 
                                isZoneAuditor = 
CollectionUtils.containsAny(securityZone.getAuditUserGroups(), 
loggedInUsersGroups);
                        }
+
+                       if (!isZoneAuditor && securityZone.getAuditRoles() != 
null) {
+                               isZoneAuditor = 
isUserOrUserGroupsInRole(userId, loggedInUsersGroups, 
securityZone.getAuditRoles());
+                       }
                }
 
                return isZoneAuditor;
@@ -511,7 +537,36 @@ public class ServiceMgr {
                vXResponse.setStatusCode(statusCode);
                return vXResponse;
        }
-       
+
+       private boolean isUserOrUserGroupsInRole(String userId, Set<String> 
userGroups, List<String> roles) {
+               boolean      ret         = false;
+               RangerRoles  rangerRoles = null;
+
+               try {
+                       rangerRoles = rolesStore.getRoles("", -1L);
+               } catch (Exception excp) {
+                       LOG.error("Unexpected error when fetching roles from 
database", excp);
+               }
+
+               if (rangerRoles != null) {
+                       RangerRolesUtil rolesUtil = new 
RangerRolesUtil(rangerRoles);
+
+                       ret = CollectionUtils.containsAny(roles, 
rolesUtil.getUserRoleMapping().get(userId));
+
+                       if (!ret && userGroups != null) {
+                               for (String userGroup : userGroups) {
+                                       ret = 
CollectionUtils.containsAny(roles, 
rolesUtil.getGroupRoleMapping().get(userGroup));
+
+                                       if (ret) {
+                                               break;
+                                       }
+                               }
+                       }
+               }
+
+               return ret;
+       }
+
        static final long _DefaultTimeoutValue_Lookp = 1000; // 1 s
        static final long _DefaultTimeoutValue_ValidateConfig = 10000; // 10 s
 
diff --git 
a/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java 
b/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java
index 10d73a76c..300c8b4bb 100644
--- 
a/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java
+++ 
b/security-admin/src/main/java/org/apache/ranger/db/RangerDaoManagerBase.java
@@ -301,6 +301,8 @@ public abstract class RangerDaoManagerBase {
 
        public XXSecurityZoneRefGroupDao getXXSecurityZoneRefGroup() { return 
new XXSecurityZoneRefGroupDao(this); }
 
+       public XXSecurityZoneRefRoleDao getXXSecurityZoneRefRole() { return new 
XXSecurityZoneRefRoleDao(this); }
+
        public XXGlobalStateDao getXXGlobalState() { return new 
XXGlobalStateDao(this); }
 
        public XXPolicyChangeLogDao getXXPolicyChangeLog() { return new 
XXPolicyChangeLogDao(this); }
diff --git 
a/security-admin/src/main/java/org/apache/ranger/db/XXSecurityZoneRefRoleDao.java
 
b/security-admin/src/main/java/org/apache/ranger/db/XXSecurityZoneRefRoleDao.java
new file mode 100644
index 000000000..65c602dea
--- /dev/null
+++ 
b/security-admin/src/main/java/org/apache/ranger/db/XXSecurityZoneRefRoleDao.java
@@ -0,0 +1,105 @@
+/*
+ * 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.db;
+
+import org.apache.ranger.common.db.BaseDao;
+import org.apache.ranger.entity.XXSecurityZoneRefRole;
+
+import javax.persistence.NoResultException;
+import java.util.Collections;
+import java.util.List;
+
+public class XXSecurityZoneRefRoleDao extends BaseDao<XXSecurityZoneRefRole>{
+
+       public XXSecurityZoneRefRoleDao(RangerDaoManagerBase daoManager) {
+               super(daoManager);
+       }
+
+       public List<XXSecurityZoneRefRole> findByZoneId(Long zoneId) {
+        if (zoneId == null) {
+            return null;
+        }
+        try {
+            List<XXSecurityZoneRefRole> xxZoneRefService = getEntityManager()
+                    .createNamedQuery("XXSecurityZoneRefRole.findByZoneId", 
tClass)
+                    .setParameter("zoneId", zoneId)
+                    .getResultList();
+            return xxZoneRefService;
+        } catch (NoResultException e) {
+            return null;
+        }
+    }
+
+       public List<XXSecurityZoneRefRole> findByRoleId(Long roleId) {
+               if (roleId == null) {
+                       return Collections.emptyList();
+               }
+               try {
+                       return 
getEntityManager().createNamedQuery("XXSecurityZoneRefRole.findByRoleId", 
tClass)
+                                       .setParameter("roleId", 
roleId).getResultList();
+               } catch (NoResultException e) {
+                       return Collections.emptyList();
+               }
+       }
+
+    public Long findRoleRefZoneCount(String roleName) {
+        Long ret = -1L;
+
+        try {
+            ret = 
getEntityManager().createNamedQuery("XXSecurityZoneRefRole.findRoleRefZoneCount",
 Long.class)
+                    .setParameter("roleName", roleName).getSingleResult();
+        } catch (Exception e) {
+        }
+
+        return ret;
+    }
+
+       public List<XXSecurityZoneRefRole> findAdminRoleByZoneId(Long zoneId) {
+        if (zoneId == null) {
+            return null;
+        }
+        try {
+            List<XXSecurityZoneRefRole> xxZoneRefRole = getEntityManager()
+                    
.createNamedQuery("XXSecurityZoneRefRole.findRoleTypeByZoneId", tClass)
+                    .setParameter("zoneId", zoneId)
+                    .setParameter("roleType", "1")
+                    .getResultList();
+            return xxZoneRefRole;
+        } catch (NoResultException e) {
+            return null;
+        }
+    }
+
+       public List<XXSecurityZoneRefRole> findAuditRoleByZoneId(Long zoneId) {
+        if (zoneId == null) {
+            return null;
+        }
+        try {
+            List<XXSecurityZoneRefRole> xxZoneRefRole = getEntityManager()
+                    
.createNamedQuery("XXSecurityZoneRefRole.findRoleTypeByZoneId", tClass)
+                    .setParameter("zoneId", zoneId)
+                    .setParameter("roleType", "0")
+                    .getResultList();
+            return xxZoneRefRole;
+        } catch (NoResultException e) {
+            return null;
+        }
+    }
+}
diff --git 
a/security-admin/src/main/java/org/apache/ranger/entity/XXSecurityZoneRefRole.java
 
b/security-admin/src/main/java/org/apache/ranger/entity/XXSecurityZoneRefRole.java
new file mode 100644
index 000000000..aaf5b8929
--- /dev/null
+++ 
b/security-admin/src/main/java/org/apache/ranger/entity/XXSecurityZoneRefRole.java
@@ -0,0 +1,185 @@
+/*
+ * 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.entity;
+
+import javax.persistence.Cacheable;
+import javax.persistence.Column;
+import javax.persistence.Entity;
+import javax.persistence.GeneratedValue;
+import javax.persistence.GenerationType;
+import javax.persistence.Id;
+import javax.persistence.SequenceGenerator;
+import javax.persistence.Table;
+import javax.xml.bind.annotation.XmlRootElement;
+import java.util.Objects;
+
+@Entity
+@Cacheable
+@XmlRootElement
+@Table(name = "x_security_zone_ref_role")
+public class XXSecurityZoneRefRole extends XXDBBase implements 
java.io.Serializable{
+       private static final long serialVersionUID = 1L;
+       @Id
+    @SequenceGenerator(name = "x_sec_zone_ref_role_SEQ", sequenceName = 
"x_sec_zone_ref_role_SEQ", allocationSize = 1)
+    @GeneratedValue(strategy = GenerationType.AUTO, generator = 
"x_sec_zone_ref_role_SEQ")
+    @Column(name = "id")
+    protected Long id;
+
+       /**
+        * zoneId of the XXSecurityZoneRefRole
+        * <ul>
+        * </ul>
+        *
+        */
+       @Column(name = "zone_id")
+       protected Long zoneId;
+
+       /**
+        * roleId of the XXSecurityZoneRefRole
+        * <ul>
+        * </ul>
+        *
+        */
+       @Column(name = "role_id")
+       protected Long roleId;
+
+       /**
+        * roleName of the XXSecurityZoneRefRole
+        * <ul>
+        * </ul>
+        *
+        */
+       @Column(name = "role_name")
+       protected String roleName;
+
+       /**
+        * roleType of the XXSecurityZoneRefRole , 1 for admin,0 for audit user.
+        * <ul>
+        * </ul>
+        *
+        */
+    @Override
+    public void setId(Long id) {
+        this.id = id;
+    }
+
+    @Override
+    public Long getId() {
+        return id;
+    }
+
+    /**
+        * This method sets the value to the member attribute <b> zoneId</b> .
+        * You cannot set null to the attribute.
+        *
+        * @param zoneId
+        *            Value to set member attribute <b> zoneId</b>
+        */
+       public void setZoneId(Long zoneId) {
+               this.zoneId = zoneId;
+       }
+
+       /**
+        * Returns the value for the member attribute <b>zoneId</b>
+        *
+        * @return Date - value of member attribute <b>zoneId</b> .
+        */
+       public Long getZoneId() {
+               return this.zoneId;
+       }
+
+       /**
+        * This method sets the value to the member attribute <b> roleId</b> .
+        * You cannot set null to the attribute.
+        *
+        * @param roleId
+        *            Value to set member attribute <b> roleId</b>
+        */
+       public void setRoleId(Long roleId) {
+               this.roleId = roleId;
+       }
+
+       /**
+        * Returns the value for the member attribute <b>roleId</b>
+        *
+        * @return Date - value of member attribute <b>roleId</b> .
+        */
+       public Long getRoleId() {
+               return roleId;
+       }
+
+       /**
+        * This method sets the value to the member attribute <b> roleName</b> .
+        * You cannot set null to the attribute.
+        *
+        * @param roleName
+        *            Value to set member attribute <b> roleName</b>
+        */
+       public void setRoleName(String roleName) {
+               this.roleName = roleName;
+       }
+
+       /**
+        * Returns the value for the member attribute <b>roleName</b>
+        *
+        * @return Date - value of member attribute <b>roleName</b> .
+        */
+       public String getRoleName() {
+               return roleName;
+       }
+
+       @Override
+       public int hashCode() {
+               return Objects.hash(super.hashCode(), id, zoneId, roleId, 
roleName);
+       }
+
+       /*
+        * (non-Javadoc)
+        *
+        * @see java.lang.Object#equals(java.lang.Object)
+        */
+       @Override
+       public boolean equals(Object obj) {
+               if (this == obj) {
+                       return true;
+               }
+
+               if (getClass() != obj.getClass()) {
+                       return false;
+               }
+
+               XXSecurityZoneRefRole other = (XXSecurityZoneRefRole) obj;
+
+               return super.equals(obj) &&
+                          Objects.equals(id, other.id) &&
+                          Objects.equals(zoneId, other.zoneId) &&
+                          Objects.equals(roleId, other.roleId) &&
+                          Objects.equals(roleName, other.roleName);
+       }
+
+       /* (non-Javadoc)
+        * @see java.lang.Object#toString()
+        */
+       @Override
+       public String toString() {
+               return "XXSecurityZoneRefRole [" + super.toString() + " id=" + 
id + ", zoneId=" + zoneId + ", roleId="
+                               + roleId + ", roleName=" + roleName + "]";
+       }
+}
\ No newline at end of file
diff --git 
a/security-admin/src/main/java/org/apache/ranger/rest/SecurityZoneREST.java 
b/security-admin/src/main/java/org/apache/ranger/rest/SecurityZoneREST.java
index 53aafae94..66fa22163 100644
--- a/security-admin/src/main/java/org/apache/ranger/rest/SecurityZoneREST.java
+++ b/security-admin/src/main/java/org/apache/ranger/rest/SecurityZoneREST.java
@@ -415,6 +415,9 @@ public class SecurityZoneREST {
                                        } else if 
(!Objects.equals(securityZone.getAdminUsers(), 
existingSecurityZone.getAdminUsers())) {
                                                throwRestError("User : " + 
userName
                                                                + " is not 
allowed to edit zone Admin User of zone : " + existingSecurityZone.getName());
+                    } else if (!Objects.equals(securityZone.getAdminRoles(), 
existingSecurityZone.getAdminRoles())) {
+                        throwRestError("User : " + userName
+                                + " is not allowed to edit zone Admin Roles of 
zone : " + existingSecurityZone.getName());
                                        } else if 
(!Objects.equals(securityZone.getAuditUsers(), 
existingSecurityZone.getAuditUsers())) {
                                                throwRestError("User : " + 
userName
                                                                + " is not 
allowed to edit zone Audit User of zone : " + existingSecurityZone.getName());
@@ -422,6 +425,10 @@ public class SecurityZoneREST {
                                                throwRestError("User : "
                                                                + userName
                                                                + " is not 
allowed to edit zone Audit User Group of zone : " + 
existingSecurityZone.getName());
+                    } else if (!Objects.equals(securityZone.getAuditRoles(), 
existingSecurityZone.getAuditRoles())) {
+                        throwRestError("User : "
+                                + userName
+                                + " is not allowed to edit zone Audit Roles of 
zone : " + existingSecurityZone.getName());
                                        }
                                }
                                
@@ -560,8 +567,10 @@ public class SecurityZoneREST {
                 bizUtil.removeEmptyStrings(securityZone.getTagServices());
                bizUtil.removeEmptyStrings(securityZone.getAdminUsers());
                bizUtil.removeEmptyStrings(securityZone.getAdminUserGroups());
+        bizUtil.removeEmptyStrings(securityZone.getAdminRoles());
                bizUtil.removeEmptyStrings(securityZone.getAuditUsers());
                bizUtil.removeEmptyStrings(securityZone.getAuditUserGroups());
+        bizUtil.removeEmptyStrings(securityZone.getAdminRoles());
                Map<String, RangerSecurityZoneService> 
serviceResouceMap=securityZone.getServices();
                if(serviceResouceMap!=null) {
                        Set<Map.Entry<String, RangerSecurityZoneService>> 
serviceResouceMapEntries = serviceResouceMap.entrySet();
diff --git 
a/security-admin/src/main/java/org/apache/ranger/service/RangerSecurityZoneServiceService.java
 
b/security-admin/src/main/java/org/apache/ranger/service/RangerSecurityZoneServiceService.java
index dfa9fbb69..476d1511b 100644
--- 
a/security-admin/src/main/java/org/apache/ranger/service/RangerSecurityZoneServiceService.java
+++ 
b/security-admin/src/main/java/org/apache/ranger/service/RangerSecurityZoneServiceService.java
@@ -117,8 +117,10 @@ public class RangerSecurityZoneServiceService extends 
RangerSecurityZoneServiceB
                 ret.setServices(zoneFromJsonData.getServices());
                 ret.setAdminUsers(zoneFromJsonData.getAdminUsers());
                 ret.setAdminUserGroups(zoneFromJsonData.getAdminUserGroups());
+                ret.setAdminRoles(zoneFromJsonData.getAdminRoles());
                 ret.setAuditUsers(zoneFromJsonData.getAuditUsers());
                 ret.setAuditUserGroups(zoneFromJsonData.getAuditUserGroups());
+                ret.setAuditRoles(zoneFromJsonData.getAuditRoles());
                 ret.setTagServices(zoneFromJsonData.getTagServices());
             }
         } else {
diff --git a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml 
b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
index d3cdecdca..14eca878f 100755
--- a/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
+++ b/security-admin/src/main/resources/META-INF/jpa_named_queries.xml
@@ -1646,6 +1646,24 @@
         </query>
     </named-query>
 
+       <named-query name="XXSecurityZoneRefRole.findByZoneId">
+               <query>
+                       select obj from XXSecurityZoneRefRole obj where 
obj.zoneId = :zoneId
+               </query>
+       </named-query>
+
+       <named-query name="XXSecurityZoneRefRole.findByRoleId">
+               <query>
+                       select obj from XXSecurityZoneRefRole obj where 
obj.roleId = :roleId
+               </query>
+       </named-query>
+
+       <named-query name="XXSecurityZoneRefRole.findRoleRefZoneCount">
+               <query>
+                       select count(obj.zoneId) from XXSecurityZoneRefRole obj 
where obj.roleName = :roleName
+               </query>
+       </named-query>
+
        <named-query name="XXSecurityZoneRefResource.findByZoneId">
         <query>
             select obj from XXSecurityZoneRefResource obj where obj.zoneId = 
:zoneId

Reply via email to