diff options
author | Nikita Popov <nikita.ppv@gmail.com> | 2021-02-15 11:33:01 +0100 |
---|---|---|
committer | Nikita Popov <nikita.ppv@gmail.com> | 2021-02-15 11:33:01 +0100 |
commit | f01ad22bab98d20f4183d32c57f529fe5ee71828 (patch) | |
tree | c78849c5110cc1db6f3683590d9aa9bd85f8c2ef | |
parent | fe01a7c515ba940155c9303ecfa4ad06fc4e2219 (diff) | |
parent | 8b9dd0a3014e7a3c76fc2ddded374fa4ca0ed386 (diff) | |
download | php-git-f01ad22bab98d20f4183d32c57f529fe5ee71828.tar.gz |
Merge branch 'PHP-8.0'
* PHP-8.0:
Fix #78680: mysqlnd pam plugin missing terminating null
-rw-r--r-- | ext/mysqli/tests/mysqli_auth_pam.phpt | 52 | ||||
-rw-r--r-- | ext/mysqlnd/mysqlnd_auth.c | 6 |
2 files changed, 51 insertions, 7 deletions
diff --git a/ext/mysqli/tests/mysqli_auth_pam.phpt b/ext/mysqli/tests/mysqli_auth_pam.phpt index 7d23ee5782..0c59e25a32 100644 --- a/ext/mysqli/tests/mysqli_auth_pam.phpt +++ b/ext/mysqli/tests/mysqli_auth_pam.phpt @@ -18,8 +18,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; } } @@ -28,12 +28,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"); @@ -87,6 +129,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 ce2fa63d6e..e3fb6fc90f 100644 --- a/ext/mysqlnd/mysqlnd_auth.c +++ b/ext/mysqlnd/mysqlnd_auth.c @@ -648,7 +648,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; } |