fix read only priv check in oracle
This commit is contained in:
@ -4124,19 +4124,12 @@ int ObSql::pc_get_plan(ObPlanCacheCtx &pc_ctx,
|
||||
pc_ctx.sql_ctx_.plan_cache_hit_ = true;
|
||||
session->set_early_lock_release(plan->stat_.enable_early_lock_release_);
|
||||
//极限性能场景下(perf_event=true),不再校验权限信息
|
||||
if (!session->has_user_super_privilege() && !pc_ctx.sql_ctx_.is_remote_sql_ && GCONF.enable_perf_event) {
|
||||
//we don't care about commit or rollback here because they will not cache in plan cache
|
||||
if (ObStmt::is_write_stmt(plan->get_stmt_type(), false)
|
||||
&& OB_FAIL(pc_ctx.sql_ctx_.schema_guard_->verify_read_only(
|
||||
session->get_effective_tenant_id(),
|
||||
plan->get_stmt_need_privs()))) {
|
||||
LOG_WARN("database or table is read only, cannot execute this stmt");
|
||||
}
|
||||
}
|
||||
//极限性能场景下(perf_event=true),不再校验权限信息
|
||||
if (OB_SUCC(ret) && !pc_ctx.sql_ctx_.is_remote_sql_ && GCONF.enable_perf_event) {
|
||||
//如果是remote sql第二次重入plan cache,不需要再做权限检查,因为在第一次进入plan cache已经检查过了
|
||||
if (!ObSchemaChecker::is_ora_priv_check()) {
|
||||
if (OB_FAIL(ObPrivilegeCheck::check_read_only(pc_ctx.sql_ctx_, plan->get_stmt_type(), false,
|
||||
plan->get_stmt_need_privs()))) {
|
||||
LOG_WARN("database or table is read only, cannot execute this stmt");
|
||||
} else if (!ObSchemaChecker::is_ora_priv_check()) {
|
||||
if (OB_FAIL(ObPrivilegeCheck::check_privilege(
|
||||
pc_ctx.sql_ctx_,
|
||||
plan->get_stmt_need_privs()))) {
|
||||
|
||||
@ -3025,6 +3025,34 @@ const ObGetStmtNeedPrivsFunc ObPrivilegeCheck::priv_check_funcs_[] =
|
||||
#undef OB_STMT_TYPE_DEF
|
||||
};
|
||||
|
||||
int ObPrivilegeCheck::check_read_only(const ObSqlCtx &ctx,
|
||||
const stmt::StmtType stmt_type,
|
||||
const bool has_global_variable,
|
||||
const ObStmtNeedPrivs &stmt_need_privs)
|
||||
{
|
||||
int ret = OB_SUCCESS;
|
||||
const bool is_mysql_mode = lib::is_mysql_mode();
|
||||
if (OB_ISNULL(ctx.session_info_) || OB_ISNULL(ctx.schema_guard_)) {
|
||||
ret = OB_INVALID_ARGUMENT;
|
||||
LOG_WARN("Session is NULL");
|
||||
} else if (ctx.session_info_->has_user_super_privilege()) {
|
||||
// super priv is only supported in mysql mode on design firstly. But some customer may use it in oracle mode to avoid this check in later time.
|
||||
// for upgrade compatibility, we still retain the oracle mode super priv checking here
|
||||
} else if (is_mysql_mode) {
|
||||
if (ObStmt::is_write_stmt(stmt_type, has_global_variable) &&
|
||||
OB_FAIL(ctx.schema_guard_->verify_read_only(ctx.session_info_->get_effective_tenant_id(),
|
||||
stmt_need_privs))) {
|
||||
LOG_WARN("database or table is read only, cannot execute this stmt", K(ret));
|
||||
}
|
||||
} else if (!is_mysql_mode) {
|
||||
if (ObStmt::is_dml_write_stmt(stmt_type) &&
|
||||
OB_FAIL(ctx.schema_guard_->verify_read_only(ctx.session_info_->get_effective_tenant_id(),
|
||||
stmt_need_privs))) {
|
||||
LOG_WARN("database or table is read only, cannot execute this stmt", K(ret));
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* 新的检查权限总入口。
|
||||
mysql mode, 或者 oracle mode的_enable_priv_check = false,沿用老的权限check逻辑,
|
||||
@ -3063,6 +3091,7 @@ int ObPrivilegeCheck::check_privilege_new(
|
||||
common::ObSEArray<ObNeedPriv, 4> tmp_need_privs;
|
||||
common::ObSEArray<ObOraNeedPriv, 4> tmp_ora_need_privs;
|
||||
ObSessionPrivInfo session_priv;
|
||||
bool has_global_variable = false;
|
||||
OZ (ctx.session_info_->get_session_priv_info(session_priv));
|
||||
OX (session_priv.set_effective_tenant_id(ctx.session_info_->get_effective_tenant_id()));
|
||||
OZ (get_stmt_need_privs(session_priv, basic_stmt, tmp_need_privs));
|
||||
@ -3079,22 +3108,11 @@ int ObPrivilegeCheck::check_privilege_new(
|
||||
tmp_ora_need_privs,
|
||||
CHECK_FLAG_NORMAL));
|
||||
OZ (stmt_ora_need_privs.need_privs_.assign(tmp_ora_need_privs));
|
||||
if (OB_SUCC(ret) && !ctx.session_info_->has_user_super_privilege()) {
|
||||
bool has_global_variable = false;
|
||||
if (basic_stmt->get_stmt_type() == stmt::T_VARIABLE_SET) {
|
||||
has_global_variable =
|
||||
static_cast<const ObVariableSetStmt*>(basic_stmt)->has_global_variable();
|
||||
}
|
||||
if (ObStmt::is_write_stmt(basic_stmt->get_stmt_type(), has_global_variable)
|
||||
&& OB_FAIL(ctx.schema_guard_->verify_read_only(
|
||||
ctx.session_info_->get_effective_tenant_id(),
|
||||
stmt_need_privs))) {
|
||||
LOG_WARN("database or table is read only, cannot execute this stmt", K(ret));
|
||||
}
|
||||
} else {
|
||||
//do nothing
|
||||
if (OB_SUCC(ret) && basic_stmt->get_stmt_type() == stmt::T_VARIABLE_SET) {
|
||||
has_global_variable =
|
||||
static_cast<const ObVariableSetStmt*>(basic_stmt)->has_global_variable();
|
||||
}
|
||||
//OZ (check_privilege(ctx, stmt_need_privs));
|
||||
OZ (check_read_only(ctx, basic_stmt->get_stmt_type(), has_global_variable, stmt_need_privs));
|
||||
OZ (check_ora_privilege(ctx, stmt_ora_need_privs));
|
||||
}
|
||||
}
|
||||
@ -3155,6 +3173,7 @@ int ObPrivilegeCheck::check_privilege(
|
||||
if (OB_SUCC(ret)) {
|
||||
common::ObSEArray<ObNeedPriv, 4> tmp_need_privs;
|
||||
ObSessionPrivInfo session_priv;
|
||||
bool has_global_variable = false;
|
||||
if (OB_FAIL(ctx.session_info_->get_session_priv_info(session_priv))) {
|
||||
LOG_WARN("fail to get session priv info", K(ret));
|
||||
} else if (FALSE_IT(session_priv.set_effective_tenant_id(
|
||||
@ -3163,20 +3182,11 @@ int ObPrivilegeCheck::check_privilege(
|
||||
LOG_WARN("Get stmt need privs error", K(ret));
|
||||
} else if (OB_FAIL(stmt_need_privs.need_privs_.assign(tmp_need_privs))) {
|
||||
LOG_WARN("fail to assign need_privs", K(ret));
|
||||
} else if (!ctx.session_info_->has_user_super_privilege()) {
|
||||
bool has_global_variable = false;
|
||||
if (basic_stmt->get_stmt_type() == stmt::T_VARIABLE_SET) {
|
||||
has_global_variable = static_cast<const ObVariableSetStmt*>(basic_stmt)->has_global_variable();
|
||||
}
|
||||
if (ObStmt::is_write_stmt(basic_stmt->get_stmt_type(), has_global_variable)
|
||||
&& OB_FAIL(ctx.schema_guard_->verify_read_only(
|
||||
ctx.session_info_->get_effective_tenant_id(),
|
||||
stmt_need_privs))) {
|
||||
LOG_WARN("database or table is read only, cannot execute this stmt", K(ret));
|
||||
}
|
||||
} else {
|
||||
//do nothing
|
||||
} else if (basic_stmt->get_stmt_type() == stmt::T_VARIABLE_SET) {
|
||||
has_global_variable =
|
||||
static_cast<const ObVariableSetStmt*>(basic_stmt)->has_global_variable();
|
||||
}
|
||||
OZ (check_read_only(ctx, basic_stmt->get_stmt_type(), has_global_variable, stmt_need_privs));
|
||||
if (OB_SUCC(ret) && OB_FAIL(check_privilege(ctx, stmt_need_privs))) {
|
||||
LOG_WARN("privilege check not passed", K(ret));
|
||||
}
|
||||
|
||||
@ -97,6 +97,10 @@ public:
|
||||
share::schema::ObSchemaGetterGuard &schema_guard,
|
||||
const common::ObIArray<uint64_t> &role_ids,
|
||||
const share::schema::ObStmtNeedPrivs &stmt_need_priv);
|
||||
static int check_read_only(const ObSqlCtx &ctx,
|
||||
const stmt::StmtType stmt_type,
|
||||
const bool has_global_variable,
|
||||
const ObStmtNeedPrivs &stmt_need_privs);
|
||||
private:
|
||||
///Extract priv info needed by a single stmt, may be sub-query.
|
||||
///called by recursive_stmt_need_priv
|
||||
|
||||
Reference in New Issue
Block a user