From 72ce2d2bc1468fd1f409fc885f8da67ab8a9bb0a Mon Sep 17 00:00:00 2001 From: Esa Korhonen Date: Tue, 13 Aug 2019 17:03:00 +0300 Subject: [PATCH] MXS-2633 Fix PAM authentication support with server version 10.4 The new server pam plugin does not always send the first password prompt with the AuthSwitchRequest-packet. In this case the server expects the client (MaxScale) to just send the password immediately. MaxScale now checks the length of the packet, sending the password if the packet is short. This works with both old and new server versions. --- .../PAM/PAMBackendAuth/pam_backend_session.cc | 29 +++++++++++++++---- 1 file changed, 24 insertions(+), 5 deletions(-) diff --git a/server/modules/authenticator/PAM/PAMBackendAuth/pam_backend_session.cc b/server/modules/authenticator/PAM/PAMBackendAuth/pam_backend_session.cc index e714d257d..2879dc408 100644 --- a/server/modules/authenticator/PAM/PAMBackendAuth/pam_backend_session.cc +++ b/server/modules/authenticator/PAM/PAMBackendAuth/pam_backend_session.cc @@ -211,15 +211,34 @@ bool PamBackendSession::extract(DCB* dcb, GWBUF* buffer) switch (m_state) { case State::INIT: - // Server should have sent the AuthSwitchRequest + 1st prompt - if (parse_authswitchreq(&data_ptr, end_ptr) - && parse_password_prompt(&data_ptr, end_ptr)) + // Server should have sent the AuthSwitchRequest. If server version is 10.4, the server may not + // send a prompt. Older versions add the first prompt to the same packet. + if (parse_authswitchreq(&data_ptr, end_ptr)) { - m_state = State::RECEIVED_PROMPT; - success = true; + if (end_ptr > data_ptr) + { + if (parse_password_prompt(&data_ptr, end_ptr)) + { + m_state = State::RECEIVED_PROMPT; + success = true; + } + else + { + // Password prompt should have been there, but was not. + unexpected_data = true; + } + } + else + { + // Just the AuthSwitchRequest, this is ok. The server now expects a password so set state + // accordingly. + m_state = State::RECEIVED_PROMPT; + success = true; + } } else { + // No AuthSwitchRequest, error. unexpected_data = true; } break;