Skip to content

Commit e65fbe1

Browse files
committed
Merge branch 'PHP-8.4'
* PHP-8.4: NEWS for phpGH-17940 NEWS for phpGH-17940 Fix php#17776 LDAP_OPT_X_TLS_REQUIRE_CERT can't be overridden
2 parents 787f26c + b3a43ca commit e65fbe1

File tree

4 files changed

+141
-25
lines changed

4 files changed

+141
-25
lines changed

ext/ldap/ldap.c

Lines changed: 66 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -859,6 +859,21 @@ static PHP_GINIT_FUNCTION(ldap)
859859
}
860860
/* }}} */
861861

862+
/* {{{ PHP_RINIT_FUNCTION */
863+
static PHP_RINIT_FUNCTION(ldap)
864+
{
865+
#if defined(COMPILE_DL_LDAP) && defined(ZTS)
866+
ZEND_TSRMLS_CACHE_UPDATE();
867+
#endif
868+
869+
/* needed before first connect and after TLS option changes */
870+
LDAPG(tls_newctx) = true;
871+
872+
return SUCCESS;
873+
}
874+
/* }}} */
875+
876+
862877
/* {{{ PHP_MINIT_FUNCTION */
863878
PHP_MINIT_FUNCTION(ldap)
864879
{
@@ -1014,6 +1029,20 @@ PHP_FUNCTION(ldap_connect)
10141029
snprintf( url, urllen, "ldap://%s:" ZEND_LONG_FMT, host, port );
10151030
}
10161031

1032+
#ifdef LDAP_OPT_X_TLS_NEWCTX
1033+
if (LDAPG(tls_newctx) && url && !strncmp(url, "ldaps:", 6)) {
1034+
int val = 0;
1035+
1036+
/* ensure all pending TLS options are applied in a new context */
1037+
if (ldap_set_option(NULL, LDAP_OPT_X_TLS_NEWCTX, &val) != LDAP_OPT_SUCCESS) {
1038+
zval_ptr_dtor(return_value);
1039+
php_error_docref(NULL, E_WARNING, "Could not create new security context");
1040+
RETURN_FALSE;
1041+
}
1042+
LDAPG(tls_newctx) = false;
1043+
}
1044+
#endif
1045+
10171046
#ifdef LDAP_API_FEATURE_X_OPENLDAP
10181047
/* ldap_init() is deprecated, use ldap_initialize() instead.
10191048
*/
@@ -3141,15 +3170,7 @@ PHP_FUNCTION(ldap_set_option)
31413170
}
31423171

