php.net |  support |  documentation |  report a bug |  advanced search |  search howto |  statistics |  random bug |  login
Bug #43812 MYSQLI_READ_DEFAULT_FILE option ignored when using mysqlnd
Submitted: 2008-01-11 03:32 UTC Modified: 2020-10-29 10:20 UTC
Votes:19
Avg. Score:4.4 ± 0.9
Reproduced:19 of 19 (100.0%)
Same Version:4 (21.1%)
Same OS:4 (21.1%)
From: graced at wingsnw dot com Assigned:
Status: Open Package: MySQLi related
PHP Version: 5.2.5 OS: Debian lenny/sid
Private report: No CVE-ID: None
View Developer Edit
Welcome! If you don't have a Git account, you can't do anything here.
If you reported this bug, you can edit this bug over here.
(description)
Block user comment
Status: Assign to:
Package:
Bug Type:
Summary:
From: graced at wingsnw dot com
New email:
PHP Version: OS:

 

 [2008-01-11 03:32 UTC] graced at wingsnw dot com
Description:
------------
my.cnf files allow the username/password/hostname and other connection information to be stored for later use.

The Mysqli extension accepts a username from the file (overriding the default of the current login username) but not a password, thus it attempts to connect with no password even when a password is specified.  The mysql command line client, when pointed at the file using --defaults-extra-file=path/to/file.cnf, successfully connects.

Reproduce code:
---------------
my.cnf contents:
[client]
host     = localhost
user     = "username"
password = "topsecret"

PHP script:
<?php
error_reporting(E_ALL);
$DB = mysqli_init();
$DB->options(MYSQLI_READ_DEFAULT_FILE, "my.cnf");
$DB->options(MYSQLI_READ_DEFAULT_GROUP, "client");
$DB->real_connect();



Expected result:
----------------
A successful database connection.

Actual result:
--------------
Warning: mysqli::real_connect(): (28000/1045): Access denied for user 'wadmin'@'localhost' (using password: NO) in /home/.../- on line 6


Patches

Pull Requests

History

AllCommentsChangesGit/SVN commitsRelated reports
 [2008-01-15 05:03 UTC] graced at wingsnw dot com
Clarification: 

Warning: mysqli::real_connect(): (28000/1045): Access denied for user
'wadmin'@'localhost' (using password: NO) in /home/.../- on line 6

'wadmin' was the username I was connecting with (I missed it when sanitizing my.cnf values), NOT my current login name (which is what PHP and mysql both default to otherwise).

Just in case it matters.
 [2008-07-14 20:28 UTC] uw@php.net
I can't reproduce this with PHP 5.3 CVS nor with PHP 5.2.6, please check the notes on http://dev.mysql.com/doc/refman/5.1/en/option-files.html, e.g. "On Unix platforms, MySQL ignores configuration files that are world-writable. This is intentional as a security measure."


 [2008-07-22 01:00 UTC] php-bugs at lists dot php dot net
No feedback was provided for this bug for over a week, so it is
being suspended automatically. If you are able to provide the
information that was originally requested, please do so and change
the status of the bug back to "Open".
 [2009-07-27 06:36 UTC] axz55 at case dot edu
Also able to reproduce this using PHP 5.3.0

Verified that the username is being read from the file but the password is not. The file permissions are 0400 and the mysql command line client reads the file just fine.
 [2015-02-26 16:47 UTC] ben at redsnapper dot net
This problem is reproducible and has nothing to do with the read-status of the my.cnf files. We are seeing username,host,database all being set by the my.cnf file - but not the password value.  

mysqli_real_connect(): (28000/1045): Access denied for user 'special_u'@'101.202.185.245' (using password: NO)

We have tested the same file using mysql --defaults-extra-file=my.cnf  with no problems.
 [2016-01-06 19:11 UTC] fms at hy dot com dot br
Same problem on 

FreeBSD 10.2-RELEASE
PHP 5.4.45 (cli) (built: Dec  8 2015 02:46:46)
Copyright (c) 1997-2014 The PHP Group
Zend Engine v2.4.0, Copyright (c) 1998-2014 Zend Technologies

Warning: mysqli::real_connect(): (HY000/1045): Access denied for user ''@'localhost' (using password: NO) in /usr/local/share/www/index.php on line 17


[client]
user="johndoe"
password="password-john"
host=127.0.0.1
port=3306
socket=/tmp/mysql.sock
database=customers
default-character-set=utf8
 [2016-01-06 20:01 UTC] requinix@php.net
-Assigned To: andrey +Assigned To:
 [2016-01-06 20:01 UTC] requinix@php.net
Can someone confirm this is still happening with PHP 5.6 or 7? Repro: the my.cnf file is private (0400 with the same owner that PHP is running as), the host and username parameters are respected, but the password is not. That means a conf file like
> [client]
> host     = "yourhost"
> user     = "yourusername"
> password = "yourpassword"
and an error message like
> Access denied for user 'yourusername'@'yourhost' (using password: NO)

For now use just the standard my.cnf file and [client] section - don't set MYSQLI_READ_DEFAULT_FILE/GROUP.

