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;
|
pc_ctx.sql_ctx_.plan_cache_hit_ = true;
|
||||||
session->set_early_lock_release(plan->stat_.enable_early_lock_release_);
|
session->set_early_lock_release(plan->stat_.enable_early_lock_release_);
|
||||||
//极限性能场景下(perf_event=true),不再校验权限信息
|
//极限性能场景下(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) {
|
if (OB_SUCC(ret) && !pc_ctx.sql_ctx_.is_remote_sql_ && GCONF.enable_perf_event) {
|
||||||
//如果是remote sql第二次重入plan cache,不需要再做权限检查,因为在第一次进入plan cache已经检查过了
|
//如果是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(
|
if (OB_FAIL(ObPrivilegeCheck::check_privilege(
|
||||||
pc_ctx.sql_ctx_,
|
pc_ctx.sql_ctx_,
|
||||||
plan->get_stmt_need_privs()))) {
|
plan->get_stmt_need_privs()))) {
|
||||||
|
|||||||
@ -3025,6 +3025,34 @@ const ObGetStmtNeedPrivsFunc ObPrivilegeCheck::priv_check_funcs_[] =
|
|||||||
#undef OB_STMT_TYPE_DEF
|
#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逻辑,
|
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<ObNeedPriv, 4> tmp_need_privs;
|
||||||
common::ObSEArray<ObOraNeedPriv, 4> tmp_ora_need_privs;
|
common::ObSEArray<ObOraNeedPriv, 4> tmp_ora_need_privs;
|
||||||
ObSessionPrivInfo session_priv;
|
ObSessionPrivInfo session_priv;
|
||||||
|
bool has_global_variable = false;
|
||||||
OZ (ctx.session_info_->get_session_priv_info(session_priv));
|
OZ (ctx.session_info_->get_session_priv_info(session_priv));
|
||||||
OX (session_priv.set_effective_tenant_id(ctx.session_info_->get_effective_tenant_id()));
|
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));
|
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,
|
tmp_ora_need_privs,
|
||||||
CHECK_FLAG_NORMAL));
|
CHECK_FLAG_NORMAL));
|
||||||
OZ (stmt_ora_need_privs.need_privs_.assign(tmp_ora_need_privs));
|
OZ (stmt_ora_need_privs.need_privs_.assign(tmp_ora_need_privs));
|
||||||
if (OB_SUCC(ret) && !ctx.session_info_->has_user_super_privilege()) {
|
if (OB_SUCC(ret) && basic_stmt->get_stmt_type() == stmt::T_VARIABLE_SET) {
|
||||||
bool has_global_variable = false;
|
|
||||||
if (basic_stmt->get_stmt_type() == stmt::T_VARIABLE_SET) {
|
|
||||||
has_global_variable =
|
has_global_variable =
|
||||||
static_cast<const ObVariableSetStmt*>(basic_stmt)->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)
|
OZ (check_read_only(ctx, basic_stmt->get_stmt_type(), has_global_variable, stmt_need_privs));
|
||||||
&& 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
|
|
||||||
}
|
|
||||||
//OZ (check_privilege(ctx, stmt_need_privs));
|
|
||||||
OZ (check_ora_privilege(ctx, stmt_ora_need_privs));
|
OZ (check_ora_privilege(ctx, stmt_ora_need_privs));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3155,6 +3173,7 @@ int ObPrivilegeCheck::check_privilege(
|
|||||||
if (OB_SUCC(ret)) {
|
if (OB_SUCC(ret)) {
|
||||||
common::ObSEArray<ObNeedPriv, 4> tmp_need_privs;
|
common::ObSEArray<ObNeedPriv, 4> tmp_need_privs;
|
||||||
ObSessionPrivInfo session_priv;
|
ObSessionPrivInfo session_priv;
|
||||||
|
bool has_global_variable = false;
|
||||||
if (OB_FAIL(ctx.session_info_->get_session_priv_info(session_priv))) {
|
if (OB_FAIL(ctx.session_info_->get_session_priv_info(session_priv))) {
|
||||||
LOG_WARN("fail to get session priv info", K(ret));
|
LOG_WARN("fail to get session priv info", K(ret));
|
||||||
} else if (FALSE_IT(session_priv.set_effective_tenant_id(
|
} 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));
|
LOG_WARN("Get stmt need privs error", K(ret));
|
||||||
} else if (OB_FAIL(stmt_need_privs.need_privs_.assign(tmp_need_privs))) {
|
} else if (OB_FAIL(stmt_need_privs.need_privs_.assign(tmp_need_privs))) {
|
||||||
LOG_WARN("fail to assign need_privs", K(ret));
|
LOG_WARN("fail to assign need_privs", K(ret));
|
||||||
} else if (!ctx.session_info_->has_user_super_privilege()) {
|
} else if (basic_stmt->get_stmt_type() == stmt::T_VARIABLE_SET) {
|
||||||
bool has_global_variable = false;
|
has_global_variable =
|
||||||
if (basic_stmt->get_stmt_type() == stmt::T_VARIABLE_SET) {
|
static_cast<const ObVariableSetStmt*>(basic_stmt)->has_global_variable();
|
||||||
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
|
|
||||||
}
|
}
|
||||||
|
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))) {
|
if (OB_SUCC(ret) && OB_FAIL(check_privilege(ctx, stmt_need_privs))) {
|
||||||
LOG_WARN("privilege check not passed", K(ret));
|
LOG_WARN("privilege check not passed", K(ret));
|
||||||
}
|
}
|
||||||
|
|||||||
@ -97,6 +97,10 @@ public:
|
|||||||
share::schema::ObSchemaGetterGuard &schema_guard,
|
share::schema::ObSchemaGetterGuard &schema_guard,
|
||||||
const common::ObIArray<uint64_t> &role_ids,
|
const common::ObIArray<uint64_t> &role_ids,
|
||||||
const share::schema::ObStmtNeedPrivs &stmt_need_priv);
|
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:
|
private:
|
||||||
///Extract priv info needed by a single stmt, may be sub-query.
|
///Extract priv info needed by a single stmt, may be sub-query.
|
||||||
///called by recursive_stmt_need_priv
|
///called by recursive_stmt_need_priv
|
||||||
|
|||||||
Reference in New Issue
Block a user