diff options
-rw-r--r-- | NEWS | 4 | ||||
-rw-r--r-- | ext/mysqli/tests/mysqli_auth_pam.phpt | 52 | ||||
-rw-r--r-- | ext/mysqlnd/mysqlnd_auth.c | 6 |
3 files changed, 55 insertions, 7 deletions
@@ -5,6 +5,10 @@ PHP NEWS - Core: . Fixed #80706 (mail(): Headers after Bcc headers may be ignored). (cmb) +- MySQLnd: + . Fixed bug #78680 (mysqlnd's mysql_clear_password does not transmit + null-terminated password). (Daniel Black) + - MySQLi: . Fixed bug #74779 (x() and y() truncating floats to integers). (cmb) diff --git a/ext/mysqli/tests/mysqli_auth_pam.phpt b/ext/mysqli/tests/mysqli_auth_pam.phpt index aa2c6a818b..587320a628 100644 --- a/ext/mysqli/tests/mysqli_auth_pam.phpt +++ b/ext/mysqli/tests/mysqli_auth_pam.phpt @@ -19,8 +19,8 @@ if (!$res = $link->query("SHOW PLUGINS")) $have_pam = false; while ($row = $res->fetch_assoc()) { - if (isset($row['Name']) && ('mysql_clear_password' == $row['Name'])) { - $have_pam = true; + if (isset($row['Name']) && in_array($row['Name'], array('pam', 'authentication_pam', 'auth_pam_compat'))) { + $have_pam = $row['Name']; break; } } @@ -29,12 +29,54 @@ $res->close(); if (!$have_pam) die("SKIP Server PAM plugin not installed"); +if ($have_pam == 'pam') { + /* MariaDB - needs system variable pam_use_cleartext_plugin=ON to be set */ + if (!$res = mysqli_query($link, 'SHOW GLOBAL VARIABLES LIKE "pam_use_cleartext_plugin"')) + die(sprintf("SKIP MariaDB probe of GLOBAL VARIABLES failed [%d] %s\n", + mysqli_errno($link), mysqli_error($link))); + $pam_use_cleartext_plugin = mysqli_fetch_row($res); + mysqli_free_result($res); + if (!$pam_use_cleartext_plugin or $pam_use_cleartext_plugin[1]!='ON') + die("SKIP Server setting pam_use_cleartext_plugin!=ON"); + + $pam_service = file_get_contents('/etc/pam.d/mysql'); +} elseif ($have_pam == 'authentication_pam') { + /* + required MySQL syntax: + https://dev.mysql.com/doc/refman/8.0/en/pam-pluggable-authentication.html#pam-pluggable-authentication-usage + */ + $have_pam .= " AS 'mysql-unix'"; + $pam_service = file_get_contents('/etc/pam.d/mysql-unix'); +} else { + $pam_service = file_get_contents('/etc/pam.d/mysql'); +} +$auth = 0; +$account = 0; +foreach (explode("\n", $pam_service) as $line) +{ + if (preg_match('/^auth/', $line)) { + $auth = 1; + } elseif (preg_match('/^account/', $line)) { + $account = 1; + } +} +if (!$auth) { + die("SKIP pam service file missing 'auth' directive"); +} +if (!$account) { + die("SKIP pam service file missing 'account' directive"); +} + +if (!posix_getpwnam('pamtest')) { + die("SKIP no pamtest user"); +} +/* Password of user 'pamtest' should be set to 'pamtest' */ mysqli_query($link, 'DROP USER pamtest'); mysqli_query($link, 'DROP USER pamtest@localhost'); -if (!mysqli_query($link, 'CREATE USER pamtest@"%" IDENTIFIED WITH mysql_clear_password') || - !mysqli_query($link, 'CREATE USER pamtest@"localhost" IDENTIFIED WITH mysql_clear_password')) { +if (!mysqli_query($link, "CREATE USER pamtest@'%' IDENTIFIED WITH $have_pam") || + !mysqli_query($link, "CREATE USER pamtest@'localhost' IDENTIFIED WITH $have_pam")) { printf("skip Cannot create second DB user [%d] %s", mysqli_errno($link), mysqli_error($link)); mysqli_close($link); die("skip CREATE USER failed"); @@ -88,6 +130,4 @@ max_execution_time=240 mysqli_query($link, 'DROP USER pamtest@localhost'); ?> --EXPECTF-- -Warning: mysqli_real_connect(): (28000/1045): Access denied for user %s -[001] Cannot connect to the server using host=%s done! diff --git a/ext/mysqlnd/mysqlnd_auth.c b/ext/mysqlnd/mysqlnd_auth.c index 915b735553..7a33fe6d58 100644 --- a/ext/mysqlnd/mysqlnd_auth.c +++ b/ext/mysqlnd/mysqlnd_auth.c @@ -652,7 +652,11 @@ mysqlnd_pam_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self, if (passwd && passwd_len) { ret = (zend_uchar*) zend_strndup(passwd, passwd_len); } - *auth_data_len = passwd_len; + /* + Trailing null required. bug#78680 + https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_authentication_methods_clear_text_password.html + */ + *auth_data_len = passwd_len + 1; return ret; } |