@ben: Are you using PHP 5.6 or 7? Are you still having the problem?
@fms: (a) The error message says the host and username options are not being used. Make sure you're using my.cnf and not a custom file, and that it's set to 0400 permissions. (b) PHP 5.4 is no longer supported - please try with 5.6 or later.
 [2016-01-06 20:53 UTC] ben at redsnapper dot net
<?php
mb_internal_encoding('UTF-8');
$mycnf="my.cnf";
$sql = mysqli_init();
mysqli_options($sql,MYSQLI_READ_DEFAULT_FILE,$mycnf);
mysqli_real_connect($sql);

Run on 5.6 responds with "Warning: mysqli_real_connect(): (HY000/2002): No such file or directory in /Users/ben/test.php on line 6" - SO the error message has changed, but the effect is no connection still.

Note that php see the file (using file_exists()).
 [2016-01-06 20:57 UTC] requinix@php.net
Do you have host=localhost? If so then the error message is probably referring to a missing socket file (which it always tries to use with host=localhost). Try with host=127.0.0.1 to force a TCP connection.
 [2016-01-06 23:06 UTC] ben at redsnapper dot net
All our databases are remote. Using DNS is obviously correct, but it makes no difference if we use either an IPv4 or DNS for the host. Localhost is a red herring here. 
"mysql --defaults-extra-file=my.cnf" works fine from commandline, and fails within php. Now tested in both 5.6 and 7.
Compare the two following code fragments.

<?php
//This code works. It's a nasty workaround.
mb_internal_encoding('UTF-8');
$mycnf="/Users/ben/my.cnf";
$sqls = parse_ini_file($mycnf);
$sql = mysqli_init();
mysqli_real_connect($sql,$sqls['host'],$sqls['user'],$sqls['password'],$sqls['database']);
if ($rs = $sql->query("select TABLE_NAME from information_schema.columns group by TABLE_NAME")) {
	print $rs->num_rows . "\n";
	$rs->close();
};
//


<?php
//This code fails.
mb_internal_encoding('UTF-8');
$mycnf="/Users/ben/my.cnf";
$sql = mysqli_init();
mysqli_options($sql,MYSQLI_READ_DEFAULT_FILE,$mycnf);
mysqli_real_connect($sql);
if ($rs = $sql->query("select TABLE_NAME from information_schema.columns group by TABLE_NAME")) {
	print $rs->num_rows . "\n";
	$rs->close();
};

In my opinion, PHP shouldn't even need read access to the file - as it should pass over the information to the mysqlclient library, which should need read access to the file.
 [2016-01-07 04:54 UTC] requinix@php.net
I was looking at the source code for mysqli and mysqlnd earlier and it seemed like the MYSQLI_READ_DEFAULT_FILE/GROUP settings were explicitly not implemented. That's why I said to repro without using those.
So if you put your settings into the global my.cnf (probably in /etc or /usr/local/mysql*) is there a difference?
 [2016-01-07 04:54 UTC] requinix@php.net
-Status: No Feedback +Status: Feedback
 [2016-01-07 04:54 UTC] requinix@php.net
Might as well reopen this since we're talking about it.
 [2016-01-07 20:30 UTC] ben at redsnapper dot net
''So if you put your settings into the global my.cnf (probably in /etc or /usr/local/mysql*) is there a difference?''

No. I get the same errors.

To be honest, NOT implementing MYSQLI_READ_DEFAULT_FILE is a huge bug for us. Our processor cluster uses arbitrary connection values on a per-request basis, connecting to our database cluster of over 100 database instances.  We don't like having to needlessly read sensitive connection data into user memory, and consider this lack of support to be one of our greatest security concerns.  I am under the impression that PHP/Zend considers itself to be suitable for enterprise environments.

