]> granicus.if.org Git - php/commitdiff
PDO: support username & password specified in DSN
authorSjon Hortensius <sjon@hortensius.net>
Mon, 14 Aug 2017 09:41:47 +0000 (11:41 +0200)
committerNikita Popov <nikita.ppv@gmail.com>
Tue, 2 Jul 2019 10:09:38 +0000 (12:09 +0200)
UPGRADING
appveyor/test_task.bat
ext/pdo/tests/pdo_dsn_containing_credentials.phpt [new file with mode: 0644]
ext/pdo_dblib/dblib_driver.c
ext/pdo_firebird/firebird_driver.c
ext/pdo_mysql/mysql_driver.c
ext/pdo_oci/oci_driver.c

index 4b0621dab28ed656a5dfcd8f568fde7490eaed09..6ce27cef86f6dc52b545fd66b618e4b31d27a2bf 100644 (file)
--- 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
 
index 2abe96642a441e8f2a9780b8e50d98ac3d5e97dd..ba6a862f22abe17c5c2234f454e8be8b6a7fe3e9 100644 (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
 
diff --git a/ext/pdo/tests/pdo_dsn_containing_credentials.phpt b/ext/pdo/tests/pdo_dsn_containing_credentials.phpt
new file mode 100644 (file)
index 0000000..dca3ba1
--- /dev/null
@@ -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
index 748929e5325962767603ad84d119b28331a77c48..7f2b7ebe3cfcb57f34160ce21bec6c190ca5ca26 100644 (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;
index 53ffbdc7c672904ca0db40d5355ddf5907b6c05a..e1b03a460169c61bc77cc70f0177e60f03868ceb 100644 (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[] = {
index ad7989d66096500cb48c3953634ede48234ca4a6..6910582ba5ccbb8aede4307e51fb9e3f7719c305 100644 (file)
@@ -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) {
index eb1f70bdb0977f8bbadd52155bde7c80c8dd395c..3ee02657c3db71a2478b930d7ac9bccec1f2439d 100644 (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),