summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSjon Hortensius <sjon@hortensius.net>2017-08-14 11:41:47 +0200
committerNikita Popov <nikita.ppv@gmail.com>2019-07-02 12:09:38 +0200
commita7881df281f74e13cf360fd3624ef849ce747e33 (patch)
tree0dd93c6782e7e9293f79d76ec38050245d7735f3
parent7f1fef9fe0a465909eb454edf36836131f484ba4 (diff)
downloadphp-git-a7881df281f74e13cf360fd3624ef849ce747e33.tar.gz
PDO: support username & password specified in DSN
-rw-r--r--UPGRADING8
-rw-r--r--appveyor/test_task.bat2
-rw-r--r--ext/pdo/tests/pdo_dsn_containing_credentials.phpt51
-rw-r--r--ext/pdo_dblib/dblib_driver.c10
-rw-r--r--ext/pdo_firebird/firebird_driver.c14
-rw-r--r--ext/pdo_mysql/mysql_driver.c16
-rw-r--r--ext/pdo_oci/oci_driver.c14
7 files changed, 107 insertions, 8 deletions
diff --git a/UPGRADING b/UPGRADING
index 4b0621dab2..6ce27cef86 100644
--- a/UPGRADING
+++ b/UPGRADING
@@ -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
diff --git a/appveyor/test_task.bat b/appveyor/test_task.bat
index 2abe96642a..ba6a862f22 100644
--- a/appveyor/test_task.bat
+++ b/appveyor/test_task.bat
@@ -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
diff --git a/ext/pdo/tests/pdo_dsn_containing_credentials.phpt b/ext/pdo/tests/pdo_dsn_containing_credentials.phpt
new file mode 100644
index 0000000000..dca3ba1709
--- /dev/null
+++ b/ext/pdo/tests/pdo_dsn_containing_credentials.phpt
@@ -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
diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c
index 748929e532..7f2b7ebe3c 100644
--- a/ext/pdo_dblib/dblib_driver.c
+++ b/ext/pdo_dblib/dblib_driver.c
@@ -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;
diff --git a/ext/pdo_firebird/firebird_driver.c b/ext/pdo_firebird/firebird_driver.c
index 53ffbdc7c6..e1b03a4601 100644
--- a/ext/pdo_firebird/firebird_driver.c
+++ b/ext/pdo_firebird/firebird_driver.c
@@ -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[] = {
diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c
index ad7989d660..6910582ba5 100644
--- a/ext/pdo_mysql/mysql_driver.c
+++ b/ext/pdo_mysql/mysql_driver.c
@@ -568,9 +568,11 @@ static int pdo_mysql_handle_factory(pdo_dbh_t *dbh, zval *driver_options)
struct pdo_data_src_parser vars[] = {
{ "charset", NULL, 0 },
{ "dbname", "", 0 },
- { "host", "localhost", 0 },
- { "port", "3306", 0 },
+ { "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) {
diff --git a/ext/pdo_oci/oci_driver.c b/ext/pdo_oci/oci_driver.c
index eb1f70bdb0..3ee02657c3 100644
--- a/ext/pdo_oci/oci_driver.c
+++ b/ext/pdo_oci/oci_driver.c
@@ -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),