Also, note the assertion of implementation found at http://php.net/manual/en/mysqli.options.php
It's a bug.
 [2016-01-17 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 [2016-01-17 04:39 UTC] requinix@php.net
-Status: No Feedback +Status: Re-Opened
 [2016-12-12 13:14 UTC] hsc@php.net
This still seems to be broken on Debian 7.0's PHP 5.6.27-0+deb8u1 (with php5-mysqlnd 5.6.27+dfsg-0+deb8u1) and Ubuntu 16.10's PHP 7.0.8-3ubuntu3 (with php7.0-mysql 7.0.8-3ubuntu3).

Setup:

$ php --version
PHP 7.0.8-3ubuntu3 (cli) ( NTS )
Copyright (c) 1997-2016 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2016 Zend Technologies
    with Zend OPcache v7.0.8-3ubuntu3, Copyright (c) 1999-2016, by Zend Technologies
$ cat dbtest.php 
<?php
error_reporting(E_ALL);
$DB = mysqli_init();
$DB->options(MYSQLI_READ_DEFAULT_FILE, "/xxxxx/.my.cnf") || die();
$DB->options(MYSQLI_READ_DEFAULT_GROUP, "client") || die();
$DB->real_connect();
$ cat ~/.my.cnf
[client]
host=xxx_some_remote_host
user=xxx
password=xxx

Connect fails:

$ php dbtest.php
PHP Warning:  mysqli::real_connect(): (HY000/2002): No such file or directory in /xxxxx/dbtest.php on line 6

strace shows that the php process doesn't even try opening .my.cnf:

$ strace -e trace=file,network php dbtest.php
[...]
open("dbtest.php", O_RDONLY)            = 3
[... several calls to getcwd and lstat ...]
socket(AF_LOCAL, SOCK_STREAM, 0)        = 3
connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/mysqld/mysqld.sock"}, 29) = -1 ENOENT (No such file or directory)
PHP Warning:  mysqli::real_connect(): (HY000/2002): No such file or directory in /xxxxx/dbtest.php on line 6
+++ exited with 0 +++

See also:
https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=835173
http://stackoverflow.com/questions/12241333/mysql-wont-read-password-from-configuration-file
 [2017-03-06 16:32 UTC] juan at verdnatura dot es
I confirm that this still affects to debian php 7.

Someone is looking to solve it?

https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=835173
 [2017-04-18 09:36 UTC] fjanisze@php.net
-Status: Re-Opened +Status: Feedback
 [2017-04-18 09:36 UTC] fjanisze@php.net
Hi everybody,

I'm attempting to reproduce this problem with very little luck, I'm running Oracle Linux release 3.10.0-514.10.2.el7.x86_64 with:

PHP 7.1.3 (cli) (built: Apr 18 2017 11:05:24) ( NTS DEBUG GCOV )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.1.0, Copyright (c) 1998-2017 Zend Technologies

And MySQL 5.7.18 configured in secure mode, with the following my.conf file:

[client]
user="root"
password="Pass"
host=localhost
port=3380
socket=/tmp/mysql.sock
database=test
default-character-set=utf8

The test script is:

error_reporting(E_ALL);
$DB = mysqli_init();
$DB->options(MYSQLI_READ_DEFAULT_FILE, "./my.conf");
$DB->options(MYSQLI_READ_DEFAULT_GROUP, "client");
$DB->real_connect();

And the connection works perfectly, the my.conf file is used to fetch the authentication data.

From the log snipped from hsd@php.net the error:

connect(3, {sa_family=AF_LOCAL, sun_path="/var/run/mysqld/mysqld.sock"}, 29) = -1 ENOENT (No such file or directory)

Looks to be related with the missing mysqld.sock file which then cause the connection failure. Was an eventual socket file problem (missing &c) excluded already?
 [2017-04-18 11:11 UTC] ben at redsnapper dot net
PHP 7.0.17 (cli) (built: Mar 18 2017 20:13:50) ( NTS )
Copyright (c) 1997-2017 The PHP Group
Zend Engine v3.0.0, Copyright (c) 1998-2017 Zend Technologies

System Version:	macOS 10.12.4 (16E195)
Kernel Version:	Darwin 16.5.0
  
mysql  Ver 14.14 Distrib 5.7.9, for osx10.9 (x86_64) using  EditLine wrapper

Following fjanisze@php.net exact files, the bug is still failing on 7.0.17

PHP Warning:  mysqli::real_connect(): (HY000/1045): Access denied for user ''@'localhost' (using password: NO) in php shell code on line 1

Warning: mysqli::real_connect(): (HY000/1045): Access denied for user ''@'localhost' (using password: NO) in php shell code on line 1
 [2017-04-18 12:00 UTC] ben at redsnapper dot net
mysqli_nonapi.c  line 59.

The problem (as I understand it) is that the connect()/real_connect() function is parsing no parameters and returning empty-strings when it calls zend_parse_parameters. So the connect() to mysql is using (default) empty_string password value which is being understood as THE password to use for the connection rather than what has been set via the defaults-extra-file.  So, as I understand it, allow_null needs to be set (and needs to be the default) on the connect() methods.
 [2017-04-30 04:22 UTC] php-bugs at lists dot php dot net
No feedback was provided. The bug is being suspended because
we assume that you are no longer experiencing the problem.
If this is not the case and you are able to provide the
information that was requested earlier, please do so and
change the status of the bug back to "Re-Opened". Thank you.
 [2017-04-30 07:20 UTC] requinix@php.net
-Status: No Feedback +Status: Open
 [2020-10-29 10:20 UTC] nikic@php.net
-Summary: 'password' parameter in my.cnf not honored even with mysqli_options() +Summary: MYSQLI_READ_DEFAULT_FILE option ignored when using mysqlnd
 [2020-10-29 10:20 UTC] nikic@php.net
The actual problem here is that mysqlnd simply doesn't support this option, see https://github.com/php/php-src/blob/5e695343ec9a4e6b9b7044ec1beabdfb0a398adc/ext/mysqlnd/mysqlnd_connection.c#L1685-L1692.

People for whom this works are linking against libmysqlclient, which does support it.
 
PHP Copyright © 2001-2024 The PHP Group
All rights reserved.
Last updated: Sat Nov 23 07:01:29 2024 UTC