Skip to content

Commit 0651ef8

Browse files
authored
refactor: set enable_experimental_rbac_check default 1 (#15436)
* refactor: set enable_experimental_rbac_check default 1 * forbiden drop user stage in binder * fix clippy
1 parent 69f3e45 commit 0651ef8

File tree

9 files changed

+55
-32
lines changed

9 files changed

+55
-32
lines changed

src/query/service/src/interpreters/access/privilege_access.rs

Lines changed: 38 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,6 +35,7 @@ use databend_common_sql::plans::PresignAction;
3535
use databend_common_sql::plans::RewriteKind;
3636
use databend_common_sql::Planner;
3737
use databend_common_users::RoleCacheManager;
38+
use databend_common_users::UserApiProvider;
3839

3940
use crate::interpreters::access::AccessChecker;
4041
use crate::sessions::QueryContext;
@@ -618,13 +619,49 @@ impl AccessChecker for PrivilegeAccess {
618619
self.validate_db_access(&plan.catalog, &plan.database, UserPrivilegeType::Drop, plan.if_exists).await?;
619620
}
620621
Plan::UndropDatabase(_)
621-
| Plan::DropUDF(_)
622622
| Plan::DropIndex(_)
623623
| Plan::DropTableIndex(_) => {
624624
// undroptable/db need convert name to id. But because of drop, can not find the id. Upgrade Object to Database.
625625
self.validate_access(&GrantObject::Global, UserPrivilegeType::Drop)
626626
.await?;
627627
}
628+
Plan::DropUDF(plan) => {
629+
let udf_name = &plan.udf;
630+
if !UserApiProvider::instance().exists_udf(&tenant, udf_name).await? && plan.if_exists {
631+
return Ok(());
632+
}
633+
if enable_experimental_rbac_check {
634+
let udf = HashSet::from([udf_name]);
635+
self.validate_udf_access(udf).await?;
636+
} else {
637+
self.validate_access(&GrantObject::Global, UserPrivilegeType::Drop)
638+
.await?;
639+
}
640+
}
641+
Plan::DropStage(plan) => {
642+
match UserApiProvider::instance().get_stage(&tenant, &plan.name).await {
643+
Ok(stage) => {
644+
if enable_experimental_rbac_check {
645+
let privileges = vec![UserPrivilegeType::Read, UserPrivilegeType::Write];
646+
for privilege in privileges {
647+
self.validate_stage_access(&stage, privilege).await?;
648+
}
649+
} else {
650+
self.validate_access(&GrantObject::Global, UserPrivilegeType::Super)
651+
.await?;
652+
}
653+
}
654+
Err(e) => {
655+
match e.code() {
656+
ErrorCode::UNKNOWN_STAGE if plan.if_exists =>
657+
{
658+
return Ok(());
659+
}
660+
_ => return Err(e.add_message("error on validating stage access")),
661+
}
662+
}
663+
}
664+
}
628665
Plan::UseDatabase(plan) => {
629666
let session = self.ctx.get_current_session();
630667
if self.has_ownership(&session, &GrantObject::Database(catalog_name.clone(), plan.database.clone())).await? {
@@ -1017,7 +1054,6 @@ impl AccessChecker for PrivilegeAccess {
10171054
| Plan::CreateCatalog(_)
10181055
| Plan::DropCatalog(_)
10191056
| Plan::CreateStage(_)
1020-
| Plan::DropStage(_)
10211057
| Plan::CreateFileFormat(_)
10221058
| Plan::DropFileFormat(_)
10231059
| Plan::ShowFileFormats(_)

src/query/service/src/interpreters/common/grant.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -78,9 +78,9 @@ pub async fn validate_grant_object_exists(
7878
}
7979
GrantObject::UDF(udf) => {
8080
if !UserApiProvider::instance().exists_udf(&tenant, udf).await? {
81-
return Err(databend_common_exception::ErrorCode::UnknownStage(format!(
82-
"udf {udf} not exists"
83-
)));
81+
return Err(databend_common_exception::ErrorCode::UnknownFunction(
82+
format!("udf {udf} not exists"),
83+
));
8484
}
8585
}
8686
GrantObject::Stage(stage) => {

src/query/service/src/interpreters/interpreter_user_stage_drop.rs

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414

1515
use std::sync::Arc;
1616

17-
use databend_common_exception::ErrorCode;
1817
use databend_common_exception::Result;
1918
use databend_common_management::RoleApi;
2019
use databend_common_meta_app::principal::OwnershipObject;
@@ -62,13 +61,6 @@ impl Interpreter for DropUserStageInterpreter {
6261
let tenant = self.ctx.get_tenant();
6362
let user_mgr = UserApiProvider::instance();
6463

65-
// Check user stage.
66-
if plan.name == "~" {
67-
return Err(ErrorCode::StagePermissionDenied(
68-
"user stage is not allowed to be dropped",
69-
));
70-
}
71-
7264
let stage = user_mgr.get_stage(&tenant, &plan.name).await;
7365
user_mgr
7466
.drop_stage(&tenant, &plan.name, plan.if_exists)

src/query/settings/src/settings_default.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -649,7 +649,7 @@ impl DefaultSettings {
649649
range: Some(SettingRange::String(vec!["rounding".into(), "truncating".into()])),
650650
}),
651651
("enable_experimental_rbac_check", DefaultSettingValue {
652-
value: UserSettingValue::UInt64(0),
652+
value: UserSettingValue::UInt64(1),
653653
desc: "experiment setting disables stage and udf privilege check(disable by default).",
654654
mode: SettingMode::Both,
655655
range: Some(SettingRange::Numeric(0..=1)),

src/query/sql/src/planner/binder/binder.rs

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -380,10 +380,17 @@ impl<'a> Binder {
380380
Statement::DropStage {
381381
stage_name,
382382
if_exists,
383-
} => Plan::DropStage(Box::new(DropStagePlan {
383+
} => {
384+
// Check user stage.
385+
if stage_name == "~" {
386+
return Err(ErrorCode::StagePermissionDenied(
387+
"user stage is not allowed to be dropped",
388+
));
389+
}
390+
Plan::DropStage(Box::new(DropStagePlan {
384391
if_exists: *if_exists,
385392
name: stage_name.clone(),
386-
})),
393+
}))},
387394
Statement::RemoveStage { location, pattern } => {
388395
self.bind_remove_stage(location, pattern).await?
389396
}

tests/suites/0_stateless/18_rbac/18_0001_udf_priv.sh

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ echo "=== test UDF priv"
77
export TEST_USER_PASSWORD="password"
88
export TEST_USER_CONNECT="bendsql --user=test-user --password=password --host=${QUERY_MYSQL_HANDLER_HOST} --port ${QUERY_HTTP_HANDLER_PORT}"
99

10-
echo "set global enable_experimental_rbac_check=1" | $BENDSQL_CLIENT_CONNECT
11-
1210
echo "drop user if exists 'test-user'" | $BENDSQL_CLIENT_CONNECT
1311
echo "DROP FUNCTION IF EXISTS f1;" | $BENDSQL_CLIENT_CONNECT
1412
echo "DROP FUNCTION IF EXISTS f2;" | $BENDSQL_CLIENT_CONNECT
@@ -141,4 +139,3 @@ echo "drop function if exists a;" | $BENDSQL_CLIENT_CONNECT
141139
echo "drop function if exists b;" | $BENDSQL_CLIENT_CONNECT
142140
echo "drop table if exists default.t;" | $BENDSQL_CLIENT_CONNECT
143141
echo "drop table if exists default.t2;" | $BENDSQL_CLIENT_CONNECT
144-
echo "unset enable_experimental_rbac_check" | $BENDSQL_CLIENT_CONNECT

tests/suites/0_stateless/18_rbac/18_0002_ownership_cover.sh

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ export TEST_USER_CONNECT="bendsql --user=owner --password=password --host=${QUER
99

1010
export TEST_TRANSFER_USER_CONNECT="bendsql --user=owner1 --password=password --host=${QUERY_MYSQL_HANDLER_HOST} --port ${QUERY_HTTP_HANDLER_PORT}"
1111

12-
echo "set global enable_experimental_rbac_check=1" | $BENDSQL_CLIENT_CONNECT
13-
1412
## cleanup
1513
echo "drop database if exists d_0002;" | $BENDSQL_CLIENT_CONNECT
1614
echo "drop user if exists '${TEST_USER_NAME}'" | $BENDSQL_CLIENT_CONNECT
@@ -72,13 +70,14 @@ echo "select * from d_0002.t" | $TEST_USER_CONNECT
7270

7371
## cleanup
7472
echo "drop database d_0002;" | $BENDSQL_CLIENT_CONNECT
75-
echo "drop stage hello;" | $BENDSQL_CLIENT_CONNECT
76-
echo "drop function a;" | $BENDSQL_CLIENT_CONNECT
73+
echo "drop stage hello;" | $TEST_TRANSFER_USER_CONNECT
74+
echo "drop stage if exists noexistshello;" | $TEST_TRANSFER_USER_CONNECT
75+
echo "drop function a;" | $TEST_TRANSFER_USER_CONNECT
76+
echo "drop function if exists noexistsa;" | $TEST_TRANSFER_USER_CONNECT
7777
echo "drop user '${TEST_USER_NAME}'" | $BENDSQL_CLIENT_CONNECT
7878
echo "drop user 'owner1'" | $BENDSQL_CLIENT_CONNECT
7979
echo "drop role 'r_0002_1'" | $BENDSQL_CLIENT_CONNECT
8080
echo "drop role 'r_0002'" | $BENDSQL_CLIENT_CONNECT
81-
echo "unset enable_experimental_rbac_check" | $BENDSQL_CLIENT_CONNECT
8281

8382
echo "=== test ownership: show stmt ==="
8483
echo "drop user if exists a;" | $BENDSQL_CLIENT_CONNECT

tests/suites/0_stateless/18_rbac/18_0007_privilege_access.sh

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ export TEST_USER_PASSWORD="password"
77
export TEST_USER_CONNECT="bendsql --user=test-user --password=password --host=${QUERY_MYSQL_HANDLER_HOST} --port ${QUERY_HTTP_HANDLER_PORT}"
88
export RM_UUID="sed -E ""s/[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}/UUID/g"""
99

10-
echo "set global enable_experimental_rbac_check=1" | $BENDSQL_CLIENT_CONNECT
11-
1210
stmt "drop database if exists db01;"
1311
stmt "create database db01;"
1412
stmt "drop database if exists dbnotexists;"
@@ -275,5 +273,3 @@ echo "drop table if exists t1" | $BENDSQL_CLIENT_CONNECT
275273
echo "drop table if exists t2" | $BENDSQL_CLIENT_CONNECT
276274
echo "drop stage if exists s3;" | $BENDSQL_CLIENT_CONNECT
277275
echo "drop database if exists db01" | $BENDSQL_CLIENT_CONNECT
278-
279-
echo "unset enable_experimental_rbac_check" | $BENDSQL_CLIENT_CONNECT

tests/suites/1_stateful/00_stage/00_0012_stage_priv.sh

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,6 @@ export TEST_USER_CONNECT="bendsql --user=u1 --password=password --host=${QUERY_M
99
export USER_B_CONNECT="bendsql --user=b --password=password --host=${QUERY_MYSQL_HANDLER_HOST} --port ${QUERY_HTTP_HANDLER_PORT}"
1010
export RM_UUID="sed -E ""s/[a-z0-9]{8}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{4}-[a-z0-9]{12}/UUID/g"""
1111

12-
echo "set global enable_experimental_rbac_check=1" | $BENDSQL_CLIENT_CONNECT
13-
1412
echo "drop table if exists test_table;" | $BENDSQL_CLIENT_CONNECT
1513
echo "drop user if exists u1;" | $BENDSQL_CLIENT_CONNECT
1614
echo "drop STAGE if exists s2;" | $BENDSQL_CLIENT_CONNECT
@@ -144,5 +142,3 @@ echo "insert into t select \$1 from 'fs:///tmp/00_0020/' (FILE_FORMAT => 'CSV');
144142
echo "drop table if exists t" | $BENDSQL_CLIENT_CONNECT
145143
echo "drop user if exists b" | $BENDSQL_CLIENT_CONNECT
146144
rm -rf /tmp/00_0012
147-
148-
echo "unset enable_experimental_rbac_check" | $BENDSQL_CLIENT_CONNECT

0 commit comments

Comments
 (0)