transport: fix process_startup cert-auth path missing connection-ready setup

When authenticate() returns a user directly (certificate-based auth,
introduced in 20e9619bb1), process_startup was missing the same
post-authentication bookkeeping that the no-auth and SASL paths perform:

  - update_scheduling_group(): without it, the connection runs under the
    default scheduling group instead of the one mapped to the user's
    service level.

  - _authenticating = false / _ready = true: without them,
    system.clients reports connection_stage = AUTHENTICATING forever
    instead of READY.

  - on_connection_ready(): without it, the connection never releases its
    slot in the uninitialized-connections concurrency semaphore (acquired
    at connection creation), leaking one unit per cert-authenticated
    connection for the lifetime of the connection.

The omission was introduced when on_connection_ready() was added to the
else and SASL branches in 474e84199c but the cert-auth branch was missed.

Fixes: 20e9619bb1 ("auth: support certificate-based authentication")

Signed-off-by: Pavel Emelyanov <xemul@scylladb.com>
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
Pavel Emelyanov
2026-03-24 18:02:46 +03:00
parent da6fe14035
commit 2d8540f1ee
2 changed files with 5 additions and 1 deletions

View File

@@ -68,7 +68,7 @@ def make_server_config(auth_type: str) -> dict:
@pytest.mark.parametrize("auth_type", [
"allow_all",
"password",
pytest.param("cert_bypass", marks=pytest.mark.xfail(reason="bug in process_startup cert-auth path", strict=True)),
"cert_bypass",
])
@pytest.mark.skip_mode("release", reason="error injections are not supported in release mode")
async def test_connection_stage_ready_after_auth(manager: ManagerClient, auth_type: str) -> None:

View File

@@ -1405,6 +1405,10 @@ future<std::unique_ptr<cql_server::response>> cql_server::connection::process_st
client_state.set_login(std::move(*opt_user));
co_await client_state.check_user_can_login();
client_state.maybe_update_per_service_level_params();
update_scheduling_group();
_authenticating = false;
_ready = true;
on_connection_ready();
res = make_ready(stream, trace_state);
} else {
res = make_autheticate(stream, a.qualified_java_name(), trace_state);