diff --git a/src/sql/ob_sql.cpp b/src/sql/ob_sql.cpp index aa0cbff6d7..8aa77df7d2 100644 --- a/src/sql/ob_sql.cpp +++ b/src/sql/ob_sql.cpp @@ -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()))) { diff --git a/src/sql/privilege_check/ob_privilege_check.cpp b/src/sql/privilege_check/ob_privilege_check.cpp index e98824981c..9b7d546333 100644 --- a/src/sql/privilege_check/ob_privilege_check.cpp +++ b/src/sql/privilege_check/ob_privilege_check.cpp @@ -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 tmp_need_privs; common::ObSEArray 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(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(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 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(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(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)); } diff --git a/src/sql/privilege_check/ob_privilege_check.h b/src/sql/privilege_check/ob_privilege_check.h index 9532630679..867821de42 100644 --- a/src/sql/privilege_check/ob_privilege_check.h +++ b/src/sql/privilege_check/ob_privilege_check.h @@ -97,6 +97,10 @@ public: share::schema::ObSchemaGetterGuard &schema_guard, const common::ObIArray &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