31433172
switch (option) {
3144-
/* options with int value */
3145-
case LDAP_OPT_DEREF:
3146-
case LDAP_OPT_SIZELIMIT:
3147-
case LDAP_OPT_TIMELIMIT:
3148-
case LDAP_OPT_PROTOCOL_VERSION:
3149-
case LDAP_OPT_ERROR_NUMBER:
3150-
#ifdef LDAP_OPT_DEBUG_LEVEL
3151-
case LDAP_OPT_DEBUG_LEVEL:
3152-
#endif
3173+
/* TLS options with int value */
31533174
#ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
31543175
case LDAP_OPT_X_TLS_REQUIRE_CERT:
31553176
#endif
@@ -3161,6 +3182,18 @@ PHP_FUNCTION(ldap_set_option)
31613182
#endif
31623183
#ifdef LDAP_OPT_X_TLS_PROTOCOL_MAX
31633184
case LDAP_OPT_X_TLS_PROTOCOL_MAX:
3185+
#endif
3186+
/* TLS option change requires resetting TLS context */
3187+
LDAPG(tls_newctx) = true;
3188+
ZEND_FALLTHROUGH;
3189+
/* other options with int value */
3190+
case LDAP_OPT_DEREF:
3191+
case LDAP_OPT_SIZELIMIT:
3192+
case LDAP_OPT_TIMELIMIT:
3193+
case LDAP_OPT_PROTOCOL_VERSION:
3194+
case LDAP_OPT_ERROR_NUMBER:
3195+
#ifdef LDAP_OPT_DEBUG_LEVEL
3196+
case LDAP_OPT_DEBUG_LEVEL:
31643197
#endif
31653198
#ifdef LDAP_OPT_X_KEEPALIVE_IDLE
31663199
case LDAP_OPT_X_KEEPALIVE_IDLE:
@@ -3234,17 +3267,7 @@ PHP_FUNCTION(ldap_set_option)
32343267
}
32353268
} break;
32363269
#endif
3237-
/* options with string value */
3238-
case LDAP_OPT_ERROR_STRING:
3239-
#ifdef LDAP_OPT_HOST_NAME
3240-
case LDAP_OPT_HOST_NAME:
3241-
#endif
3242-
#ifdef HAVE_LDAP_SASL
3243-
case LDAP_OPT_X_SASL_MECH:
3244-
case LDAP_OPT_X_SASL_REALM:
3245-
case LDAP_OPT_X_SASL_AUTHCID:
3246-
case LDAP_OPT_X_SASL_AUTHZID:
3247-
#endif
3270+
/* TLS options with string value */
32483271
#if (LDAP_API_VERSION > 2000)
32493272
case LDAP_OPT_X_TLS_CACERTDIR:
32503273
case LDAP_OPT_X_TLS_CACERTFILE:
@@ -3258,6 +3281,20 @@ PHP_FUNCTION(ldap_set_option)
32583281
#endif
32593282
#ifdef LDAP_OPT_X_TLS_DHFILE
32603283
case LDAP_OPT_X_TLS_DHFILE:
3284+
#endif
3285+
/* TLS option change requires resetting TLS context */
3286+
LDAPG(tls_newctx) = true;
3287+
ZEND_FALLTHROUGH;
3288+
/* other options with string value */
3289+
case LDAP_OPT_ERROR_STRING:
3290+
#ifdef LDAP_OPT_HOST_NAME
3291+
case LDAP_OPT_HOST_NAME:
3292+
#endif
3293+
#ifdef HAVE_LDAP_SASL
3294+
case LDAP_OPT_X_SASL_MECH:
3295+
case LDAP_OPT_X_SASL_REALM:
3296+
case LDAP_OPT_X_SASL_AUTHCID:
3297+
case LDAP_OPT_X_SASL_AUTHZID:
32613298
#endif
32623299
#ifdef LDAP_OPT_MATCHED_DN
32633300
case LDAP_OPT_MATCHED_DN:
@@ -3675,6 +3712,9 @@ PHP_FUNCTION(ldap_start_tls)
36753712
zval *link;
36763713
ldap_linkdata *ld;
36773714
int rc, protocol = LDAP_VERSION3;
3715+
#ifdef LDAP_OPT_X_TLS_NEWCTX
3716+
int val = 0;
3717+
#endif
36783718

