[improvement](auth)Not allowed to operate internal_schema database (#29790)
Only root user can operate __internal_schema database The scope of impact includes: create database drop database alter database create table drop table alter table truncate table insert overwrite insert delete update load(root also not allowed) delete support check auth
This commit is contained in:
@ -21,6 +21,7 @@ import org.apache.doris.catalog.Env;
|
||||
import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.common.ErrorReport;
|
||||
import org.apache.doris.common.UserException;
|
||||
import org.apache.doris.common.util.InternalDatabaseUtil;
|
||||
import org.apache.doris.common.util.PrintableMap;
|
||||
import org.apache.doris.common.util.PropertyAnalyzer;
|
||||
import org.apache.doris.mysql.privilege.PrivPredicate;
|
||||
@ -51,7 +52,7 @@ public class AlterDatabasePropertyStmt extends DdlStmt {
|
||||
@Override
|
||||
public void analyze(Analyzer analyzer) throws UserException {
|
||||
super.analyze(analyzer);
|
||||
|
||||
InternalDatabaseUtil.checkDatabase(dbName, ConnectContext.get());
|
||||
if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) {
|
||||
ErrorReport.reportAnalysisException(ErrorCode.ERR_DBACCESS_DENIED_ERROR,
|
||||
analyzer.getQualifiedUser(), dbName);
|
||||
|
||||
@ -21,6 +21,7 @@ import org.apache.doris.catalog.Env;
|
||||
import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.common.ErrorReport;
|
||||
import org.apache.doris.common.UserException;
|
||||
import org.apache.doris.common.util.InternalDatabaseUtil;
|
||||
import org.apache.doris.common.util.ParseUtil;
|
||||
import org.apache.doris.mysql.privilege.PrivPredicate;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
@ -61,7 +62,7 @@ public class AlterDatabaseQuotaStmt extends DdlStmt {
|
||||
@Override
|
||||
public void analyze(Analyzer analyzer) throws UserException {
|
||||
super.analyze(analyzer);
|
||||
|
||||
InternalDatabaseUtil.checkDatabase(dbName, ConnectContext.get());
|
||||
if (!Env.getCurrentEnv().getAccessManager().checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) {
|
||||
ErrorReport.reportAnalysisException(ErrorCode.ERR_DBACCESS_DENIED_ERROR,
|
||||
analyzer.getQualifiedUser(), dbName);
|
||||
|
||||
@ -24,6 +24,7 @@ import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.common.ErrorReport;
|
||||
import org.apache.doris.common.FeNameFormat;
|
||||
import org.apache.doris.common.UserException;
|
||||
import org.apache.doris.common.util.InternalDatabaseUtil;
|
||||
import org.apache.doris.mysql.privilege.PrivBitSet;
|
||||
import org.apache.doris.mysql.privilege.PrivPredicate;
|
||||
import org.apache.doris.mysql.privilege.Privilege;
|
||||
@ -54,7 +55,7 @@ public class AlterDatabaseRename extends DdlStmt {
|
||||
if (Strings.isNullOrEmpty(dbName)) {
|
||||
throw new AnalysisException("Database name is not set");
|
||||
}
|
||||
|
||||
InternalDatabaseUtil.checkDatabase(dbName, ConnectContext.get());
|
||||
if (!Env.getCurrentEnv().getAccessManager().checkDbPriv(ConnectContext.get(), dbName,
|
||||
PrivPredicate.of(PrivBitSet.of(Privilege.ADMIN_PRIV, Privilege.ALTER_PRIV), Operator.OR))) {
|
||||
ErrorReport.reportAnalysisException(ErrorCode.ERR_DBACCESS_DENIED_ERROR,
|
||||
|
||||
@ -27,6 +27,7 @@ import org.apache.doris.common.AnalysisException;
|
||||
import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.common.ErrorReport;
|
||||
import org.apache.doris.common.UserException;
|
||||
import org.apache.doris.common.util.InternalDatabaseUtil;
|
||||
import org.apache.doris.common.util.PropertyAnalyzer;
|
||||
import org.apache.doris.common.util.Util;
|
||||
import org.apache.doris.mysql.privilege.PrivPredicate;
|
||||
@ -67,6 +68,7 @@ public class AlterTableStmt extends DdlStmt {
|
||||
tbl.analyze(analyzer);
|
||||
// disallow external catalog
|
||||
Util.prohibitExternalCatalog(tbl.getCtl(), this.getClass().getSimpleName());
|
||||
InternalDatabaseUtil.checkDatabase(tbl.getDb(), ConnectContext.get());
|
||||
if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), tbl.getDb(), tbl.getTbl(),
|
||||
PrivPredicate.ALTER)) {
|
||||
ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR, "ALTER TABLE",
|
||||
|
||||
@ -22,6 +22,7 @@ import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.common.ErrorReport;
|
||||
import org.apache.doris.common.FeNameFormat;
|
||||
import org.apache.doris.common.UserException;
|
||||
import org.apache.doris.common.util.InternalDatabaseUtil;
|
||||
import org.apache.doris.common.util.PrintableMap;
|
||||
import org.apache.doris.mysql.privilege.PrivPredicate;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
@ -56,7 +57,7 @@ public class CreateDbStmt extends DdlStmt {
|
||||
public void analyze(Analyzer analyzer) throws UserException {
|
||||
super.analyze(analyzer);
|
||||
FeNameFormat.checkDbName(dbName);
|
||||
|
||||
InternalDatabaseUtil.checkDatabase(dbName, ConnectContext.get());
|
||||
if (!Env.getCurrentEnv().getAccessManager().checkDbPriv(ConnectContext.get(), dbName, PrivPredicate.CREATE)) {
|
||||
ErrorReport.reportAnalysisException(
|
||||
ErrorCode.ERR_DBACCESS_DENIED_ERROR, analyzer.getQualifiedUser(), dbName);
|
||||
|
||||
@ -35,6 +35,7 @@ import org.apache.doris.common.FeNameFormat;
|
||||
import org.apache.doris.common.Pair;
|
||||
import org.apache.doris.common.UserException;
|
||||
import org.apache.doris.common.util.AutoBucketUtils;
|
||||
import org.apache.doris.common.util.InternalDatabaseUtil;
|
||||
import org.apache.doris.common.util.ParseUtil;
|
||||
import org.apache.doris.common.util.PrintableMap;
|
||||
import org.apache.doris.common.util.PropertyAnalyzer;
|
||||
@ -285,7 +286,7 @@ public class CreateTableStmt extends DdlStmt {
|
||||
FeNameFormat.checkTableName(tableName.getTbl());
|
||||
// disallow external catalog
|
||||
Util.prohibitExternalCatalog(tableName.getCtl(), this.getClass().getSimpleName());
|
||||
|
||||
InternalDatabaseUtil.checkDatabase(tableName.getDb(), ConnectContext.get());
|
||||
if (!Env.getCurrentEnv().getAccessManager()
|
||||
.checkTblPriv(ConnectContext.get(), tableName.getDb(), tableName.getTbl(), PrivPredicate.CREATE)) {
|
||||
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR, "CREATE");
|
||||
|
||||
@ -23,6 +23,7 @@ import org.apache.doris.catalog.Env;
|
||||
import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.common.ErrorReport;
|
||||
import org.apache.doris.common.UserException;
|
||||
import org.apache.doris.common.util.InternalDatabaseUtil;
|
||||
import org.apache.doris.mysql.privilege.PrivPredicate;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
|
||||
@ -58,7 +59,7 @@ public class DropDbStmt extends DdlStmt {
|
||||
if (Strings.isNullOrEmpty(dbName)) {
|
||||
ErrorReport.reportAnalysisException(ErrorCode.ERR_WRONG_DB_NAME, dbName);
|
||||
}
|
||||
|
||||
InternalDatabaseUtil.checkDatabase(dbName, ConnectContext.get());
|
||||
// Don't allow to drop mysql compatible databases
|
||||
DatabaseIf db = Env.getCurrentInternalCatalog().getDbNullable(dbName);
|
||||
if (db != null && (db instanceof Database) && ((Database) db).isMysqlCompatibleDatabase()) {
|
||||
|
||||
@ -21,6 +21,7 @@ import org.apache.doris.catalog.Env;
|
||||
import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.common.ErrorReport;
|
||||
import org.apache.doris.common.UserException;
|
||||
import org.apache.doris.common.util.InternalDatabaseUtil;
|
||||
import org.apache.doris.common.util.Util;
|
||||
import org.apache.doris.mysql.privilege.PrivPredicate;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
@ -85,7 +86,7 @@ public class DropTableStmt extends DdlStmt {
|
||||
tableName.analyze(analyzer);
|
||||
// disallow external catalog
|
||||
Util.prohibitExternalCatalog(tableName.getCtl(), this.getClass().getSimpleName());
|
||||
|
||||
InternalDatabaseUtil.checkDatabase(tableName.getDb(), ConnectContext.get());
|
||||
// check access
|
||||
if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), tableName.getDb(),
|
||||
tableName.getTbl(), PrivPredicate.DROP)) {
|
||||
|
||||
@ -21,6 +21,7 @@ import org.apache.doris.catalog.Env;
|
||||
import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.common.ErrorReport;
|
||||
import org.apache.doris.common.UserException;
|
||||
import org.apache.doris.common.util.InternalDatabaseUtil;
|
||||
import org.apache.doris.mysql.privilege.PrivPredicate;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
|
||||
@ -74,6 +75,8 @@ public class InsertOverwriteTableStmt extends DdlStmt {
|
||||
|
||||
@Override
|
||||
public void analyze(Analyzer analyzer) throws UserException {
|
||||
target.getTblName().analyze(analyzer);
|
||||
InternalDatabaseUtil.checkDatabase(getDb(), ConnectContext.get());
|
||||
if (!Env.getCurrentEnv().getAccessManager()
|
||||
.checkTblPriv(ConnectContext.get(), getDb(), getTbl(), PrivPredicate.LOAD)) {
|
||||
ErrorReport.reportAnalysisException(ErrorCode.ERR_TABLEACCESS_DENIED_ERROR, "LOAD",
|
||||
|
||||
@ -22,6 +22,7 @@ import org.apache.doris.common.AnalysisException;
|
||||
import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.common.ErrorReport;
|
||||
import org.apache.doris.common.UserException;
|
||||
import org.apache.doris.common.util.InternalDatabaseUtil;
|
||||
import org.apache.doris.common.util.Util;
|
||||
import org.apache.doris.mysql.privilege.PrivPredicate;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
@ -49,7 +50,7 @@ public class TruncateTableStmt extends DdlStmt {
|
||||
if (tblRef.hasExplicitAlias()) {
|
||||
throw new AnalysisException("Not support truncate table with alias");
|
||||
}
|
||||
|
||||
InternalDatabaseUtil.checkDatabase(tblRef.getName().getDb(), ConnectContext.get());
|
||||
// check access
|
||||
// it requires LOAD privilege, because we consider this operation as 'delete data', which is also a
|
||||
// 'load' operation.
|
||||
|
||||
@ -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.
|
||||
|
||||
package org.apache.doris.common.util;
|
||||
|
||||
import org.apache.doris.common.AnalysisException;
|
||||
import org.apache.doris.common.FeConstants;
|
||||
import org.apache.doris.qe.ConnectContext;
|
||||
|
||||
import com.google.common.base.Preconditions;
|
||||
|
||||
public class InternalDatabaseUtil {
|
||||
|
||||
public static void checkDatabase(String dbName, ConnectContext ctx) throws AnalysisException {
|
||||
Preconditions.checkNotNull(dbName, "require dbName object");
|
||||
if (!FeConstants.INTERNAL_DB_NAME.equals(dbName)) {
|
||||
return;
|
||||
}
|
||||
if (ctx == null || ctx.getCurrentUserIdentity() == null || !ctx.getCurrentUserIdentity().isRootUser()) {
|
||||
throw new AnalysisException("Not allowed to operate database: " + dbName);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -26,6 +26,8 @@ import org.apache.doris.catalog.Env;
|
||||
import org.apache.doris.catalog.KeysType;
|
||||
import org.apache.doris.catalog.OlapTable;
|
||||
import org.apache.doris.common.Config;
|
||||
import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.mysql.privilege.PrivPredicate;
|
||||
import org.apache.doris.nereids.NereidsPlanner;
|
||||
import org.apache.doris.nereids.analyzer.UnboundRelation;
|
||||
import org.apache.doris.nereids.exceptions.AnalysisException;
|
||||
@ -115,6 +117,14 @@ public class DeleteFromCommand extends Command implements ForwardWithSync {
|
||||
UnboundRelation relation = optRelation.get();
|
||||
PhysicalFilter<?> filter = optFilter.get();
|
||||
|
||||
if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), scan.getDatabase().getFullName(),
|
||||
scan.getTable().getName(), PrivPredicate.LOAD)) {
|
||||
String message = ErrorCode.ERR_TABLEACCESS_DENIED_ERROR.formatErrorMsg("LOAD",
|
||||
ConnectContext.get().getQualifiedUser(), ConnectContext.get().getRemoteIP(),
|
||||
scan.getDatabase().getFullName() + ": " + scan.getTable().getName());
|
||||
throw new AnalysisException(message);
|
||||
}
|
||||
|
||||
// predicate check
|
||||
OlapTable olapTable = scan.getTable();
|
||||
Set<String> columns = olapTable.getFullSchema().stream().map(Column::getName).collect(Collectors.toSet());
|
||||
|
||||
@ -23,6 +23,7 @@ import org.apache.doris.catalog.TableIf;
|
||||
import org.apache.doris.common.ErrorCode;
|
||||
import org.apache.doris.common.ErrorReport;
|
||||
import org.apache.doris.common.UserException;
|
||||
import org.apache.doris.common.util.InternalDatabaseUtil;
|
||||
import org.apache.doris.insertoverwrite.InsertOverwriteUtil;
|
||||
import org.apache.doris.mysql.privilege.PrivPredicate;
|
||||
import org.apache.doris.nereids.NereidsPlanner;
|
||||
@ -111,6 +112,8 @@ public class InsertOverwriteTableCommand extends Command implements ForwardWithS
|
||||
Preconditions.checkArgument(plan.isPresent(), "insert into command must contain OlapTableSinkNode");
|
||||
PhysicalOlapTableSink<?> physicalOlapTableSink = ((PhysicalOlapTableSink<?>) plan.get());
|
||||
OlapTable targetTable = physicalOlapTableSink.getTargetTable();
|
||||
InternalDatabaseUtil
|
||||
.checkDatabase(targetTable.getQualifiedDbName(), ConnectContext.get());
|
||||
// check auth
|
||||
if (!Env.getCurrentEnv().getAccessManager()
|
||||
.checkTblPriv(ConnectContext.get(), targetTable.getQualifiedDbName(), targetTable.getName(),
|
||||
|
||||
@ -46,6 +46,7 @@ import org.apache.doris.common.FeConstants;
|
||||
import org.apache.doris.common.FeNameFormat;
|
||||
import org.apache.doris.common.Pair;
|
||||
import org.apache.doris.common.util.AutoBucketUtils;
|
||||
import org.apache.doris.common.util.InternalDatabaseUtil;
|
||||
import org.apache.doris.common.util.ParseUtil;
|
||||
import org.apache.doris.common.util.PropertyAnalyzer;
|
||||
import org.apache.doris.common.util.Util;
|
||||
@ -254,7 +255,11 @@ public class CreateTableInfo {
|
||||
if (Strings.isNullOrEmpty(dbName)) {
|
||||
dbName = ctx.getDatabase();
|
||||
}
|
||||
|
||||
try {
|
||||
InternalDatabaseUtil.checkDatabase(dbName, ConnectContext.get());
|
||||
} catch (org.apache.doris.common.AnalysisException e) {
|
||||
throw new AnalysisException(e.getMessage(), e.getCause());
|
||||
}
|
||||
if (!Env.getCurrentEnv().getAccessManager().checkTblPriv(ConnectContext.get(), dbName,
|
||||
tableName, PrivPredicate.CREATE)) {
|
||||
try {
|
||||
|
||||
@ -45,6 +45,7 @@ import org.apache.doris.common.Pair;
|
||||
import org.apache.doris.common.QuotaExceedException;
|
||||
import org.apache.doris.common.UserException;
|
||||
import org.apache.doris.common.util.DebugUtil;
|
||||
import org.apache.doris.common.util.InternalDatabaseUtil;
|
||||
import org.apache.doris.common.util.MetaLockUtils;
|
||||
import org.apache.doris.common.util.TimeUtils;
|
||||
import org.apache.doris.metric.MetricRepo;
|
||||
@ -314,6 +315,8 @@ public class DatabaseTransactionMgr {
|
||||
long listenerId, long timeoutSecond)
|
||||
throws DuplicatedRequestException, LabelAlreadyUsedException, BeginTransactionException,
|
||||
AnalysisException, QuotaExceedException, MetaNotFoundException {
|
||||
Database db = env.getInternalCatalog().getDbOrMetaException(dbId);
|
||||
InternalDatabaseUtil.checkDatabase(db.getFullName(), ConnectContext.get());
|
||||
checkDatabaseDataQuota();
|
||||
Preconditions.checkNotNull(coordinator);
|
||||
Preconditions.checkNotNull(label);
|
||||
|
||||
Reference in New Issue
Block a user