Skip to content

Commit bcee2af

Browse files
committed
Merge branch 'PHP-8.3' into PHP-8.4
* PHP-8.3: NEWS for GH-17940 Fix #17776 LDAP_OPT_X_TLS_REQUIRE_CERT can't be overridden
2 parents 6d458ca + 98fb27a commit bcee2af

File tree

4 files changed

+141
-25
lines changed

4 files changed

+141
-25
lines changed

ext/ldap/ldap.c

+66-23
Original file line numberDiff line numberDiff line change
@@ -834,6 +834,21 @@ static PHP_GINIT_FUNCTION(ldap)
834834
}
835835
/* }}} */
836836

837+
/* {{{ PHP_RINIT_FUNCTION */
838+
static PHP_RINIT_FUNCTION(ldap)
839+
{
840+
#if defined(COMPILE_DL_LDAP) && defined(ZTS)
841+
ZEND_TSRMLS_CACHE_UPDATE();
842+
#endif
843+
844+
/* needed before first connect and after TLS option changes */
845+
LDAPG(tls_newctx) = true;
846+
847+
return SUCCESS;
848+
}
849+
/* }}} */
850+
851+
837852
/* {{{ PHP_MINIT_FUNCTION */
838853
PHP_MINIT_FUNCTION(ldap)
839854
{
@@ -989,6 +1004,20 @@ PHP_FUNCTION(ldap_connect)
9891004
snprintf( url, urllen, "ldap://%s:" ZEND_LONG_FMT, host, port );
9901005
}
9911006

1007+
#ifdef LDAP_OPT_X_TLS_NEWCTX
1008+
if (LDAPG(tls_newctx) && url && !strncmp(url, "ldaps:", 6)) {
1009+
int val = 0;
1010+
1011+
/* ensure all pending TLS options are applied in a new context */
1012+
if (ldap_set_option(NULL, LDAP_OPT_X_TLS_NEWCTX, &val) != LDAP_OPT_SUCCESS) {
1013+
zval_ptr_dtor(return_value);
1014+
php_error_docref(NULL, E_WARNING, "Could not create new security context");
1015+
RETURN_FALSE;
1016+
}
1017+
LDAPG(tls_newctx) = false;
1018+
}
1019+
#endif
1020+
9921021
#ifdef LDAP_API_FEATURE_X_OPENLDAP
9931022
/* ldap_init() is deprecated, use ldap_initialize() instead.
9941023
*/
@@ -3177,15 +3206,7 @@ PHP_FUNCTION(ldap_set_option)
31773206
}
31783207

