This is an automated email from the ASF dual-hosted git repository.
achennaka pushed a commit to branch branch-1.18.x
in repository https://gitbox.apache.org/repos/asf/kudu.git
The following commit(s) were added to refs/heads/branch-1.18.x by this push:
new 89eaf9dbd KUDU-3661 Ranger policy not honored in Kudu
89eaf9dbd is described below
commit 89eaf9dbd9ac728a9b1cc69484e4777035f1b249
Author: Abhishek Chennaka <[email protected]>
AuthorDate: Wed Apr 23 12:20:41 2025 -0700
KUDU-3661 Ranger policy not honored in Kudu
This fixes a long-standing bug in the Ranger authorization provider
where we return prematurely from
RangerAuthzProvider::FillTablePrivilegePB() when the SELECT
action is encountered while iterating through
unordered_set<ActionPB, ActionHas> container, potentially
resulting in missing privileges depending on the position of the
SELECT action in the set. While this behavior depends on the
libc++/libstdc++ implementation, we have observed reports of this
issue on RHEL/CentOS 8 machines.
Thanks to Alexey Serbin for valuable inputs and contributions on
this fix.
Test case source: https://gerrit.cloudera.org/#/c/22809/
Change-Id: I635132154d622eb41e993a0a1a818b21b5af6bb7
Reviewed-on: http://gerrit.cloudera.org:8080/22806
Reviewed-by: Alexey Serbin <[email protected]>
Tested-by: Abhishek Chennaka <[email protected]>
(cherry picked from commit 4e5cd21da441444cf960e8fa53a71042b7be17c9)
Reviewed-on: http://gerrit.cloudera.org:8080/22814
---
src/kudu/integration-tests/ts_authz-itest.cc | 46 ++++++++++++++++++++++++++--
src/kudu/master/ranger_authz_provider.cc | 7 +++--
2 files changed, 47 insertions(+), 6 deletions(-)
diff --git a/src/kudu/integration-tests/ts_authz-itest.cc
b/src/kudu/integration-tests/ts_authz-itest.cc
index 382d3960f..988f16720 100644
--- a/src/kudu/integration-tests/ts_authz-itest.cc
+++ b/src/kudu/integration-tests/ts_authz-itest.cc
@@ -190,23 +190,31 @@ Status PerformWrite(const WritePrivileges&
write_privileges,
};
// Note: we could test UPSERTs, but it complicates the logic, and UPSERTs are
// tested elsewhere anyway.
+ unique_ptr<ThreadSafeRandom> own_prng(
+ prng ? nullptr : new ThreadSafeRandom(SeedRandom()));
switch (op_type) {
case WritePrivilegeType::INSERT: {
unique_ptr<KuduInsert> ins(table->NewInsert());
- GenerateDataForRow(table->schema(), prng->Next32(), prng,
ins->mutable_row());
+ GenerateDataForRow(table->schema(),
+ prng ? prng->Next32() : 0,
+ prng ? prng : own_prng.get(),
+ ins->mutable_row());
return unwrap_session_error(session->Apply(ins.release()));
}
break;
case WritePrivilegeType::UPDATE: {
unique_ptr<KuduUpdate> upd(table->NewUpdate());
- GenerateDataForRow(table->schema(), prng->Next32(), prng,
upd->mutable_row());
+ GenerateDataForRow(table->schema(),
+ prng ? prng->Next32() : 0,
+ prng ? prng : own_prng.get(),
+ upd->mutable_row());
return unwrap_session_error(session->Apply(upd.release()));
}
break;
case WritePrivilegeType::DELETE: {
unique_ptr<KuduDelete> del(table->NewDelete());
KuduPartialRow* row = del->mutable_row();
- RETURN_NOT_OK(row->SetInt32(0, prng->Next32()));
+ RETURN_NOT_OK(row->SetInt32(0, prng ? prng->Next32() : 0));
return unwrap_session_error(session->Apply(del.release()));
}
break;
@@ -605,6 +613,38 @@ TEST_P(TSAuthzITest, TestReadsAndWrites) {
}
}
+// Test to catch KUDU-3661 regression
+TEST_P(TSAuthzITest, Kudu3661) {
+ SKIP_IF_SLOW_NOT_ALLOWED();
+
+ static const string kTableName = "table";
+ const string table_ident = Substitute("$0.$1", kDb, kTableName);
+ const string user = "user0";
+ ASSERT_OK(CreateTable(table_ident, user));
+
+ ASSERT_OK(cluster_->kdc()->CreateUserPrincipal(user));
+ ASSERT_OK(cluster_->kdc()->Kinit(user));
+
+ shared_ptr<KuduClient> user_client;
+ ASSERT_OK(cluster_->CreateClient(nullptr, &user_client));
+
+ ASSERT_OK(harness_->GrantTablePrivilege(kDb, kTableName, user, "SELECT",
/*admin=*/false,
+ cluster_));
+ ASSERT_OK(harness_->GrantTablePrivilege(kDb, kTableName, user, "INSERT",
/*admin=*/false,
+ cluster_));
+ ASSERT_OK(harness_->GrantTablePrivilege(kDb, kTableName, user, "UPDATE",
/*admin=*/false,
+ cluster_));
+
+ // Perform INSERT and UPDATE operations on the table. Ensure that the UPDATE
privilege is
+ // included in the authz token. Without the KUDU-3661 fix, this privilege
may be missing
+ // on RHEL/CentOS 8 systems due to the SELECT privilege grant blocking the
UPDATE privilege
+ // from being granted.
+ shared_ptr<KuduTable> table;
+ ASSERT_OK(user_client->OpenTable(table_ident, &table));
+ ASSERT_OK(PerformWrite({ WritePrivilegeType::INSERT }, nullptr,
table.get()));
+ ASSERT_OK(PerformWrite({ WritePrivilegeType::UPDATE }, nullptr,
table.get()));
+}
+
// Test for a couple of scenarios related to alter tables.
TEST_P(TSAuthzITest, TestAlters) {
SKIP_IF_SLOW_NOT_ALLOWED();
diff --git a/src/kudu/master/ranger_authz_provider.cc
b/src/kudu/master/ranger_authz_provider.cc
index 156cef4ab..dff7b4c37 100644
--- a/src/kudu/master/ranger_authz_provider.cc
+++ b/src/kudu/master/ranger_authz_provider.cc
@@ -311,9 +311,10 @@ Status RangerAuthzProvider::FillTablePrivilegePB(const
string& table_name,
LOG(WARNING) << "Unexpected action returned by Ranger: " <<
ActionPB_Name(action);
break;
}
- if (pb->scan_privilege()) {
- return Status::OK();
- }
+ }
+ // If select is allowed, we can skip checking column-level privileges and
return early.
+ if (pb->scan_privilege()) {
+ return Status::OK();
}
// If select is not allowed on the table level we need to dig in and set