PDO: support username & password specified in DSN

This commit is contained in:
Sjon Hortensius 2017-08-14 11:41:47 +02:00 committed by Nikita Popov
parent 7f1fef9fe0
commit a7881df281
7 changed files with 107 additions and 8 deletions

View File

@ -250,6 +250,14 @@ PHP 7.4 UPGRADE NOTES
PREG_OFFSET_CAPTURE and PREG_UNMATCHED_AS_NULL flags. This influences the
format of the matches array passed to to the callback function.
- PDO:
. The username and password can now be specified as part of the PDO DSN for
the mysql, mssql, sybase, dblib, firebird and oci drivers. Previously this
was only supported by the pgsql driver. If a username/password is specified
both in the constructor and the DSN, the constructor takes precedence.
new PDO("mysql:host=xxx;port=xxx;dbname=xxx;user=xxx;password=xxx");
- PDO_OCI:
. PDOStatement::getColumnMeta() is now available

View File

@ -27,7 +27,7 @@ set PDO_MYSQL_TEST_USER=%MYSQL_TEST_USER%
set PDO_MYSQL_TEST_PASS=%MYSQL_PWD%
set PDO_MYSQL_TEST_HOST=%MYSQL_TEST_HOST%
set PDO_MYSQL_TEST_PORT=%MYSQL_TEST_PORT%
set PDO_MYSQL_TEST_DSN=mysql:host=%PDO_MYSQL_TEST_HOST%;port=%PDO_MYSQL_TEST_PORT%;dbname=test;user=%PDO_MYSQL_TEST_USER%;password=%MYSQL_PW%
set PDO_MYSQL_TEST_DSN=mysql:host=%PDO_MYSQL_TEST_HOST%;port=%PDO_MYSQL_TEST_PORT%;dbname=test
"C:\Program Files\MySql\MySQL Server 5.7\bin\mysql.exe" --user=%MYSQL_TEST_USER% -e "CREATE DATABASE IF NOT EXISTS test"
if %errorlevel% neq 0 exit /b 3

View File

@ -0,0 +1,51 @@
--TEST--
PDO Common: Pass credentials in dsn instead of constructor params
--SKIPIF--
<?php
if (!extension_loaded('pdo')) die('skip');
$dir = getenv('REDIR_TEST_DIR');
if (false == $dir) die('skip no driver');
$driver = substr(getenv('PDOTEST_DSN'), 0, strpos(getenv('PDOTEST_DSN'), ':'));
if (!in_array($driver, array('mssql','sybase','dblib','firebird','mysql','oci')))
die('skip not supported');
require_once $dir . 'pdo_test.inc';
PDOTest::skip();
?>
--FILE--
<?php
require_once getenv('REDIR_TEST_DIR') . 'pdo_test.inc';
$orgDsn = getenv('PDOTEST_DSN');
$orgUser = getenv('PDOTEST_USER');
$orgPass = getenv('PDOTEST_PASS');
try
{
putenv("PDOTEST_DSN=$orgDsn;user=$orgUser;password=$orgPass");
putenv("PDOTEST_USER");
putenv("PDOTEST_PASS");
$link = PDOTest::factory();
echo "using credentials in dsn: done\n";
// test b/c - credentials in DSN are ignored when user/pass passed as separate params
putenv("PDOTEST_DSN=$orgDsn;user=incorrect;password=ignored");
putenv("PDOTEST_USER=$orgUser");
putenv("PDOTEST_PASS=$orgPass");
$link = PDOTest::factory();
echo "ignoring credentials in dsn: done\n";
}
finally
{
putenv("PDOTEST_DSN=$orgDsn");
putenv("PDOTEST_USER=$orgUser");
putenv("PDOTEST_PASS=$orgPass");
}
?>
--EXPECTF--
using credentials in dsn: done
ignoring credentials in dsn: done

View File

@ -458,6 +458,8 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
,{ "dbname", NULL, 0 }
,{ "secure", NULL, 0 } /* DBSETLSECURE */
,{ "version", NULL, 0 } /* DBSETLVERSION */
,{ "user", NULL, 0 }
,{ "password", NULL, 0 }
};
nvars = sizeof(vars)/sizeof(vars[0]);
@ -519,12 +521,20 @@ static int pdo_dblib_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
}
}
if (!dbh->username && vars[6].optval) {
dbh->username = vars[6].optval;
}
if (dbh->username) {
if(FAIL == DBSETLUSER(H->login, dbh->username)) {
goto cleanup;
}
}
if (!dbh->password && vars[7].optval) {
dbh->password = vars[7].optval;
}
if (dbh->password) {
if(FAIL == DBSETLPWD(H->login, dbh->password)) {
goto cleanup;

View File

@ -623,14 +623,24 @@ static int pdo_firebird_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /*
struct pdo_data_src_parser vars[] = {
{ "dbname", NULL, 0 },
{ "charset", NULL, 0 },
{ "role", NULL, 0 }
{ "role", NULL, 0 },
{ "user", NULL, 0 },
{ "password", NULL, 0 }
};
int i, ret = 0;
short buf_len = 256, dpb_len;
pdo_firebird_db_handle *H = dbh->driver_data = pecalloc(1,sizeof(*H),dbh->is_persistent);
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 3);
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 5);
if (!dbh->username && vars[3].optval) {
dbh->username = vars[3].optval;
}
if (!dbh->password && vars[4].optval) {
dbh->password = vars[4].optval;
}
do {
static char const dpb_flags[] = {

View File

@ -571,6 +571,8 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
{ "host", "localhost", 0 },
{ "port", "3306", 0 },
{ "unix_socket", PDO_DEFAULT_MYSQL_UNIX_ADDR, 0 },
{ "user", NULL, 0 },
{ "password", NULL, 0 },
};
int connect_opts = 0
#ifdef CLIENT_MULTI_RESULTS
@ -596,7 +598,7 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
PDO_DBG_INF("multi results");
#endif
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 5);
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 7);
H = pecalloc(1, sizeof(pdo_mysql_db_handle), dbh->is_persistent);
@ -808,6 +810,14 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
unix_socket = vars[4].optval;
}
if (!dbh->username && vars[5].optval) {
dbh->username = vars[5].optval;
}
if (!dbh->password && vars[6].optval) {
dbh->password = vars[6].optval;
}
/* TODO: - Check zval cache + ZTS */
#ifdef PDO_USE_MYSQLND
if (dbname) {

View File

@ -678,10 +678,12 @@ static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ *
int i, ret = 0;
struct pdo_data_src_parser vars[] = {
{ "charset", NULL, 0 },
{ "dbname", "", 0 }
{ "dbname", "", 0 },
{ "user", NULL, 0 },
{ "password", NULL, 0 }
};
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 2);
php_pdo_parse_data_source(dbh->data_source, dbh->data_source_len, vars, 4);
H = pecalloc(1, sizeof(*H), dbh->is_persistent);
dbh->driver_data = H;
@ -745,6 +747,10 @@ static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ *
}
/* username */
if (!dbh->username && vars[2].optval) {
dbh->username = vars[2].optval;
}
if (dbh->username) {
H->last_err = OCIAttrSet(H->session, OCI_HTYPE_SESSION,
dbh->username, (ub4) strlen(dbh->username),
@ -756,6 +762,10 @@ static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ *
}
/* password */
if (!dbh->password && vars[3].optval) {
dbh->password = vars[3].optval;
}
if (dbh->password) {
H->last_err = OCIAttrSet(H->session, OCI_HTYPE_SESSION,
dbh->password, (ub4) strlen(dbh->password),