[fix](auth)support check priv when tvf use resource (#36928) (#37132)

pick https://github.com/apache/doris/pull/36928
This commit is contained in:
zhangdong
2024-07-02 23:03:29 +08:00
committed by GitHub
parent 177764647d
commit 0a1abf10d6
8 changed files with 90 additions and 0 deletions

View File

@ -53,6 +53,7 @@ public class AlterPolicyStmt extends DdlStmt {
super.analyze(analyzer);
// check auth
// check if can alter policy and use storage_resource
if (!Env.getCurrentEnv().getAccessManager()
.checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR,

View File

@ -102,6 +102,7 @@ public class CreatePolicyStmt extends DdlStmt {
+ "Enable it by setting 'enable_storage_policy=true' in fe.conf");
}
// check auth
// check if can create policy and use storage_resource
if (!Env.getCurrentEnv().getAccessManager()
.checkGlobalPriv(ConnectContext.get(), PrivPredicate.ADMIN)) {
ErrorReport.reportAnalysisException(ErrorCode.ERR_SPECIFIC_ACCESS_DENIED_ERROR,

View File

@ -81,6 +81,10 @@ public enum ErrorCode {
+ "one of) the (%s) privilege(s) on database %s for this operation"),
ERR_SPECIFIC_ALL_ACCESS_DENIED_ERROR(1223, new byte[] {'4', '2', '0', '0', '0'}, "Access denied; you need all "
+ " %s privilege(s) for this operation"),
ERR_RESOURCE_ACCESS_DENIED_ERROR(1222, new byte[]{'4', '2', '0', '0', '0'}, "Access denied; you need (at least "
+ "one of) the (%s) privilege(s) on resource %s for this operation"),
ERR_LOCAL_VARIABLE(1228, new byte[]{'H', 'Y', '0', '0', '0'}, "Variable '%s' is a SESSION variable and can't be "
+ "used with SET GLOBAL"),
ERR_GLOBAL_VARIABLE(1229, new byte[]{'H', 'Y', '0', '0', '0'}, "Variable '%s' is a GLOBAL variable and should be "

View File

@ -27,9 +27,11 @@ import org.apache.doris.nereids.jobs.JobContext;
import org.apache.doris.nereids.rules.analysis.UserAuthentication;
import org.apache.doris.nereids.trees.expressions.Slot;
import org.apache.doris.nereids.trees.expressions.SlotReference;
import org.apache.doris.nereids.trees.expressions.functions.table.TableValuedFunction;
import org.apache.doris.nereids.trees.plans.Plan;
import org.apache.doris.nereids.trees.plans.logical.LogicalCatalogRelation;
import org.apache.doris.nereids.trees.plans.logical.LogicalRelation;
import org.apache.doris.nereids.trees.plans.logical.LogicalTVFRelation;
import org.apache.doris.nereids.trees.plans.logical.LogicalView;
import org.apache.doris.qe.ConnectContext;
@ -62,6 +64,13 @@ public class CheckPrivileges extends ColumnPruning {
return view;
}
@Override
public Plan visitLogicalTVFRelation(LogicalTVFRelation tvfRelation, PruneContext context) {
TableValuedFunction tvf = tvfRelation.getFunction();
tvf.checkAuth(jobContext.getCascadesContext().getConnectContext());
return super.visitLogicalTVFRelation(tvfRelation, context);
}
@Override
public Plan visitLogicalRelation(LogicalRelation relation, PruneContext context) {
if (relation instanceof LogicalCatalogRelation) {

View File

@ -31,6 +31,7 @@ import org.apache.doris.nereids.trees.expressions.functions.Nondeterministic;
import org.apache.doris.nereids.trees.expressions.shape.UnaryExpression;
import org.apache.doris.nereids.trees.expressions.visitor.ExpressionVisitor;
import org.apache.doris.nereids.types.DataType;
import org.apache.doris.qe.ConnectContext;
import org.apache.doris.statistics.ColumnStatistic;
import org.apache.doris.statistics.Statistics;
import org.apache.doris.tablefunction.TableValuedFunctionIf;
@ -102,6 +103,10 @@ public abstract class TableValuedFunction extends BoundFunction
return tableCache.get();
}
public final void checkAuth(ConnectContext ctx) {
getCatalogFunction().checkAuth(ctx);
}
@Override
public <R, C> R accept(ExpressionVisitor<R, C> visitor, C context) {
return visitor.visitTableValuedFunction(this, context);

View File

@ -33,6 +33,7 @@ import org.apache.doris.catalog.StructType;
import org.apache.doris.catalog.Table;
import org.apache.doris.catalog.Type;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.common.ErrorCode;
import org.apache.doris.common.Pair;
import org.apache.doris.common.UserException;
import org.apache.doris.common.util.BrokerUtil;
@ -41,6 +42,7 @@ import org.apache.doris.common.util.FileFormatUtils;
import org.apache.doris.common.util.NetUtils;
import org.apache.doris.common.util.Util;
import org.apache.doris.datasource.tvf.source.TVFScanNode;
import org.apache.doris.mysql.privilege.PrivPredicate;
import org.apache.doris.planner.PlanNodeId;
import org.apache.doris.planner.ScanNode;
import org.apache.doris.proto.InternalService;
@ -125,6 +127,9 @@ public abstract class ExternalFileTableValuedFunction extends TableValuedFunctio
protected String filePath;
protected TFileFormatType fileFormatType;
protected Optional<String> resourceName = Optional.empty();
private TFileCompressType compressionType;
private String headerType = "";
@ -181,6 +186,7 @@ public abstract class ExternalFileTableValuedFunction extends TableValuedFunctio
if (resource == null) {
throw new AnalysisException("Can not find resource: " + properties.get("resource"));
}
this.resourceName = Optional.of(properties.get("resource"));
mergedProperties = resource.getCopiedProperties();
}
mergedProperties.putAll(properties);
@ -562,5 +568,16 @@ public abstract class ExternalFileTableValuedFunction extends TableValuedFunctio
}
return false;
}
public void checkAuth(ConnectContext ctx) {
if (resourceName.isPresent()) {
if (!Env.getCurrentEnv().getAccessManager()
.checkResourcePriv(ctx, resourceName.get(), PrivPredicate.USAGE)) {
String message = ErrorCode.ERR_RESOURCE_ACCESS_DENIED_ERROR.formatErrorMsg(
PrivPredicate.USAGE.getPrivs().toString(), resourceName.get());
throw new org.apache.doris.nereids.exceptions.AnalysisException(message);
}
}
}
}

View File

@ -24,6 +24,7 @@ import org.apache.doris.catalog.TableIf;
import org.apache.doris.common.AnalysisException;
import org.apache.doris.planner.PlanNodeId;
import org.apache.doris.planner.ScanNode;
import org.apache.doris.qe.ConnectContext;
import java.util.List;
import java.util.Map;
@ -84,4 +85,8 @@ public abstract class TableValuedFunctionIf {
public abstract List<Column> getTableColumns() throws AnalysisException;
public abstract ScanNode getScanNode(PlanNodeId id, TupleDescriptor desc);
public void checkAuth(ConnectContext ctx) {
}
}