diff options
author | robot-piglet <robot-piglet@yandex-team.com> | 2023-11-25 09:58:34 +0300 |
---|---|---|
committer | robot-piglet <robot-piglet@yandex-team.com> | 2023-11-25 10:21:16 +0300 |
commit | 87b47db8278b512a71c50ed56d2ed8ee68ac7e4d (patch) | |
tree | 7bd7c6e592dd051becd4e873d49e08300fd09fe8 | |
parent | 6b2a05ea439e6a1248e679d60d44519c21f11396 (diff) | |
download | ydb-87b47db8278b512a71c50ed56d2ed8ee68ac7e4d.tar.gz |
Intermediate changes
4 files changed, 27 insertions, 5 deletions
diff --git a/contrib/clickhouse/src/Interpreters/InterpreterAlterQuery.cpp b/contrib/clickhouse/src/Interpreters/InterpreterAlterQuery.cpp index 7d1f994823..669ad4e985 100644 --- a/contrib/clickhouse/src/Interpreters/InterpreterAlterQuery.cpp +++ b/contrib/clickhouse/src/Interpreters/InterpreterAlterQuery.cpp @@ -42,6 +42,7 @@ namespace ErrorCodes extern const int TABLE_IS_READ_ONLY; extern const int BAD_ARGUMENTS; extern const int UNKNOWN_TABLE; + extern const int UNKNOWN_DATABASE; } @@ -74,9 +75,14 @@ BlockIO InterpreterAlterQuery::executeToTable(const ASTAlterQuery & alter) if (!UserDefinedSQLFunctionFactory::instance().empty()) UserDefinedSQLFunctionVisitor::visit(query_ptr); - auto table_id = getContext()->resolveStorageID(alter, Context::ResolveOrdinary); - query_ptr->as<ASTAlterQuery &>().setDatabase(table_id.database_name); - StoragePtr table = DatabaseCatalog::instance().tryGetTable(table_id, getContext()); + auto table_id = getContext()->tryResolveStorageID(alter, Context::ResolveOrdinary); + StoragePtr table; + + if (table_id) + { + query_ptr->as<ASTAlterQuery &>().setDatabase(table_id.database_name); + table = DatabaseCatalog::instance().tryGetTable(table_id, getContext()); + } if (!alter.cluster.empty() && !maybeRemoveOnCluster(query_ptr, getContext())) { @@ -90,6 +96,9 @@ BlockIO InterpreterAlterQuery::executeToTable(const ASTAlterQuery & alter) getContext()->checkAccess(getRequiredAccess()); + if (!table_id) + throw Exception(ErrorCodes::UNKNOWN_DATABASE, "Database {} does not exist", backQuoteIfNeed(alter.getDatabase())); + DatabasePtr database = DatabaseCatalog::instance().getDatabase(table_id.database_name); if (database->shouldReplicateQuery(getContext(), query_ptr)) { diff --git a/contrib/clickhouse/src/Interpreters/InterpreterCreateQuery.cpp b/contrib/clickhouse/src/Interpreters/InterpreterCreateQuery.cpp index 92d74f4f18..06cee002ba 100644 --- a/contrib/clickhouse/src/Interpreters/InterpreterCreateQuery.cpp +++ b/contrib/clickhouse/src/Interpreters/InterpreterCreateQuery.cpp @@ -1215,9 +1215,9 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create) DatabasePtr database; bool need_add_to_database = !create.temporary; if (need_add_to_database) - database = DatabaseCatalog::instance().getDatabase(database_name); + database = DatabaseCatalog::instance().tryGetDatabase(database_name); - if (need_add_to_database && database->shouldReplicateQuery(getContext(), query_ptr)) + if (need_add_to_database && database && database->shouldReplicateQuery(getContext(), query_ptr)) { chassert(!ddl_guard); auto guard = DatabaseCatalog::instance().getDDLGuard(create.getDatabase(), create.getTable()); @@ -1232,6 +1232,9 @@ BlockIO InterpreterCreateQuery::createTable(ASTCreateQuery & create) return executeQueryOnCluster(create); } + if (need_add_to_database && !database) + throw Exception(ErrorCodes::UNKNOWN_DATABASE, "Database {} does not exist", backQuoteIfNeed(database_name)); + if (create.replace_table) { chassert(!ddl_guard); diff --git a/contrib/clickhouse/src/Server/TCPHandler.cpp b/contrib/clickhouse/src/Server/TCPHandler.cpp index bb3bee3897..82bf934549 100644 --- a/contrib/clickhouse/src/Server/TCPHandler.cpp +++ b/contrib/clickhouse/src/Server/TCPHandler.cpp @@ -688,6 +688,13 @@ void TCPHandler::runImpl() LOG_WARNING(log, "Client has gone away."); } + /// Interserver authentication is done only after we read the query. + /// This fact can be abused by producing exception before or while we read the query. + /// To avoid any potential exploits, we simply close connection on any exceptions + /// that happen before the first query is authenticated with the cluster secret. + if (is_interserver_mode && exception && !is_interserver_authenticated) + exception->rethrow(); + try { /// A query packet is always followed by one or more data packets. @@ -1664,6 +1671,8 @@ void TCPHandler::receiveQuery() /// address. session->authenticate(AlwaysAllowCredentials{client_info.initial_user}, client_info.initial_address); } + + is_interserver_authenticated = true; #else auto exception = Exception(ErrorCodes::AUTHENTICATION_FAILED, "Inter-server secret support is disabled, because ClickHouse was built without SSL library"); diff --git a/contrib/clickhouse/src/Server/TCPHandler.h b/contrib/clickhouse/src/Server/TCPHandler.h index 235f634afe..a97abe0935 100644 --- a/contrib/clickhouse/src/Server/TCPHandler.h +++ b/contrib/clickhouse/src/Server/TCPHandler.h @@ -196,6 +196,7 @@ private: /// For inter-server secret (remote_server.*.secret) bool is_interserver_mode = false; + bool is_interserver_authenticated = false; /// For DBMS_MIN_REVISION_WITH_INTERSERVER_SECRET String salt; /// For DBMS_MIN_REVISION_WITH_INTERSERVER_SECRET_V2 |