Skip to content

Commit ee51eac

Browse files
morozovramsey
authored andcommitted
[Bug #77120] Handle OCI_SUCCESS_WITH_INFO returned from OCISessionBegin
1. Proceed with connection initialization if OCI_SUCCESS_WITH_INFO is returned 2. Do not throw an exception upon OCI_SUCCESS_WITH_INFO
1 parent fa3d198 commit ee51eac

File tree

2 files changed

+86
-2
lines changed

2 files changed

+86
-2
lines changed

ext/pdo_oci/oci_driver.c

+7-2
Original file line numberDiff line numberDiff line change
@@ -175,7 +175,7 @@ ub4 _oci_error(OCIError *err, pdo_dbh_t *dbh, pdo_stmt_t *stmt, char *what, swor
175175
}
176176

177177
/* little mini hack so that we can use this code from the dbh ctor */
178-
if (!dbh->methods) {
178+
if (!dbh->methods && status != OCI_SUCCESS_WITH_INFO) {
179179
zend_throw_exception_ex(php_pdo_get_exception(), einfo->errcode, "SQLSTATE[%s]: %s", *pdo_err, einfo->errmsg);
180180
}
181181

@@ -831,7 +831,12 @@ static int pdo_oci_handle_factory(pdo_dbh_t *dbh, zval *driver_options) /* {{{ *
831831
H->last_err = OCISessionBegin(H->svc, H->err, H->session, OCI_CRED_RDBMS, OCI_DEFAULT);
832832
if (H->last_err) {
833833
oci_drv_error("OCISessionBegin");
834-
goto cleanup;
834+
/* OCISessionBegin returns OCI_SUCCESS_WITH_INFO when
835+
* user's password has expired, but is still usable.
836+
*/
837+
if (H->last_err != OCI_SUCCESS_WITH_INFO) {
838+
goto cleanup;
839+
}
835840
}
836841

837842
/* set the server handle into service handle */
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,79 @@
1+
--TEST--
2+
Handling OCI_SUCCESS_WITH_INFO
3+
--SKIPIF--
4+
<?php
5+
if (!extension_loaded('pdo') || !extension_loaded('pdo_oci')) die('skip not loaded');
6+
?>
7+
--FILE--
8+
<?php
9+
10+
function connectAsAdmin(): PDO {
11+
return PDOTest::test_factory(__DIR__ . '/../../pdo_oci/tests/common.phpt');
12+
}
13+
14+
function connectAsUser(string $username, string $password): PDO {
15+
return new PDO(getenv('PDOTEST_DSN'), $username, $password);
16+
}
17+
18+
function dropProfile(PDO $conn): void {
19+
$conn->exec(<<<'SQL'
20+
BEGIN
21+
EXECUTE IMMEDIATE 'DROP PROFILE BUG77120_PROFILE CASCADE';
22+
EXCEPTION
23+
WHEN OTHERS THEN
24+
IF SQLCODE != -2380 THEN
25+
RAISE;
26+
END IF;
27+
END;
28+
SQL
29+
);
30+
}
31+
32+
function dropUser(PDO $conn): void {
33+
$conn->exec(<<<'SQL'
34+
BEGIN
35+
EXECUTE IMMEDIATE 'DROP USER BUG77120_USER CASCADE';
36+
EXCEPTION
37+
WHEN OTHERS THEN
38+
IF SQLCODE != -1918 THEN
39+
RAISE;
40+
END IF;
41+
END;
42+
SQL
43+
);
44+
}
45+
46+
require __DIR__ . '/../../pdo/tests/pdo_test.inc';
47+
48+
$conn = connectAsAdmin();
49+
50+
dropUser($conn);
51+
dropProfile($conn);
52+
53+
$password = bin2hex(random_bytes(8));
54+
55+
$conn->exec('CREATE PROFILE BUG77120_PROFILE LIMIT PASSWORD_LIFE_TIME 1/86400 PASSWORD_GRACE_TIME 1');
56+
$conn->exec('CREATE USER BUG77120_USER IDENTIFIED BY "' . $password . '" PROFILE BUG77120_PROFILE');
57+
$conn->exec('GRANT CREATE SESSION TO BUG77120_USER');
58+
59+
// let the password expire
60+
sleep(2);
61+
62+
$conn = connectAsUser('BUG77120_USER', $password);
63+
var_dump($conn->errorInfo());
64+
65+
$conn = connectAsAdmin();
66+
dropUser($conn);
67+
dropProfile($conn);
68+
69+
?>
70+
--EXPECTF--
71+
array(3) {
72+
[0]=>
73+
string(5) "HY000"
74+
[1]=>
75+
int(28002)
76+
[2]=>
77+
string(%d) "OCISessionBegin: OCI_SUCCESS_WITH_INFO: ORA-28002: %s
78+
(%s:%d)"
79+
}

0 commit comments

Comments
 (0)