aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorNikita Vasilev <ns-vasilev@ydb.tech>2025-07-02 12:23:12 +0300
committerGitHub <noreply@github.com>2025-07-02 12:23:12 +0300
commit9f38b92a88a1f58076febab540e14a74dda18b56 (patch)
tree13309282185518f0009af6ad3c79ea4a3c52efcc
parentf0176285cf0af5c49d3d5ea352d57352bfa02751 (diff)
downloadydb-9f38b92a88a1f58076febab540e14a74dda18b56.tar.gz
Fix ACL for temp tables (#20444)
-rw-r--r--ydb/core/kqp/executer_actor/kqp_scheme_executer.cpp35
-rw-r--r--ydb/core/kqp/ut/scheme/kqp_acl_ut.cpp274
-rw-r--r--ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp14
3 files changed, 299 insertions, 24 deletions
diff --git a/ydb/core/kqp/executer_actor/kqp_scheme_executer.cpp b/ydb/core/kqp/executer_actor/kqp_scheme_executer.cpp
index 0f8f3d2b8c7..5c310673fde 100644
--- a/ydb/core/kqp/executer_actor/kqp_scheme_executer.cpp
+++ b/ydb/core/kqp/executer_actor/kqp_scheme_executer.cpp
@@ -114,15 +114,6 @@ public:
auto* makeDir = modifyScheme->MutableMkDir();
makeDir->SetName(GetSessionDirName());
- NACLib::TDiffACL diffAcl;
- diffAcl.AddAccess(
- NACLib::EAccessType::Allow,
- NACLib::EAccessRights::CreateDirectory | NACLib::EAccessRights::DescribeSchema,
- AppData()->AllAuthenticatedUsers);
-
- auto* modifyAcl = modifyScheme->MutableModifyACL();
- modifyAcl->SetDiffACL(diffAcl.SerializeAsString());
-
auto promise = NewPromise<IKqpGateway::TGenericResult>();
IActor* requestHandler = new TSchemeOpRequestHandler(ev.Release(), promise, false);
RegisterWithSameMailbox(requestHandler);
@@ -142,9 +133,7 @@ public:
auto& record = ev->Record;
record.SetDatabaseName(Database);
- if (UserToken) {
- record.SetUserToken(UserToken->GetSerializedToken());
- }
+ record.SetUserToken(NACLib::TSystemUsers::Tmp().SerializeAsString());
record.SetPeerName(ClientAddress);
auto* modifyScheme = record.MutableTransaction()->MutableModifyScheme();
@@ -156,14 +145,20 @@ public:
makeDir->SetName(SessionId);
ActorIdToProto(KqpTempTablesAgentActor, modifyScheme->MutableTempDirOwnerActorId());
- NACLib::TDiffACL diffAcl;
- diffAcl.RemoveAccess(
- NACLib::EAccessType::Allow,
- NACLib::EAccessRights::CreateDirectory | NACLib::EAccessRights::DescribeSchema,
- AppData()->AllAuthenticatedUsers);
-
- auto* modifyAcl = modifyScheme->MutableModifyACL();
- modifyAcl->SetDiffACL(diffAcl.SerializeAsString());
+ if (UserToken) {
+ constexpr ui32 access = NACLib::EAccessRights::CreateDirectory
+ | NACLib::EAccessRights::CreateTable
+ | NACLib::EAccessRights::RemoveSchema
+ | NACLib::EAccessRights::DescribeSchema;
+
+ NACLib::TDiffACL diffAcl;
+ diffAcl.AddAccess(
+ NACLib::EAccessType::Allow,
+ access,
+ UserToken->GetUserSID());
+ auto* modifyAcl = modifyScheme->MutableModifyACL();
+ modifyAcl->SetDiffACL(diffAcl.SerializeAsString());
+ }
auto promise = NewPromise<IKqpGateway::TGenericResult>();
IActor* requestHandler = new TSchemeOpRequestHandler(ev.Release(), promise, false);
diff --git a/ydb/core/kqp/ut/scheme/kqp_acl_ut.cpp b/ydb/core/kqp/ut/scheme/kqp_acl_ut.cpp
index 85960f3810c..27f7ebebcff 100644
--- a/ydb/core/kqp/ut/scheme/kqp_acl_ut.cpp
+++ b/ydb/core/kqp/ut/scheme/kqp_acl_ut.cpp
@@ -774,6 +774,280 @@ Y_UNIT_TEST_SUITE(KqpAcl) {
}
}
}
+
+ Y_UNIT_TEST_QUAD(AclTemporary, IsOlap, UseAdmin) {
+ NKikimrConfig::TAppConfig appConfig;
+ appConfig.MutableTableServiceConfig()->SetEnableOltpSink(true);
+ appConfig.MutableTableServiceConfig()->SetEnableOlapSink(true);
+ auto settings = NKqp::TKikimrSettings()
+ .SetAppConfig(appConfig)
+ .SetWithSampleTables(false)
+ .SetEnableTempTables(true);
+ TKikimrRunner kikimr(settings);
+ if (UseAdmin) {
+ kikimr.GetTestClient().GrantConnect("user_write@builtin");
+ kikimr.GetTestServer().GetRuntime()->GetAppData().AdministrationAllowedSIDs.emplace_back("root@builtin");
+ }
+
+ const TString UserWriteName = "user_write@builtin";
+ const TString UserReadName = "root@builtin";
+
+ auto driverWriteConfig = TDriverConfig()
+ .SetEndpoint(kikimr.GetEndpoint())
+ .SetAuthToken(UserWriteName)
+ .SetDatabase("/Root");
+ auto driverWrite = TDriver(driverWriteConfig);
+ auto clientWrite = NYdb::NQuery::TQueryClient(driverWrite);
+
+ auto sessionWrite = CreateSession(clientWrite);
+ auto sessionWriteOther = CreateSession(clientWrite);
+
+ auto driverReadConfig = TDriverConfig()
+ .SetEndpoint(kikimr.GetEndpoint())
+ .SetAuthToken(UserReadName)
+ .SetDatabase("/Root");
+ auto driverRead = TDriver(driverReadConfig);
+ auto clientRead = NYdb::NQuery::TQueryClient(driverRead);
+
+ auto sessionRead = CreateSession(clientRead);
+
+
+ {
+ const TString queryWrite = Sprintf(R"(
+ CREATE TEMPORARY TABLE `/Root/Test` (
+ id Uint64 NOT NULL,
+ name String,
+ primary key (id)
+ ) WITH (STORE=%s);
+ )", IsOlap ? "COLUMN" : "ROW");
+
+ auto result = sessionWrite.ExecuteQuery(queryWrite, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
+ UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString());
+ }
+
+ // tmp table by session alias
+ const TString queryWithAlias = R"(
+ UPSERT INTO `/Root/Test` (id, name) VALUES
+ (10u, "One");
+ )";
+
+ {
+ auto result = sessionWrite.ExecuteQuery(queryWithAlias, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
+ UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString());
+ }
+
+ {
+ auto result = sessionWriteOther.ExecuteQuery(queryWithAlias, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
+ UNIT_ASSERT_C(!result.IsSuccess(), result.GetIssues().ToString());
+ }
+
+ {
+ auto result = sessionRead.ExecuteQuery(queryWithAlias, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
+ UNIT_ASSERT_C(!result.IsSuccess(), result.GetIssues().ToString());
+ }
+
+ // tmp table by real path
+ const TStringBuf sessionPrefix = "&id=";
+ const auto pos = sessionWrite.GetId().find(sessionPrefix);
+
+ const TString sessionTmpDir = TStringBuilder()
+ << "/Root/.tmp/sessions/"
+ << sessionWrite.GetId().substr(pos + sessionPrefix.size());
+
+ {
+ auto result = sessionWrite.ExecuteQuery(Sprintf(R"(
+ CREATE TABLE `%s/Test` (
+ id Uint64 NOT NULL,
+ name String,
+ primary key (id)
+ );
+ )", sessionTmpDir.c_str()), NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
+
+ UNIT_ASSERT_C(!result.IsSuccess(), result.GetIssues().ToString());
+ UNIT_ASSERT_C(result.GetIssues().ToString().contains("path is temporary"), result.GetIssues().ToString());
+ }
+
+ const TString queryWithRealPath = Sprintf(R"(
+ UPSERT INTO `%s/Root/Test` (id, name) VALUES
+ (10u, "One");
+ )", sessionTmpDir.c_str());
+
+ const TString queryWithFakePath = Sprintf(R"(
+ UPSERT INTO `%s/Root/Test2` (id, name) VALUES
+ (10u, "One");
+ )", sessionTmpDir.c_str());
+
+ {
+ auto result = sessionWrite.ExecuteQuery(queryWithRealPath, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
+
+ UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString());
+ }
+
+ {
+ auto result = sessionWriteOther.ExecuteQuery(queryWithRealPath, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
+
+ UNIT_ASSERT_C(result.IsSuccess(), result.GetIssues().ToString());
+ }
+
+ {
+ auto result = sessionRead.ExecuteQuery(queryWithRealPath, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
+
+ UNIT_ASSERT_C(!result.IsSuccess(), result.GetIssues().ToString());
+ UNIT_ASSERT_C(result.GetIssues().ToString().contains("because it does not exist or you do not have access permissions. Please check correctness of table path and user permissions."), result.GetIssues().ToString());
+ }
+
+ {
+ auto result = sessionRead.ExecuteQuery(queryWithFakePath, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
+
+ UNIT_ASSERT_C(!result.IsSuccess(), result.GetIssues().ToString());
+ UNIT_ASSERT_C(result.GetIssues().ToString().contains("because it does not exist or you do not have access permissions. Please check correctness of table path and user permissions."), result.GetIssues().ToString());
+ }
+
+ auto schemeClientWrite = NYdb::NScheme::TSchemeClient(driverWrite);
+ auto schemeClientRead = NYdb::NScheme::TSchemeClient(driverRead);
+
+ {
+ auto result = schemeClientWrite.ListDirectory(sessionTmpDir).GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
+ }
+
+ {
+ auto result = schemeClientRead.ListDirectory(sessionTmpDir).GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::UNAUTHORIZED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "Access denied",
+ result.GetIssues().ToString()
+ );
+ }
+
+ {
+ auto result = schemeClientWrite.DescribePath(sessionTmpDir).GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL_C(result.GetStatus(), EStatus::SUCCESS, result.GetIssues().ToString());
+ }
+
+ {
+ auto result = schemeClientRead.DescribePath(sessionTmpDir).GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::UNAUTHORIZED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "Access denied",
+ result.GetIssues().ToString()
+ );
+ }
+
+ {
+ auto result = schemeClientWrite.ListDirectory("/Root/.tmp").GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::UNAUTHORIZED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "Access denied",
+ result.GetIssues().ToString()
+ );
+ }
+
+ {
+ auto result = schemeClientRead.ListDirectory("/Root/.tmp").GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::UNAUTHORIZED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "Access denied",
+ result.GetIssues().ToString()
+ );
+ }
+
+ {
+ auto result = schemeClientWrite.DescribePath("/Root/.tmp").GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::UNAUTHORIZED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "Access denied",
+ result.GetIssues().ToString()
+ );
+ }
+
+ {
+ auto result = schemeClientRead.DescribePath("/Root/.tmp").GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::UNAUTHORIZED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "Access denied",
+ result.GetIssues().ToString()
+ );
+ }
+
+ {
+ auto result = schemeClientWrite.ListDirectory("/Root/.tmp/sessions").GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::UNAUTHORIZED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "Access denied",
+ result.GetIssues().ToString()
+ );
+ }
+
+ {
+ auto result = schemeClientRead.ListDirectory("/Root/.tmp/sessions").GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::UNAUTHORIZED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "Access denied",
+ result.GetIssues().ToString()
+ );
+ }
+
+ {
+ auto result = schemeClientWrite.DescribePath("/Root/.tmp/sessions").GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::UNAUTHORIZED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "Access denied",
+ result.GetIssues().ToString()
+ );
+ }
+
+ {
+ auto result = schemeClientRead.DescribePath("/Root/.tmp/sessions").GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::UNAUTHORIZED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "Access denied",
+ result.GetIssues().ToString()
+ );
+ }
+
+
+ {
+ auto result = schemeClientWrite.MakeDirectory("/Root/.tmp/test1").GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::UNAUTHORIZED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "Access denied",
+ result.GetIssues().ToString()
+ );
+ }
+
+ {
+ auto result = schemeClientRead.MakeDirectory("/Root/.tmp/test2").GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::UNAUTHORIZED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "Access denied",
+ result.GetIssues().ToString()
+ );
+ }
+
+ {
+ auto result = schemeClientWrite.MakeDirectory("/Root/.tmp/sessions/test1").GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::UNAUTHORIZED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "Access denied",
+ result.GetIssues().ToString()
+ );
+ }
+
+ {
+ auto result = schemeClientRead.MakeDirectory("/Root/.tmp/sessions/test2").GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::UNAUTHORIZED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "Access denied",
+ result.GetIssues().ToString()
+ );
+ }
+
+ {
+ auto result = schemeClientWrite.MakeDirectory(sessionTmpDir + "/test1").GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::PRECONDITION_FAILED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "path is temporary",
+ result.GetIssues().ToString()
+ );
+ }
+
+ {
+ auto result = schemeClientRead.MakeDirectory(sessionTmpDir + "/test2").GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL(result.GetStatus(), EStatus::UNAUTHORIZED);
+ UNIT_ASSERT_STRING_CONTAINS_C(result.GetIssues().ToString(), "Access denied",
+ result.GetIssues().ToString()
+ );
+ }
+
+ driverWrite.Stop(true);
+ driverRead.Stop(true);
+ }
}
} // namespace NKqp
diff --git a/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp b/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp
index d4ccfb5f94d..08b2c5da857 100644
--- a/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp
+++ b/ydb/core/kqp/ut/service/kqp_qs_queries_ut.cpp
@@ -1908,6 +1908,8 @@ Y_UNIT_TEST_SUITE(KqpQueryService) {
serverSettings.SetWithSampleTables(false).SetEnableTempTables(true));
auto clientConfig = NGRpcProxy::TGRpcClientConfig(kikimr.GetEndpoint());
auto client = kikimr.GetQueryClient();
+
+ TString SessionId;
{
auto session = client.GetSession().GetValueSync().GetSession();
auto id = session.GetId();
@@ -1933,13 +1935,15 @@ Y_UNIT_TEST_SUITE(KqpQueryService) {
UNIT_ASSERT_C(resultSelect.IsSuccess(), resultSelect.GetIssues().ToString());
const TVector<TString> sessionIdSplitted = StringSplitter(id).SplitByString("&id=");
+ SessionId = sessionIdSplitted.back();
+
const auto queryCreateRestricted = Q_(fmt::format(R"(
--!syntax_v1
CREATE TABLE `/Root/.tmp/sessions/{}/Test` (
Key Uint64 NOT NULL,
Value String,
PRIMARY KEY (Key)
- );)", sessionIdSplitted.back()));
+ );)", SessionId));
auto resultCreateRestricted = session.ExecuteQuery(queryCreateRestricted, NYdb::NQuery::TTxControl::NoTx()).ExtractValueSync();
UNIT_ASSERT(!resultCreateRestricted.IsSuccess());
@@ -1966,9 +1970,11 @@ Y_UNIT_TEST_SUITE(KqpQueryService) {
{
auto schemeClient = kikimr.GetSchemeClient();
- auto listResult = schemeClient.ListDirectory("/Root/.tmp/sessions").GetValueSync();
- UNIT_ASSERT_VALUES_EQUAL_C(listResult.GetStatus(), NYdb::EStatus::SUCCESS, listResult.GetIssues().ToString());
- UNIT_ASSERT_VALUES_EQUAL(listResult.GetChildren().size(), 0);
+ auto listResult = schemeClient.ListDirectory(
+ fmt::format("/Root/.tmp/sessions/{}", SessionId)
+ ).GetValueSync();
+ UNIT_ASSERT_VALUES_EQUAL_C(listResult.GetStatus(), NYdb::EStatus::SCHEME_ERROR, listResult.GetIssues().ToString());
+ UNIT_ASSERT_STRING_CONTAINS_C(listResult.GetIssues().ToString(), "Path not found",listResult.GetIssues().ToString());
}
}