Skip to content

Commit d34aece

Browse files
committed
Fix GH-18529: additional inheriting of TLS int options
This is for LDAP_OPT_X_TLS_PROTOCOL_MIN and LDAP_OPT_X_TLS_PROTOCOL_MAX It also adds a test that uses LDAPCONF with TLS max version lower than the minimum TLS server version so it should always fail. However it does not fial for the second case without this change which confirms that the change works as expected. Closes GH-18676
1 parent ae92b85 commit d34aece

File tree

5 files changed

+105
-5
lines changed

5 files changed

+105
-5
lines changed

.github/scripts/setup-slapd.sh

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,9 @@ olcTLSCertificateKeyFile: /etc/ldap/ssl/server.key
7272
add: olcTLSVerifyClient
7373
olcTLSVerifyClient: never
7474
-
75+
add: olcTLSProtocolMin
76+
olcTLSProtocolMin: 3.3
77+
-
7578
add: olcAuthzRegexp
7679
olcAuthzRegexp: uid=usera,cn=digest-md5,cn=auth cn=usera,dc=my-domain,dc=com
7780
-

ext/ldap/ldap.c

Lines changed: 27 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -3732,7 +3732,8 @@ PHP_FUNCTION(ldap_rename_ext)
37323732
*/
37333733
static int _php_ldap_tls_newctx(LDAP *ld)
37343734
{
3735-
int val = 0, i, opts[] = {
3735+
int val = 0, i;
3736+
int str_opts[] = {
37363737
#if (LDAP_API_VERSION > 2000)
37373738
LDAP_OPT_X_TLS_CACERTDIR,
37383739
LDAP_OPT_X_TLS_CACERTFILE,
@@ -3752,21 +3753,42 @@ static int _php_ldap_tls_newctx(LDAP *ld)
37523753
#endif
37533754
0};
37543755

3755-
for (i=0 ; opts[i] ; i++) {
3756+
for (i=0 ; str_opts[i] ; i++) {
37563757
char *path = NULL;
37573758

3758-
ldap_get_option(ld, opts[i], &path);
3759+
ldap_get_option(ld, str_opts[i], &path);
37593760
if (path) { /* already set locally */
37603761
ldap_memfree(path);
37613762
} else {
3762-
ldap_get_option(NULL, opts[i], &path);
3763+
ldap_get_option(NULL, str_opts[i], &path);
37633764
if (path) { /* set globally, inherit */
3764-
ldap_set_option(ld, opts[i], path);
3765+
ldap_set_option(ld, str_opts[i], path);
37653766
ldap_memfree(path);
37663767
}
37673768
}
37683769
}
37693770

3771+
#ifdef LDAP_OPT_X_TLS_PROTOCOL_MIN
3772+
int int_opts[] = {
3773+
LDAP_OPT_X_TLS_PROTOCOL_MIN,
3774+
#ifdef LDAP_OPT_X_TLS_PROTOCOL_MAX
3775+
LDAP_OPT_X_TLS_PROTOCOL_MAX,
3776+
#endif
3777+
0
3778+
};
3779+
for (i=0 ; int_opts[i] ; i++) {
3780+
int value = 0;
3781+
3782+
ldap_get_option(ld, int_opts[i], &value);
3783+
if (value <= 0) { /* if value is not set already */
3784+
ldap_get_option(NULL, int_opts[i], &value);
3785+
if (value > 0) { /* set globally, inherit */
3786+
ldap_set_option(ld, int_opts[i], &value);
3787+
}
3788+
}
3789+
}
3790+
#endif
3791+
37703792
return ldap_set_option(ld, LDAP_OPT_X_TLS_NEWCTX, &val);
37713793
}
37723794

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
TLS_PROTOCOL_MAX 3.2
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
--TEST--
2+
ldap_start_tls() - Basic ldap_start_tls test
3+
--EXTENSIONS--
4+
ldap
5+
--ENV--
6+
LDAPCONF={PWD}/ldap_start_tls_rc_max_version.conf
7+
--SKIPIF--
8+
<?php
9+
$require_vendor = [
10+
"name" => "OpenLDAP",
11+
"min_version" => 20500,
12+
];
13+
require_once __DIR__ .'/skipifbindfailure.inc';
14+
?>
15+
--FILE--
16+
<?php
17+
require_once "connect.inc";
18+
19+
// CI uses self signed certificate
20+
21+
// No cert option - fails
22+
$link = ldap_connect($uri);
23+
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
24+
var_dump(@ldap_start_tls($link));
25+
26+
// No cert check - should pass but due to ldaps check, it fails as well
27+
$link = ldap_connect($uri);
28+
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
29+
ldap_set_option($link, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_NEVER);
30+
var_dump(@ldap_start_tls($link));
31+
32+
// With cert check - fails
33+
$link = ldap_connect($uri);
34+
ldap_set_option($link, LDAP_OPT_PROTOCOL_VERSION, $protocol_version);
35+
ldap_set_option($link, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_DEMAND);
36+
var_dump(@ldap_start_tls($link));
37+
?>
38+
--EXPECT--
39+
bool(false)
40+
bool(false)
41+
bool(false)

ext/ldap/tests/skipifbindfailure.inc

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,4 +10,37 @@ if ($skip_on_bind_failure) {
1010

1111
ldap_unbind($link);
1212
}
13+
14+
if (isset($require_vendor)) {
15+
ob_start();
16+
phpinfo(INFO_MODULES);
17+
$phpinfo = ob_get_clean();
18+
19+
// Extract the LDAP section specifically
20+
if (preg_match('/^ldap\s*$(.*?)^[a-z_]+\s*$/ims', $phpinfo, $ldap_section_match)) {
21+
$ldap_section = $ldap_section_match[1];
22+
23+
// Extract vendor info from the LDAP section only
24+
if (preg_match('/Vendor Name\s*=>\s*(.+)/i', $ldap_section, $name_match) &&
25+
preg_match('/Vendor Version\s*=>\s*(\d+)/i', $ldap_section, $version_match)) {
26+
27+
$vendor_name = trim($name_match[1]);
28+
$vendor_version = (int)$version_match[1];
29+
30+
// Check vendor name if specified
31+
if (isset($require_vendor['name']) && $vendor_name !== $require_vendor['name']) {
32+
die("skip Requires {$require_vendor['name']} (detected: $vendor_name)");
33+
}
34+
35+
// Check minimum version if specified
36+
if (isset($require_vendor['min_version']) && $vendor_version < $require_vendor['min_version']) {
37+
die("skip Requires minimum version {$require_vendor['min_version']} (detected: $vendor_version)");
38+
}
39+
} else {
40+
die("skip Cannot determine LDAP vendor information");
41+
}
42+
} else {
43+
die("skip LDAP extension information not found");
44+
}
45+
}
1346
?>

0 commit comments

Comments
 (0)