From d5748e7ac62afff65f0935f12a35b9d69b3288d0 Mon Sep 17 00:00:00 2001 From: Sjon Hortensius Date: Mon, 14 Aug 2017 11:41:47 +0200 Subject: [PATCH 1/5] PDO - support username & password specified in DSN --- ext/pdo_mysql/mysql_driver.c | 16 +++++++++--- .../pdo_mysql_dsn_containing_credentials.phpt | 26 +++++++++++++++++++ 2 files changed, 39 insertions(+), 3 deletions(-) create mode 100644 ext/pdo_mysql/tests/pdo_mysql_dsn_containing_credentials.phpt diff --git a/ext/pdo_mysql/mysql_driver.c b/ext/pdo_mysql/mysql_driver.c index ec7d5b8ea72a6..d5278e607ebb1 100644 --- a/ext/pdo_mysql/mysql_driver.c +++ b/ext/pdo_mysql/mysql_driver.c @@ -549,9 +549,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 @@ -577,7 +579,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); @@ -775,6 +777,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_mysql/tests/pdo_mysql_dsn_containing_credentials.phpt b/ext/pdo_mysql/tests/pdo_mysql_dsn_containing_credentials.phpt new file mode 100644 index 0000000000000..65bcf09cf6042 --- /dev/null +++ b/ext/pdo_mysql/tests/pdo_mysql_dsn_containing_credentials.phpt @@ -0,0 +1,26 @@ +--TEST-- +PDO_MYSQL: Pass credentials in dsn instead of constructor params +--SKIPIF-- + +--FILE-- + PDO_MYSQL_TEST_USER, 'password' => PDO_MYSQL_TEST_PASS]); + echo "using credentials in dsn: done\n"; + + // test b/c - credentials in DSN are ignored when user/pass passed as separate params + $link = MySQLPDOTest::factory('PDO', false, null, ['user' => 'incorrect', 'password' => 'ignored']); + echo "ignoring credentials in dsn: done\n"; +?> +--EXPECTF-- +using credentials in dsn: done +ignoring credentials in dsn: done From 5e1a99e5e487d56cb65379e1559684bb2fa0f803 Mon Sep 17 00:00:00 2001 From: Kalle Sommer Nielsen Date: Tue, 15 Aug 2017 15:03:32 +0200 Subject: [PATCH 2/5] Extend PDO support for credentials in DSN to dblib/firebire/oci --- ext/pdo_dblib/dblib_driver.c | 10 ++++++++++ ext/pdo_firebird/firebird_driver.c | 14 ++++++++++++-- ext/pdo_oci/oci_driver.c | 14 ++++++++++++-- 3 files changed, 34 insertions(+), 4 deletions(-) diff --git a/ext/pdo_dblib/dblib_driver.c b/ext/pdo_dblib/dblib_driver.c index efc8dc119782c..c75c69826734b 100644 --- a/ext/pdo_dblib/dblib_driver.c +++ b/ext/pdo_dblib/dblib_driver.c @@ -375,6 +375,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]); @@ -432,12 +434,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 83203d7804f23..448204cc7d3bc 100644 --- a/ext/pdo_firebird/firebird_driver.c +++ b/ext/pdo_firebird/firebird_driver.c @@ -617,14 +617,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_oci/oci_driver.c b/ext/pdo_oci/oci_driver.c index 60205a8e31a13..4facae5018e0e 100644 --- a/ext/pdo_oci/oci_driver.c +++ b/ext/pdo_oci/oci_driver.c @@ -591,10 +591,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; @@ -658,6 +660,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), @@ -669,6 +675,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), From dd96d1d8eadff4ff7df381da410b3aecf1885b77 Mon Sep 17 00:00:00 2001 From: Sjon Hortensius Date: Wed, 16 Aug 2017 13:55:18 +0200 Subject: [PATCH 3/5] Move pdo_dsn_containing_credentials from pdo_mysql to pdo prepend die with skip: --- .../tests/pdo_dsn_containing_credentials.phpt | 35 +++++++++++++++++++ .../pdo_mysql_dsn_containing_credentials.phpt | 26 -------------- 2 files changed, 35 insertions(+), 26 deletions(-) create mode 100644 ext/pdo/tests/pdo_dsn_containing_credentials.phpt delete mode 100644 ext/pdo_mysql/tests/pdo_mysql_dsn_containing_credentials.phpt 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 0000000000000..6c463275f1a1e --- /dev/null +++ b/ext/pdo/tests/pdo_dsn_containing_credentials.phpt @@ -0,0 +1,35 @@ +--TEST-- +PDO Common: Pass credentials in dsn instead of constructor params +--SKIPIF-- + +--FILE-- + getenv('PDOTEST_USER'), 'password' => getenv('PDOTEST_PASS')]); + echo "using credentials in dsn: done\n"; + + // test b/c - credentials in DSN are ignored when user/pass passed as separate params + $link = PDOTest::factory('PDO', false, null, ['user' => 'incorrect', 'password' => 'ignored']); + echo "ignoring credentials in dsn: done\n"; +?> +--EXPECTF-- +using credentials in dsn: done +ignoring credentials in dsn: done diff --git a/ext/pdo_mysql/tests/pdo_mysql_dsn_containing_credentials.phpt b/ext/pdo_mysql/tests/pdo_mysql_dsn_containing_credentials.phpt deleted file mode 100644 index 65bcf09cf6042..0000000000000 --- a/ext/pdo_mysql/tests/pdo_mysql_dsn_containing_credentials.phpt +++ /dev/null @@ -1,26 +0,0 @@ ---TEST-- -PDO_MYSQL: Pass credentials in dsn instead of constructor params ---SKIPIF-- - ---FILE-- - PDO_MYSQL_TEST_USER, 'password' => PDO_MYSQL_TEST_PASS]); - echo "using credentials in dsn: done\n"; - - // test b/c - credentials in DSN are ignored when user/pass passed as separate params - $link = MySQLPDOTest::factory('PDO', false, null, ['user' => 'incorrect', 'password' => 'ignored']); - echo "ignoring credentials in dsn: done\n"; -?> ---EXPECTF-- -using credentials in dsn: done -ignoring credentials in dsn: done From cc3f7b1728d5b95b27b4bc87d634148741da58a6 Mon Sep 17 00:00:00 2001 From: Sjon Hortensius Date: Fri, 17 May 2019 10:33:55 +0200 Subject: [PATCH 4/5] appveyor - don't include credentials in DSN as the tests don't expect it to do anything - which it does since PR #2684 --- appveyor/test_task.bat | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor/test_task.bat b/appveyor/test_task.bat index 3ebc773c30138..66d37d6fd651f 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 From e6e64e46d59db82f0ed78909aeaa155d32df3502 Mon Sep 17 00:00:00 2001 From: Sjon Hortensius Date: Sat, 18 May 2019 13:12:21 +0200 Subject: [PATCH 5/5] Fix test - was moved in dd96d1d8ea but not correctly refactored since PDOTest::factory has a different factory then MySQLPDOTest this test was effectively useless --- .../tests/pdo_dsn_containing_credentials.phpt | 36 +++++++++++++------ 1 file changed, 26 insertions(+), 10 deletions(-) diff --git a/ext/pdo/tests/pdo_dsn_containing_credentials.phpt b/ext/pdo/tests/pdo_dsn_containing_credentials.phpt index 6c463275f1a1e..dca3ba1709e86 100644 --- a/ext/pdo/tests/pdo_dsn_containing_credentials.phpt +++ b/ext/pdo/tests/pdo_dsn_containing_credentials.phpt @@ -17,18 +17,34 @@ PDOTest::skip(); getenv('PDOTEST_USER'), 'password' => getenv('PDOTEST_PASS')]); - echo "using credentials in dsn: done\n"; - // test b/c - credentials in DSN are ignored when user/pass passed as separate params - $link = PDOTest::factory('PDO', false, null, ['user' => 'incorrect', 'password' => 'ignored']); - echo "ignoring 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