@@ -17,8 +17,10 @@ use std::sync::Arc;
1717
1818use databend_common_base:: base:: GlobalInstance ;
1919use databend_common_catalog:: catalog:: Catalog ;
20+ use databend_common_catalog:: catalog:: CATALOG_DEFAULT ;
2021use databend_common_catalog:: plan:: DataSourceInfo ;
2122use databend_common_catalog:: table_context:: TableContext ;
23+ use databend_common_config:: GlobalConfig ;
2224use databend_common_exception:: ErrorCode ;
2325use databend_common_exception:: Result ;
2426use databend_common_management:: RoleApi ;
@@ -31,6 +33,7 @@ use databend_common_meta_app::principal::StageType;
3133use databend_common_meta_app:: principal:: UserGrantSet ;
3234use databend_common_meta_app:: principal:: UserPrivilegeSet ;
3335use databend_common_meta_app:: principal:: UserPrivilegeType ;
36+ use databend_common_meta_app:: principal:: SENSITIVE_SYSTEM_RESOURCE ;
3437use databend_common_meta_app:: principal:: SYSTEM_TABLES_ALLOW_LIST ;
3538use databend_common_meta_app:: tenant:: Tenant ;
3639use databend_common_meta_types:: seq_value:: SeqV ;
@@ -46,6 +49,7 @@ use databend_common_users::UserApiProvider;
4649use databend_enterprise_resources_management:: ResourcesManagement ;
4750use databend_storages_common_table_meta:: table:: OPT_KEY_TEMP_PREFIX ;
4851
52+ use crate :: history_tables:: session:: get_history_log_user;
4953use crate :: interpreters:: access:: AccessChecker ;
5054use crate :: sessions:: QueryContext ;
5155use crate :: sessions:: Session ;
@@ -159,13 +163,44 @@ impl PrivilegeAccess {
159163 Ok ( Some ( object) )
160164 }
161165
166+ fn access_system_history (
167+ & self ,
168+ catalog_name : & str ,
169+ db_name : & str ,
170+ privilege : UserPrivilegeType ,
171+ ) -> Result < ( ) > {
172+ let cluster_id = GlobalConfig :: instance ( ) . query . cluster_id . clone ( ) ;
173+ let tenant_id = GlobalConfig :: instance ( ) . query . tenant_id . clone ( ) ;
174+ if get_history_log_user ( tenant_id. tenant_name ( ) , & cluster_id) . identity ( )
175+ == self . ctx . get_current_user ( ) ?. identity ( )
176+ {
177+ return Ok ( ( ) ) ;
178+ }
179+ if catalog_name == CATALOG_DEFAULT
180+ && db_name. eq_ignore_ascii_case ( SENSITIVE_SYSTEM_RESOURCE )
181+ && !matches ! (
182+ privilege,
183+ UserPrivilegeType :: Select | UserPrivilegeType :: Drop
184+ )
185+ {
186+ return Err ( ErrorCode :: PermissionDenied (
187+ format ! (
188+ "Permission Denied: Operation '{:?}' on database 'default.system_history' is not allowed. This sensitive system resource only supports 'SELECT' and 'DROP'" ,
189+ privilege
190+ ) ,
191+ ) ) ;
192+ }
193+ Ok ( ( ) )
194+ }
195+
162196 async fn validate_db_access (
163197 & self ,
164198 catalog_name : & str ,
165199 db_name : & str ,
166200 privileges : UserPrivilegeType ,
167201 if_exists : bool ,
168202 ) -> Result < ( ) > {
203+ self . access_system_history ( catalog_name, db_name, privileges) ?;
169204 let tenant = self . ctx . get_tenant ( ) ;
170205 let check_current_role_only = match privileges {
171206 // create table/stream need check db's Create Privilege
@@ -270,6 +305,8 @@ impl PrivilegeAccess {
270305 return Ok ( ( ) ) ;
271306 }
272307
308+ self . access_system_history ( catalog_name, db_name, privilege) ?;
309+
273310 if self . ctx . is_temp_table ( catalog_name, db_name, table_name) {
274311 return Ok ( ( ) ) ;
275312 }
0 commit comments