31793208
switch (option) {
3180-
/* options with int value */
3181-
case LDAP_OPT_DEREF:
3182-
case LDAP_OPT_SIZELIMIT:
3183-
case LDAP_OPT_TIMELIMIT:
3184-
case LDAP_OPT_PROTOCOL_VERSION:
3185-
case LDAP_OPT_ERROR_NUMBER:
3186-
#ifdef LDAP_OPT_DEBUG_LEVEL
3187-
case LDAP_OPT_DEBUG_LEVEL:
3188-
#endif
3209+
/* TLS options with int value */
31893210
#ifdef LDAP_OPT_X_TLS_REQUIRE_CERT
31903211
case LDAP_OPT_X_TLS_REQUIRE_CERT:
31913212
#endif
@@ -3197,6 +3218,18 @@ PHP_FUNCTION(ldap_set_option)
31973218
#endif
31983219
#ifdef LDAP_OPT_X_TLS_PROTOCOL_MAX
31993220
case LDAP_OPT_X_TLS_PROTOCOL_MAX:
3221+
#endif
3222+
/* TLS option change requires resetting TLS context */
3223+
LDAPG(tls_newctx) = true;
3224+
ZEND_FALLTHROUGH;
3225+
/* other options with int value */
3226+
case LDAP_OPT_DEREF:
3227+
case LDAP_OPT_SIZELIMIT:
3228+
case LDAP_OPT_TIMELIMIT:
3229+
case LDAP_OPT_PROTOCOL_VERSION:
3230+
case LDAP_OPT_ERROR_NUMBER:
3231+
#ifdef LDAP_OPT_DEBUG_LEVEL
3232+
case LDAP_OPT_DEBUG_LEVEL:
32003233
#endif
32013234
#ifdef LDAP_OPT_X_KEEPALIVE_IDLE
32023235
case LDAP_OPT_X_KEEPALIVE_IDLE:
@@ -3253,17 +3286,7 @@ PHP_FUNCTION(ldap_set_option)
32533286
}
32543287
} break;
32553288
#endif
3256-
/* options with string value */
3257-
case LDAP_OPT_ERROR_STRING:
3258-
#ifdef LDAP_OPT_HOST_NAME
3259-
case LDAP_OPT_HOST_NAME:
3260-
#endif
3261-
#ifdef HAVE_LDAP_SASL
3262-
case LDAP_OPT_X_SASL_MECH:
3263-
case LDAP_OPT_X_SASL_REALM:
3264-
case LDAP_OPT_X_SASL_AUTHCID:
3265-
case LDAP_OPT_X_SASL_AUTHZID:
3266-
#endif
3289+
/* TLS options with string value */
32673290
#if (LDAP_API_VERSION > 2000)
32683291
case LDAP_OPT_X_TLS_CACERTDIR:
32693292
case LDAP_OPT_X_TLS_CACERTFILE:
@@ -3277,6 +3300,20 @@ PHP_FUNCTION(ldap_set_option)
32773300
#endif
32783301
#ifdef LDAP_OPT_X_TLS_DHFILE
32793302
case LDAP_OPT_X_TLS_DHFILE:
3303+
#endif
3304+
/* TLS option change requires resetting TLS context */
3305+
LDAPG(tls_newctx) = true;
3306+
ZEND_FALLTHROUGH;
3307+
/* other options with string value */
3308+
case LDAP_OPT_ERROR_STRING:
3309+
#ifdef LDAP_OPT_HOST_NAME
3310+
case LDAP_OPT_HOST_NAME:
3311+
#endif
3312+
#ifdef HAVE_LDAP_SASL
3313+
case LDAP_OPT_X_SASL_MECH:
3314+
case LDAP_OPT_X_SASL_REALM:
3315+
case LDAP_OPT_X_SASL_AUTHCID:
3316+
case LDAP_OPT_X_SASL_AUTHZID:
32803317
#endif
32813318
#ifdef LDAP_OPT_MATCHED_DN
32823319
case LDAP_OPT_MATCHED_DN:
@@ -3696,6 +3733,9 @@ PHP_FUNCTION(ldap_start_tls)
36963733
zval *link;
36973734
ldap_linkdata *ld;
36983735
int rc, protocol = LDAP_VERSION3;
3736+
#ifdef LDAP_OPT_X_TLS_NEWCTX
3737+
int val = 0;
3738+
#endif
36993739

37003740
if (zend_parse_parameters(ZEND_NUM_ARGS(), "O", &link, ldap_link_ce) != SUCCESS) {
37013741
RETURN_THROWS();
@@ -3705,13 +3745,16 @@ PHP_FUNCTION(ldap_start_tls)
37053745
VERIFY_LDAP_LINK_CONNECTED(ld);
37063746

37073747
if (((rc = ldap_set_option(ld->link, LDAP_OPT_PROTOCOL_VERSION, &protocol)) != LDAP_SUCCESS) ||
3748+
#ifdef LDAP_OPT_X_TLS_NEWCTX
3749+
(LDAPG(tls_newctx) && (rc = ldap_set_option(ld->link, LDAP_OPT_X_TLS_NEWCTX, &val)) != LDAP_OPT_SUCCESS) ||
3750+
#endif
37083751
((rc = ldap_start_tls_s(ld->link, NULL, NULL)) != LDAP_SUCCESS)
37093752
) {
37103753
php_error_docref(NULL, E_WARNING,"Unable to start TLS: %s", ldap_err2string(rc));
37113754
RETURN_FALSE;
3712-
} else {
3713-
RETURN_TRUE;
37143755
}
3756+
LDAPG(tls_newctx) = false;
3757+
RETURN_TRUE;
37153758
}
37163759
/* }}} */
37173760
#endif
@@ -4233,7 +4276,7 @@ zend_module_entry ldap_module_entry = { /* {{{ */
42334276
ext_functions,
42344277
PHP_MINIT(ldap),
42354278
PHP_MSHUTDOWN(ldap),
4236-
NULL,
4279+
PHP_RINIT(ldap),
42374280
NULL,
42384281
PHP_MINFO(ldap),
42394282
PHP_LDAP_VERSION,

ext/ldap/php_ldap.h

+1
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

+19-2
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

+55
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)