Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -270,8 +270,9 @@ protected boolean checkGlobalPriv(UserIdentity currentUser, PrivPredicate wanted
readLock();
try {
Set<Role> roles = getRolesByUserWithLdap(currentUser);
PrivBitSet savedPrivs = PrivBitSet.of();
for (Role role : roles) {
if (role.checkGlobalPriv(wanted)) {
if (role.checkGlobalPriv(wanted, savedPrivs)) {
return true;
}
}
Expand All @@ -293,8 +294,9 @@ protected boolean checkCtlPriv(UserIdentity currentUser, String ctl, PrivPredica
readLock();
try {
Set<Role> roles = getRolesByUserWithLdap(currentUser);
PrivBitSet savedPrivs = PrivBitSet.of();
for (Role role : roles) {
if (role.checkCtlPriv(ctl, wanted)) {
if (role.checkCtlPriv(ctl, wanted, savedPrivs)) {
return true;
}
}
Expand All @@ -316,8 +318,9 @@ protected boolean checkDbPriv(UserIdentity currentUser, String ctl, String db, P
readLock();
try {
Set<Role> roles = getRolesByUserWithLdap(currentUser);
PrivBitSet savedPrivs = PrivBitSet.of();
for (Role role : roles) {
if (role.checkDbPriv(ctl, db, wanted)) {
if (role.checkDbPriv(ctl, db, wanted, savedPrivs)) {
return true;
}
}
Expand All @@ -339,8 +342,9 @@ protected boolean checkTblPriv(UserIdentity currentUser, String ctl, String db,
readLock();
try {
Set<Role> roles = getRolesByUserWithLdap(currentUser);
PrivBitSet savedPrivs = PrivBitSet.of();
for (Role role : roles) {
if (role.checkTblPriv(ctl, db, tbl, wanted)) {
if (role.checkTblPriv(ctl, db, tbl, wanted, savedPrivs)) {
return true;
}
}
Expand All @@ -367,8 +371,9 @@ protected void checkColsPriv(UserIdentity currentUser, String ctl, String db, St

private boolean checkColPriv(String ctl, String db, String tbl,
String col, PrivPredicate wanted, Set<Role> roles) {
PrivBitSet savedPrivs = PrivBitSet.of();
for (Role role : roles) {
if (role.checkColPriv(ctl, db, tbl, col, wanted)) {
if (role.checkColPriv(ctl, db, tbl, col, wanted, savedPrivs)) {
return true;
}
}
Expand All @@ -380,8 +385,9 @@ protected boolean checkResourcePriv(UserIdentity currentUser, String resourceNam
readLock();
try {
Set<Role> roles = getRolesByUserWithLdap(currentUser);
PrivBitSet savedPrivs = PrivBitSet.of();
for (Role role : roles) {
if (role.checkResourcePriv(resourceName, wanted)) {
if (role.checkResourcePriv(resourceName, wanted, savedPrivs)) {
return true;
}
}
Expand All @@ -396,8 +402,9 @@ protected boolean checkStorageVaultPriv(UserIdentity currentUser, String storage
readLock();
try {
Set<Role> roles = getRolesByUserWithLdap(currentUser);
PrivBitSet savedPrivs = PrivBitSet.of();
for (Role role : roles) {
if (role.checkStorageVaultPriv(storageVaultName, wanted)) {
if (role.checkStorageVaultPriv(storageVaultName, wanted, savedPrivs)) {
return true;
}
}
Expand All @@ -418,8 +425,9 @@ protected boolean checkWorkloadGroupPriv(UserIdentity currentUser, String worklo
}

Set<Role> roles = getRolesByUserWithLdap(currentUser);
PrivBitSet savedPrivs = PrivBitSet.of();
for (Role role : roles) {
if (role.checkWorkloadGroupPriv(workloadGroupName, wanted)) {
if (role.checkWorkloadGroupPriv(workloadGroupName, wanted, savedPrivs)) {
return true;
}
}
Expand All @@ -440,29 +448,10 @@ protected boolean checkCloudPriv(UserIdentity currentUser, String cloudName,
return true;
}
}
Set<String> roles = userRoleManager.getRolesByUser(currentUser);
for (String roleName : roles) {
if (roleManager.getRole(roleName).checkCloudPriv(cloudName, wanted, type)) {
return true;
}
}
return false;
} finally {
readUnlock();
}
}

// ==== Other ====
/*
* Check if current user has certain privilege.
* This method will check the given privilege levels
*/
public boolean checkHasPriv(ConnectContext ctx, PrivPredicate priv, PrivLevel... levels) {
readLock();
try {
Set<Role> roles = getRolesByUserWithLdap(ctx.getCurrentUserIdentity());
Set<Role> roles = getRolesByUserWithLdap(currentUser);
PrivBitSet savedPrivs = PrivBitSet.of();
for (Role role : roles) {
if (role.checkHasPriv(priv, levels)) {
if (role.checkCloudPriv(cloudName, wanted, type, savedPrivs)) {
return true;
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -312,13 +312,11 @@ public void merge(Role other) throws DdlException {
mergeNotCheck(other);
}

public boolean checkGlobalPriv(PrivPredicate wanted) {
PrivBitSet savedPrivs = PrivBitSet.of();
public boolean checkGlobalPriv(PrivPredicate wanted, PrivBitSet savedPrivs) {
return checkGlobalInternal(wanted, savedPrivs);
}

public boolean checkCtlPriv(String ctl, PrivPredicate wanted) {
PrivBitSet savedPrivs = PrivBitSet.of();
public boolean checkCtlPriv(String ctl, PrivPredicate wanted, PrivBitSet savedPrivs) {
if (checkGlobalInternal(wanted, savedPrivs)
|| checkCatalogInternal(ctl, wanted, savedPrivs)) {
return true;
Expand Down Expand Up @@ -362,8 +360,7 @@ private boolean checkCatalogInternal(String ctl, PrivPredicate wanted, PrivBitSe
return false;
}

public boolean checkDbPriv(String ctl, String db, PrivPredicate wanted) {
PrivBitSet savedPrivs = PrivBitSet.of();
public boolean checkDbPriv(String ctl, String db, PrivPredicate wanted, PrivBitSet savedPrivs) {
if (checkGlobalInternal(wanted, savedPrivs)
|| checkCatalogInternal(ctl, wanted, savedPrivs)
|| checkDbInternal(ctl, db, wanted, savedPrivs)) {
Expand Down Expand Up @@ -434,8 +431,7 @@ private boolean checkDbInternal(String ctl, String db, PrivPredicate wanted,
return false;
}

public boolean checkTblPriv(String ctl, String db, String tbl, PrivPredicate wanted) {
PrivBitSet savedPrivs = PrivBitSet.of();
public boolean checkTblPriv(String ctl, String db, String tbl, PrivPredicate wanted, PrivBitSet savedPrivs) {
if (checkGlobalInternal(wanted, savedPrivs)
|| checkCatalogInternal(ctl, wanted, savedPrivs)
|| checkDbInternal(ctl, db, wanted, savedPrivs)
Expand All @@ -456,14 +452,13 @@ public boolean checkTblPriv(String ctl, String db, String tbl, PrivPredicate wan
}

public boolean checkCloudPriv(String cloudName,
PrivPredicate wanted, ResourceTypeEnum type) {
PrivPredicate wanted, ResourceTypeEnum type, PrivBitSet savedPrivs) {
ResourcePrivTable cloudPrivTable = getCloudPrivTable(type);
if (cloudPrivTable == null) {
LOG.warn("cloud resource type err: {}", type);
return false;
}

PrivBitSet savedPrivs = PrivBitSet.of();
if (checkGlobalInternal(wanted, savedPrivs)
|| checkCloudInternal(cloudName, wanted, savedPrivs, cloudPrivTable, type)) {
return true;
Expand All @@ -473,12 +468,14 @@ public boolean checkCloudPriv(String cloudName,
return false;
}

public boolean checkColPriv(String ctl, String db, String tbl, String col, PrivPredicate wanted) {
public boolean checkColPriv(String ctl, String db, String tbl, String col, PrivPredicate wanted,
PrivBitSet savedPrivs) {
Optional<Privilege> colPrivilege = wanted.getColPrivilege();
if (!colPrivilege.isPresent()) {
throw new IllegalStateException("this privPredicate should not use checkColPriv:" + wanted);
}
return checkTblPriv(ctl, db, tbl, wanted) || onlyCheckColPriv(ctl, db, tbl, col, colPrivilege.get());
return checkTblPriv(ctl, db, tbl, wanted, savedPrivs) || onlyCheckColPriv(ctl, db, tbl, col,
colPrivilege.get());
}

private boolean onlyCheckColPriv(String ctl, String db, String tbl, String col,
Expand All @@ -495,8 +492,7 @@ private boolean checkTblInternal(String ctl, String db, String tbl, PrivPredicat
return Privilege.satisfy(savedPrivs, wanted);
}

public boolean checkResourcePriv(String resourceName, PrivPredicate wanted) {
PrivBitSet savedPrivs = PrivBitSet.of();
public boolean checkResourcePriv(String resourceName, PrivPredicate wanted, PrivBitSet savedPrivs) {
if (checkGlobalInternal(wanted, savedPrivs)
|| checkResourceInternal(resourceName, wanted, savedPrivs)) {
return true;
Expand All @@ -513,8 +509,7 @@ private boolean checkResourceInternal(String resourceName, PrivPredicate wanted,
return Privilege.satisfy(savedPrivs, wanted);
}

public boolean checkStorageVaultPriv(String storageVaultName, PrivPredicate wanted) {
PrivBitSet savedPrivs = PrivBitSet.of();
public boolean checkStorageVaultPriv(String storageVaultName, PrivPredicate wanted, PrivBitSet savedPrivs) {
if (checkGlobalInternal(wanted, savedPrivs)
|| checkStorageVaultInternal(storageVaultName, wanted, savedPrivs)) {
return true;
Expand All @@ -537,12 +532,11 @@ private boolean checkCloudInternal(String cloudName, PrivPredicate wanted,
return Privilege.satisfy(savedPrivs, wanted);
}

public boolean checkWorkloadGroupPriv(String workloadGroupName, PrivPredicate wanted) {
public boolean checkWorkloadGroupPriv(String workloadGroupName, PrivPredicate wanted, PrivBitSet savedPrivs) {
// For compatibility with older versions, it is not needed to check the privileges of the default group.
if (WorkloadGroupMgr.DEFAULT_GROUP_NAME.equals(workloadGroupName)) {
return true;
}
PrivBitSet savedPrivs = PrivBitSet.of();
// usage priv not in global, but grant_priv may in global
if (checkGlobalInternal(wanted, savedPrivs)
|| checkWorkloadGroupInternal(workloadGroupName, wanted, savedPrivs)) {
Expand Down Expand Up @@ -633,22 +627,6 @@ public void setComment(String comment) {
this.comment = comment;
}

public boolean checkCanEnterCluster(String clusterName) {
if (checkGlobalPriv(PrivPredicate.ALL)) {
return true;
}

if (dbPrivTable.hasClusterPriv(clusterName)) {
return true;
}

if (tablePrivTable.hasClusterPriv(clusterName)) {
return true;
}
return false;
}


private void grantPrivs(ResourcePattern resourcePattern, PrivBitSet privs) throws DdlException {
if (privs.isEmpty()) {
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -224,7 +224,7 @@ public void getRoleWorkloadGroupPrivs(List<List<String>> result, Set<String> lim
if (limitedRole != null && !limitedRole.contains(role.getRoleName())) {
continue;
}
String isGrantable = role.checkGlobalPriv(PrivPredicate.ADMIN) ? "YES" : "NO";
String isGrantable = role.checkGlobalPriv(PrivPredicate.ADMIN, PrivBitSet.of()) ? "YES" : "NO";

for (Map.Entry<WorkloadGroupPattern, PrivBitSet> entry : role.getWorkloadGroupPatternToPrivs().entrySet()) {
List<String> row = Lists.newArrayList();
Expand Down
38 changes: 38 additions & 0 deletions regression-test/suites/account_p0/test_grant_priv.groovy
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ suite("test_grant_priv") {
def user1 = 'test_grant_priv_user1'
def user2 = 'test_grant_priv_user2'
def role1 = 'test_grant_priv_role1'
def role2 = 'test_grant_priv_role2'
def pwd = '123456'
def dbName = 'test_grant_priv_db'
def tokens = context.config.jdbcUrl.split('/')
Expand All @@ -29,6 +30,7 @@ suite("test_grant_priv") {
sql """drop user if exists ${user1}"""
sql """drop user if exists ${user2}"""
sql """drop role if exists ${role1}"""
sql """drop role if exists ${role2}"""
sql """DROP DATABASE IF EXISTS ${dbName}"""

sql """CREATE DATABASE ${dbName}"""
Expand Down Expand Up @@ -82,5 +84,41 @@ suite("test_grant_priv") {
sql """drop user if exists ${user1}"""
sql """drop user if exists ${user2}"""
sql """drop role if exists ${role1}"""
sql """drop role if exists ${role2}"""

sql """CREATE ROLE ${role1}"""
sql """CREATE ROLE ${role2}"""
sql """CREATE USER '${user1}' IDENTIFIED BY '${pwd}'"""
// for login
sql """grant select_priv on ${dbName}.* to ${user1}"""
sql """CREATE USER '${user2}' IDENTIFIED BY '${pwd}'"""
sql """grant grant_priv on *.*.* to role '${role1}'"""
sql """grant select_priv on *.*.* to role '${role2}'"""
sql """grant '${role1}' to ${user1}"""
// test only have role1 can not grant
connect(user1, "${pwd}", url) {
test {
sql """grant select_priv on *.*.* to ${user2}"""
exception "denied"
}
}
sql """revoke '${role1}' from ${user1}"""
sql """grant '${role2}' to ${user1}"""
// test only have role2 can not grant
connect(user1, "${pwd}", url) {
test {
sql """grant select_priv on *.*.* to ${user2}"""
exception "denied"
}
}
// test both have role1 and role2 can grant to other
sql """grant '${role1}' to ${user1}"""
connect(user1, "${pwd}", url) {
sql """grant select_priv on *.*.* to ${user2}"""
}
sql """drop user if exists ${user1}"""
sql """drop user if exists ${user2}"""
sql """drop role if exists ${role1}"""
sql """drop role if exists ${role2}"""
sql """DROP DATABASE IF EXISTS ${dbName}"""
}