Skip to content

Commit b941c5e

Browse files
committed
Bug#34679835 authentication_ldap_sasl_client infinite loop on error
When authentication via sasl fails (the user can't be found in a kerberos server), the sasl_authenticate() function enters an infinite loop. Enabling debugging via AUTHENTICATION_LDAP_CLIENT_LOG=5 shows that [DBG] : Sasl_client::SaslStart sasl output: ... [DBG] : Sasl_client::SendSaslRequestToServer length:570 request: ... [Error] : Sasl_client::SendSaslRequestToServer: sasl response read failed but that "read failed" doesn't abort the loop. Instead, the same message is sent again and now the write fails: [DBG] : Sasl_client::SaslStart sasl output: ... [DBG] : Sasl_client::SendSaslRequestToServer length:570 request: ... [Error] : Sasl_client::SendSaslRequestToServer: sasl response write failed It loops in sasl_authenticate() as the function checks for 'rc_auth < 0', if it shall leave the loop, but send_sasl_to_server returns 0 for success and 1 for error. Change ------ - leave the loop if 1 (error) is returned, instead of "rc_auth < 0" - added doc-comments Change-Id: I74ed37ea916ff8bea92cddd59638551080a077b1
1 parent c4eeb59 commit b941c5e

File tree

1 file changed

+35
-4
lines changed

1 file changed

+35
-4
lines changed

libmysql/authentication_ldap/auth_ldap_sasl_client.cc

+35-4
Original file line numberDiff line numberDiff line change
@@ -229,11 +229,29 @@ Sasl_client::~Sasl_client() {
229229
m_sasl_mechanism = nullptr;
230230
}
231231

232+
/**
233+
* send SASL request to the server and read the servers reply.
234+
*
235+
* wraps the SASL message in a MySQL packet and sends it to the server.
236+
*
237+
* if sending to the server fails, the function fails. But if reading
238+
* the reply fails, the *response_len will be 0.
239+
*
240+
* @param[in] request pointer to the SASL request payload
241+
* @param[in] request_len length of the request
242+
* @param[out] response pointer to a location where the response buffers
243+
* location shall be stored.
244+
* @param[out] response_len pointer to a location where the length of the
245+
* response buffer shall be stored.
246+
*
247+
* @retval 1 write failed.
248+
* @retval 0 write succeeded, but read may have failed.
249+
*/
232250
int Sasl_client::send_sasl_request_to_server(const unsigned char *request,
233251
int request_len,
234252
unsigned char **response,
235253
int *response_len) {
236-
int rc_server = CR_ERROR;
254+
int rc_server = 1;
237255
std::stringstream log_stream;
238256

239257
if (m_vio == nullptr) {
@@ -364,6 +382,16 @@ static int initialize_plugin(char *, size_t, int, va_list) SUPPRESS_UBSAN;
364382
static int deinitialize_plugin() SUPPRESS_UBSAN;
365383
#endif // __clang__
366384

385+
/*
386+
* authenticate via SASL.
387+
*
388+
* executes the SASL full handshake.
389+
*
390+
* @returns one of the CR_xxx codes.
391+
* @retval CR_OK on auth success
392+
* @retval CR_ERROR on generic auth failure
393+
* @retval CR_AUTH_HANDSHAKE on handshake failure
394+
*/
367395
static int sasl_authenticate(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) {
368396
int rc_sasl = SASL_FAIL;
369397
int rc_auth = CR_ERROR;
@@ -424,10 +452,12 @@ static int sasl_authenticate(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) {
424452
do {
425453
server_packet = nullptr;
426454
server_packet_len = 0;
427-
rc_auth = sasl_client.send_sasl_request_to_server(
455+
const int send_res = sasl_client.send_sasl_request_to_server(
428456
(const unsigned char *)sasl_client_output, sasl_client_output_len,
429457
&server_packet, &server_packet_len);
430-
if (rc_auth < 0) {
458+
if (send_res != 0) {
459+
rc_auth = CR_AUTH_HANDSHAKE;
460+
431461
goto EXIT;
432462
}
433463
sasl_client_output = nullptr;
@@ -442,6 +472,7 @@ static int sasl_authenticate(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) {
442472

443473
if (rc_sasl == SASL_OK) {
444474
rc_auth = CR_OK;
475+
445476
log_dbg("sasl_authenticate authentication successful");
446477
/**
447478
Kerberos authentication is concluded by the LDAP/SASL server,
@@ -451,7 +482,7 @@ static int sasl_authenticate(MYSQL_PLUGIN_VIO *vio, MYSQL *mysql) {
451482
*/
452483
if (strcmp(sasl_client.get_method().c_str(), SASL_GSSAPI) == 0) {
453484
server_packet = nullptr;
454-
rc_auth = sasl_client.send_sasl_request_to_server(
485+
/* int send_res = */ sasl_client.send_sasl_request_to_server(
455486
(const unsigned char *)sasl_client_output, sasl_client_output_len,
456487
&server_packet, &server_packet_len);
457488
rc_auth = CR_OK;

0 commit comments

Comments
 (0)