Skip to content

Commit 8b9dd0a

Browse files
committed
Merge branch 'PHP-7.4' into PHP-8.0
* PHP-7.4: Fix #78680: mysqlnd pam plugin missing terminating null
2 parents 8e9eeca + 3646604 commit 8b9dd0a

File tree

3 files changed

+55
-7
lines changed

3 files changed

+55
-7
lines changed

NEWS

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,10 @@ PHP NEWS
1313
. Fixed bug #53251 (bindtextdomain with null dir doesn't return old value).
1414
(cmb)
1515

16+
- MySQLnd:
17+
. Fixed bug #78680 (mysqlnd's mysql_clear_password does not transmit
18+
null-terminated password). (Daniel Black)
19+
1620
- MySQLi:
1721
. Fixed bug #74779 (x() and y() truncating floats to integers). (cmb)
1822

ext/mysqli/tests/mysqli_auth_pam.phpt

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@ if (!$res = $link->query("SHOW PLUGINS"))
1818

1919
$have_pam = false;
2020
while ($row = $res->fetch_assoc()) {
21-
if (isset($row['Name']) && ('mysql_clear_password' == $row['Name'])) {
22-
$have_pam = true;
21+
if (isset($row['Name']) && in_array($row['Name'], array('pam', 'authentication_pam', 'auth_pam_compat'))) {
22+
$have_pam = $row['Name'];
2323
break;
2424
}
2525
}
@@ -28,12 +28,54 @@ $res->close();
2828
if (!$have_pam)
2929
die("SKIP Server PAM plugin not installed");
3030

31+
if ($have_pam == 'pam') {
32+
/* MariaDB - needs system variable pam_use_cleartext_plugin=ON to be set */
33+
if (!$res = mysqli_query($link, 'SHOW GLOBAL VARIABLES LIKE "pam_use_cleartext_plugin"'))
34+
die(sprintf("SKIP MariaDB probe of GLOBAL VARIABLES failed [%d] %s\n",
35+
mysqli_errno($link), mysqli_error($link)));
36+
$pam_use_cleartext_plugin = mysqli_fetch_row($res);
37+
mysqli_free_result($res);
38+
if (!$pam_use_cleartext_plugin or $pam_use_cleartext_plugin[1]!='ON')
39+
die("SKIP Server setting pam_use_cleartext_plugin!=ON");
40+
41+
$pam_service = file_get_contents('/etc/pam.d/mysql');
42+
} elseif ($have_pam == 'authentication_pam') {
43+
/*
44+
required MySQL syntax:
45+
https://dev.mysql.com/doc/refman/8.0/en/pam-pluggable-authentication.html#pam-pluggable-authentication-usage
46+
*/
47+
$have_pam .= " AS 'mysql-unix'";
48+
$pam_service = file_get_contents('/etc/pam.d/mysql-unix');
49+
} else {
50+
$pam_service = file_get_contents('/etc/pam.d/mysql');
51+
}
52+
$auth = 0;
53+
$account = 0;
54+
foreach (explode("\n", $pam_service) as $line)
55+
{
56+
if (preg_match('/^auth/', $line)) {
57+
$auth = 1;
58+
} elseif (preg_match('/^account/', $line)) {
59+
$account = 1;
60+
}
61+
}
62+
if (!$auth) {
63+
die("SKIP pam service file missing 'auth' directive");
64+
}
65+
if (!$account) {
66+
die("SKIP pam service file missing 'account' directive");
67+
}
68+
69+
if (!posix_getpwnam('pamtest')) {
70+
die("SKIP no pamtest user");
71+
}
72+
/* Password of user 'pamtest' should be set to 'pamtest' */
3173

3274
mysqli_query($link, 'DROP USER pamtest');
3375
mysqli_query($link, 'DROP USER pamtest@localhost');
3476

35-
if (!mysqli_query($link, 'CREATE USER pamtest@"%" IDENTIFIED WITH mysql_clear_password') ||
36-
!mysqli_query($link, 'CREATE USER pamtest@"localhost" IDENTIFIED WITH mysql_clear_password')) {
77+
if (!mysqli_query($link, "CREATE USER pamtest@'%' IDENTIFIED WITH $have_pam") ||
78+
!mysqli_query($link, "CREATE USER pamtest@'localhost' IDENTIFIED WITH $have_pam")) {
3779
printf("skip Cannot create second DB user [%d] %s", mysqli_errno($link), mysqli_error($link));
3880
mysqli_close($link);
3981
die("skip CREATE USER failed");
@@ -87,6 +129,4 @@ max_execution_time=240
87129
mysqli_query($link, 'DROP USER pamtest@localhost');
88130
?>
89131
--EXPECTF--
90-
Warning: mysqli_real_connect(): (28000/1045): Access denied for user %s
91-
[001] Cannot connect to the server using host=%s
92132
done!

ext/mysqlnd/mysqlnd_auth.c

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -650,7 +650,11 @@ mysqlnd_pam_auth_get_auth_data(struct st_mysqlnd_authentication_plugin * self,
650650
if (passwd && passwd_len) {
651651
ret = (zend_uchar*) zend_strndup(passwd, passwd_len);
652652
}
653-
*auth_data_len = passwd_len;
653+
/*
654+
Trailing null required. bug#78680
655+
https://dev.mysql.com/doc/dev/mysql-server/latest/page_protocol_connection_phase_authentication_methods_clear_text_password.html
656+
*/
657+
*auth_data_len = passwd_len + 1;
654658

655659
return ret;
656660
}

0 commit comments

Comments
 (0)