branch-2.1:[fix](auth)fix when authentication, the permissions of multiple roles should be merged #52349 (#52947)

pick #52349
This commit is contained in:
zhangdong
2025-07-24 17:06:32 +08:00
committed by GitHub
parent d316dbb3bd
commit 5873aa3083
4 changed files with 63 additions and 58 deletions

View File

@ -266,8 +266,9 @@ public class Auth implements Writable {
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;
}
}
@ -289,8 +290,9 @@ public class Auth implements Writable {
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;
}
}
@ -312,8 +314,9 @@ public class Auth implements Writable {
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;
}
}
@ -335,8 +338,9 @@ public class Auth implements Writable {
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;
}
}
@ -363,8 +367,9 @@ public class Auth implements Writable {
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;
}
}
@ -376,8 +381,9 @@ public class Auth implements Writable {
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;
}
}
@ -398,28 +404,9 @@ public class Auth implements Writable {
}
Set<Role> roles = getRolesByUserWithLdap(currentUser);
PrivBitSet savedPrivs = PrivBitSet.of();
for (Role role : roles) {
if (role.checkWorkloadGroupPriv(workloadGroupName, wanted)) {
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());
for (Role role : roles) {
if (role.checkHasPriv(priv, levels)) {
if (role.checkWorkloadGroupPriv(workloadGroupName, wanted, savedPrivs)) {
return true;
}
}

View File

@ -235,13 +235,11 @@ public class Role implements Writable, GsonPostProcessable {
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;
@ -285,8 +283,7 @@ public class Role implements Writable, GsonPostProcessable {
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)) {
@ -357,8 +354,7 @@ public class Role implements Writable, GsonPostProcessable {
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)
@ -378,12 +374,14 @@ public class Role implements Writable, GsonPostProcessable {
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,
@ -400,8 +398,7 @@ public class Role implements Writable, GsonPostProcessable {
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;
@ -418,12 +415,11 @@ public class Role implements Writable, GsonPostProcessable {
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)) {
@ -502,22 +498,6 @@ public class Role implements Writable, GsonPostProcessable {
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;

View File

@ -198,7 +198,7 @@ public class RoleManager implements Writable, GsonPostProcessable {
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();