36793719
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &link, ldap_link_ce) != SUCCESS) {
36803720
RETURN_THROWS();
@@ -3684,13 +3724,16 @@ PHP_FUNCTION(ldap_start_tls)
36843724
VERIFY_LDAP_LINK_CONNECTED(ld);
36853725

36863726
if (((rc = ldap_set_option(ld->link, LDAP_OPT_PROTOCOL_VERSION, &protocol)) != LDAP_SUCCESS) ||
3727+
#ifdef LDAP_OPT_X_TLS_NEWCTX
3728+
(LDAPG(tls_newctx) && (rc = ldap_set_option(ld->link, LDAP_OPT_X_TLS_NEWCTX, &val)) != LDAP_OPT_SUCCESS) ||
3729+
#endif
36873730
((rc = ldap_start_tls_s(ld->link, NULL, NULL)) != LDAP_SUCCESS)
36883731
) {
36893732
php_error_docref(NULL, E_WARNING,"Unable to start TLS: %s", ldap_err2string(rc));
36903733
RETURN_FALSE;
3691-
} else {
3692-
RETURN_TRUE;
36933734
}
3735+
LDAPG(tls_newctx) = false;
3736+
RETURN_TRUE;
36943737
}
36953738
/* }}} */
36963739
#endif
@@ -4213,7 +4256,7 @@ zend_module_entry ldap_module_entry = { /* {{{ */
42134256
ext_functions,
42144257
PHP_MINIT(ldap),
42154258
PHP_MSHUTDOWN(ldap),
4216-
NULL,
4259+
PHP_RINIT(ldap),
42174260
NULL,
42184261
PHP_MINFO(ldap),
42194262
PHP_LDAP_VERSION,

ext/ldap/php_ldap.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,7 @@ PHP_MINFO_FUNCTION(ldap);
3939
ZEND_BEGIN_MODULE_GLOBALS(ldap)
4040
zend_long num_links;
4141
zend_long max_links;
42+
bool tls_newctx; /* create new TLS context before connect */
4243
ZEND_END_MODULE_GLOBALS(ldap)
4344

4445
#if defined(ZTS) && defined(COMPILE_DL_LDAP)

ext/ldap/tests/ldap_start_tls_basic.phpt

Lines changed: 19 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,11 +9,28 @@ ldap
99
<?php require_once __DIR__ .'/skipifbindfailure.inc'; ?>
1010
--FILE--
1111
<?php
12-
require "connect.inc";
12+
require_once "connect.inc";
1313

14+
// CI uses self signed certificate
15+
16+
// No cert option - fails
17+
$link = ldap_connect($uri);
18+
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
19+
var_dump(@ldap_start_tls($link));
20+
21+
// No cert check - passes
22+
$link = ldap_connect($uri);
23+
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
24+
ldap_set_option($link, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_NEVER);
25+
var_dump(@ldap_start_tls($link));
26+
27+
// With cert check - fails
1428
$link = ldap_connect($uri);
1529
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
16-
var_dump(ldap_start_tls($link));
30+
ldap_set_option($link, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_DEMAND);
31+
var_dump(@ldap_start_tls($link));
1732
?>
1833
--EXPECT--
34+
bool(false)
1935
bool(true)
36+
bool(false)

ext/ldap/tests/ldaps_basic.phpt

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
--TEST--
2+
ldap_connect() - Basic ldaps test
3+
--EXTENSIONS--
4+
ldap
5+
--XFAIL--
6+
Passes locally but fails on CI - need investigation (configuration ?)
7+
--SKIPIF--
8+
<?php require_once __DIR__ .'/skipifbindfailure.inc'; ?>
9+
--FILE--
10+
<?php
11+
require_once "connect.inc";
12+
13+
$uri = "ldaps://$host:636";
14+
15+
// CI uses self signed certificate
16+
17+
// No cert option - fails
18+
$link = ldap_connect($uri);
19+
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
20+
var_dump(@ldap_bind($link, $user, $passwd));
21+
ldap_unbind($link);
22+
23+
// No cert check - passes
24+
ldap_set_option(null, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_ALLOW);
25+
$link = ldap_connect($uri);
26+
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
27+
var_dump(@ldap_bind($link, $user, $passwd));
28+
ldap_unbind($link);
29+
30+
// No change to TLS options
31+
$link = ldap_connect($uri);
32+
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
33+
var_dump(@ldap_bind($link, $user, $passwd));
34+
ldap_unbind($link);
35+
36+
// With cert check - fails
37+
ldap_set_option(null, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_DEMAND);
38+
$link = ldap_connect($uri);
39+
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
40+
var_dump(@ldap_bind($link, $user, $passwd));
41+
ldap_unbind($link);
42+
43+
// No change to TLS options
44+
$link = ldap_connect($uri);
45+
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
46+
var_dump(@ldap_bind($link, $user, $passwd));
47+
ldap_unbind($link);
48+
49+
?>
50+
--EXPECT--
51+
bool(false)
52+
bool(true)
53+
bool(true)
54+
bool(false)
55+
bool(false)

0 commit comments

Comments
 (0)