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
49 changes: 19 additions & 30 deletions fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Auth.java
Original file line number Diff line number Diff line change
Expand Up @@ -274,8 +274,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 @@ -297,8 +298,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 @@ -320,8 +322,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 @@ -343,8 +346,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 @@ -371,8 +375,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 @@ -384,8 +389,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 @@ -400,8 +406,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 @@ -422,8 +429,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 @@ -444,29 +452,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
46 changes: 12 additions & 34 deletions fe/fe-core/src/main/java/org/apache/doris/mysql/privilege/Role.java
Original file line number Diff line number Diff line change
Expand Up @@ -301,13 +301,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 @@ -351,8 +349,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 @@ -423,8 +420,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 @@ -445,14 +441,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 @@ -462,12 +457,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 @@ -484,8 +481,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 @@ -502,8 +498,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 @@ -526,12 +521,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 @@ -622,22 +616,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 @@ -223,7 +223,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
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
// 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.doris.mysql.privilege;

import org.apache.doris.analysis.CompoundPredicate.Operator;
import org.apache.doris.analysis.UserIdentity;
import org.apache.doris.catalog.Env;
import org.apache.doris.datasource.InternalCatalog;
import org.apache.doris.utframe.TestWithFeService;

import org.junit.jupiter.api.Test;

public class AuthTest extends TestWithFeService {
@Override
protected void runBeforeAll() throws Exception {
createDatabase("test");
}

@Test
public void testMergeRolePriv() throws Exception {
addUser("u1", true);
createRole("role1");
createRole("role2");
grantPriv("GRANT LOAD_PRIV ON internal.test.* TO ROLE 'role1';");
grantPriv("GRANT GRANT_PRIV ON internal.test.* TO ROLE 'role2';");

grantRole("GRANT 'role1','role2' TO 'u1'@'%'");
Env.getCurrentEnv().getAuth().checkDbPriv(UserIdentity.createAnalyzedUserIdentWithIp("u1", "%"),
InternalCatalog.INTERNAL_CATALOG_NAME, "test",
PrivPredicate.of(PrivBitSet.of(Privilege.GRANT_PRIV, Privilege.LOAD_PRIV), Operator.AND));
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,15 @@
import org.apache.doris.nereids.trees.plans.commands.AlterMTMVCommand;
import org.apache.doris.nereids.trees.plans.commands.CreateMTMVCommand;
import org.apache.doris.nereids.trees.plans.commands.CreatePolicyCommand;
import org.apache.doris.nereids.trees.plans.commands.CreateRoleCommand;
import org.apache.doris.nereids.trees.plans.commands.CreateTableCommand;
import org.apache.doris.nereids.trees.plans.commands.CreateUserCommand;
import org.apache.doris.nereids.trees.plans.commands.CreateViewCommand;
import org.apache.doris.nereids.trees.plans.commands.DropConstraintCommand;
import org.apache.doris.nereids.trees.plans.commands.DropMTMVCommand;
import org.apache.doris.nereids.trees.plans.commands.DropRowPolicyCommand;
import org.apache.doris.nereids.trees.plans.commands.GrantRoleCommand;
import org.apache.doris.nereids.trees.plans.commands.GrantTablePrivilegeCommand;
import org.apache.doris.nereids.trees.plans.commands.info.TableNameInfo;
import org.apache.doris.nereids.trees.plans.logical.LogicalPlan;
import org.apache.doris.nereids.util.MemoTestUtils;
Expand Down Expand Up @@ -821,6 +824,34 @@ protected void addUser(String userName, boolean ifNotExists) throws Exception {
}
}

protected void createRole(String roleName) throws Exception {
NereidsParser nereidsParser = new NereidsParser();
String sql = "CREATE ROLE " + roleName;
LogicalPlan parsed = nereidsParser.parseSingle(sql);
StmtExecutor stmtExecutor = new StmtExecutor(connectContext, sql);
if (parsed instanceof CreateRoleCommand) {
((CreateRoleCommand) parsed).run(connectContext, stmtExecutor);
}
}

protected void grantRole(String sql) throws Exception {
NereidsParser nereidsParser = new NereidsParser();
LogicalPlan parsed = nereidsParser.parseSingle(sql);
StmtExecutor stmtExecutor = new StmtExecutor(connectContext, sql);
if (parsed instanceof GrantRoleCommand) {
((GrantRoleCommand) parsed).run(connectContext, stmtExecutor);
}
}

protected void grantPriv(String sql) throws Exception {
NereidsParser nereidsParser = new NereidsParser();
LogicalPlan parsed = nereidsParser.parseSingle(sql);
StmtExecutor stmtExecutor = new StmtExecutor(connectContext, sql);
if (parsed instanceof GrantTablePrivilegeCommand) {
((GrantTablePrivilegeCommand) parsed).run(connectContext, stmtExecutor);
}
}

protected void addRollup(String sql) throws Exception {
AlterTableStmt alterTableStmt = (AlterTableStmt) UtFrameUtils.parseAndAnalyzeStmt(sql, connectContext);
Env.getCurrentEnv().alterTable(alterTableStmt);
Expand Down
Loading