8000 feature #18725 [Ldap] Added the possibility to configure all availabl… · symfony/symfony@918eb27 · GitHub
[go: up one dir, main page]

Skip to content

Commit 918eb27

Browse files
committed
feature #18725 [Ldap] Added the possibility to configure all available Ldap options for connection (csarrazi)
This PR was merged into the 3.1-dev branch. Discussion ---------- [Ldap] Added the possibility to configure all available Ldap options for connection | Q | A | ------------- | --- | Branch? | master | Bug fix? | no | New feature? | yes | BC breaks? | no | Deprecations? | no | Tests pass? | yes | Fixed tickets | #18448 | License | MIT | Doc PR | This PR lets a user configure [all documented Ldap options](http://php.net/manual/fr/function.ldap-get-option.php), as well as a few undocumented ones (back-ported from the [OpenLdap C library](http://linux.die.net/man/3/ldap_set_option), as well as the [Ldap client specification](https://www.ietf.org/proceedings/50/I-D/ldapext-ldap-c-api-05.txt)). Commits ------- a8bae31 Added the possibility to configure all Ldap options for connection
2 parents a1b2d8c + a8bae31 commit 918eb27

File tree

5 files changed

+172
-26
lines changed

5 files changed

+172
-26
lines changed

src/Symfony/Component/Ldap/Adapter/AbstractConnection.php

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -24,22 +24,40 @@ abstract class AbstractConnection implements ConnectionInterface
2424
public function __construct(array $config = array())
2525
{
2626
$resolver = new OptionsResolver();
27+
28+
$this->configureOptions($resolver);
29+
30+
$this->config = $resolver->resolve($config);
31+
}
32+
33+
/**
34+
* Configures the adapter's options.
35+
*
36+
* @param OptionsResolver $resolver An OptionsResolver instance
37+
*/
38+
protected function configureOptions(OptionsResolver $resolver)
39+
{
2740
$resolver->setDefaults(array(
28-
'host' => null,
29-
'port' => 389,
41+
'host' => 'localhost',
3042
'version' => 3,
31-
'useSsl' => false,
32-
'useStartTls' => false,
33-
'optReferrals' => false,
43+
'connection_string' => null,
44+
'encryption' => 'none',
45+
'options' => array(),
3446
));
35-
$resolver->setNormalizer('host', function (Options $options, $value) {
36-
if ($value && $options[ 8000 9;useSsl']) {
37-
return 'ldaps://'.$value;
38-
}
3947

40-
return $value;
48+
$resolver->setDefault('port', function (Options $options) {
49+
return 'ssl' === $options['encryption'] ? 636 : 389;
4150
});
4251

43-
$this->config = $resolver->resolve($config);
52+
$resolver->setDefault('connection_string', function (Options $options) {
53+
return sprintf('ldap%s://%s:%s', 'ssl' === $options['encryption'] ? 's' : '', $options['host'], $options['port']);
54+
});
55+
56+
$resolver->setAllowedTypes('host', 'string');
57+
$resolver->setAllowedTypes('port', 'numeric');
58+
$resolver->setAllowedTypes('connection_string', 'string');
59+
$resolver->setAllowedTypes('version', 'numeric');
60+
$resolver->setAllowedValues('encryption', array('none', 'ssl', 'tls'));
61+
$resolver->setAllowedTypes('options', 'array');
4462
}
4563
}

src/Symfony/Component/Ldap/Adapter/ExtLdap/Connection.php

Lines changed: 59 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,8 @@
1414
use Symfony\Component\Ldap\Adapter\AbstractConnection;
1515
use Symfony\Component\Ldap\Exception\ConnectionException;
1616
use Symfony\Component\Ldap\Exception\LdapException;
17+
use Symfony\Component\OptionsResolver\Options;
18+
use Symfony\Component\OptionsResolver\OptionsResolver;
1719

1820
/**
1921
* @author Charles Sarrazin <charles@sarraz.in>
@@ -67,24 +69,75 @@ public function getResource()
6769
return $this->connection;
6870
}
6971

72+
public function setOption($name, $value)
73+
{
74+
if (!@ldap_set_option($this->connection, ConnectionOptions::getOption($name), $value)) {
75+
throw new LdapException(sprintf('Could not set value "%s" for option "%s".', $value, $name));
76+
}
77+
}
78+
79+
public function getOption($name)
80+
{
81+
if (!@ldap_get_option($this->connection, ConnectionOptions::getOption($name), $ret)) {
82+
throw new LdapException(sprintf('Could not retrieve value for option "%s".', $name));
83+
}
84+
85+
return $ret;
86+
}
87+
88+
protected function configureOptions(OptionsResolver $resolver)
89+
{
90+
parent::configureOptions($resolver);
91+
92+
$resolver->setDefault('debug', false);
93+
$resolver->setAllowedTypes('debug', 'bool');
94+
$resolver->setDefault('referrals', false);
95+
$resolver->setAllowedTypes('referrals', 'bool');
96+
97+
$resolver->setNormalizer('options', function (Options $options, $value) {
98+
if (true === $options['debug']) {
99+
$value['debug_level'] = 7;
100+
}
101+
102+
if (!isset($value['protocol_version'])) {
103+
$value['protocol_version'] = $options['version'];
104+
}
105+
106+
if (!isset($value['referrals'])) {
107+
$value['referrals'] = $options['referrals'];
108+
}
109+
110+
return $value;
111+
});
112+
113+
$resolver->setAllowedValues('options', function (array $values) {
114+
foreach ($values as $name => $value) {
115+
if (!ConnectionOptions::isOption($name)) {
116+
return false;
117+
}
118+
}
119+
120+
return true;
121+
});
122+
}
123+
70124
private function connect()
71125
{
72126
if ($this->connection) {
73127
return;
74128
}
75129

76-
$host = $this->config['host'];
77-
78-
ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, $this->config['version']);
79-
ldap_set_option($this->connection, LDAP_OPT_REFERRALS, $this->config['optReferrals']);
130+
$this->connection = ldap_connect($this->config['connection_string']);
80131

81-
$this->connection = ldap_connect($host, $this->config['port']);
132+
foreach ($this->config['options'] as $name => $value) {
133+
$this->setOption($name, $value);
134+
}
82135

83136
if (false === $this->connection) {
84137
throw new LdapException(sprintf('Could not connect to Ldap server: %s', ldap_error($this->connection)));
85138
}
86139

87-
if ($this->config['useStartTls'] && false === ldap_start_tls($this->connection)) {
140+
if ('tls' === $this->config['encryption'] && false === ldap_start_tls($this->connection)) {
88141
throw new LdapException(sprintf('Could not initiate TLS connection: %s', ldap_error($this->connection)));
89142
}
90143
}
Lines changed: 78 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,78 @@
1+
<?php
2+
3+
/*
4+
* This file is part of the Symfony package.
5+
*
6+
* (c) Fabien Potencier <fabien@symfony.com>
7+
*
8+
* For the full copyright and license information, please view the LICENSE
9+
* file that was distributed with this source code.
10+
*/
11+
12+
namespace Symfony\Component\Ldap\Adapter\ExtLdap;
13+
14+
use Symfony\Component\Ldap\Exception\LdapException;
15+
16+
/**
17+
* A class representing the Ldap extension's options, which can be used with
18+
* ldap_set_option or ldap_get_option.
19+
*
20+
* @author Charles Sarrazin <charles@sarraz.in>
21+
*
22+
* @internal
23+
*/
24+
final class ConnectionOptions
25+
{
26+
const API_INFO = 0x00;
27+
const DEREF = 0x02;
28+
const SIZELIMIT = 0x03;
29+
const TIMELIMIT = 0x04;
30+
const REFERRALS = 0x08;
31+
const RESTART = 0x09;
32+
const PROTOCOL_VERSION = 0x11;
33+
const SERVER_CONTROLS = 0x12;
34+
const CLIENT_CONTROLS = 0x13;
35+
const API_FEATURE_INFO = 0x15;
36+
const HOST_NAME = 0x30;
37+
const ERROR_NUMBER = 0x31;
38+
const ERROR_STRING = 0x32;
39+
const MATCHED_DN = 0x33;
40+
const DEBUG_LEVEL = 0x5001;
41+
const NETWORK_TIMEOUT = 0x5005;
42+
c 1CF5 onst X_SASL_MECH = 0x6100;
43+
const X_SASL_REALM = 0x6101;
44+
const X_SASL_AUTHCID = 0x6102;
45+
const X_SASL_AUTHZID = 0x6103;
46+
47+
public static function getOptionName($name)
48+
{
49+
return sprintf('%s::%s', self::class, strtoupper($name));
50+
}
51+
52+
/**
53+
* Fetches an option's corresponding constant value from an option name.
54+
* The option name can either be in snake or camel case.
55+
*
56+
* @param string $name
57+
*
58+
* @return int
59+
*
60+
* @throws LdapException
61+
*/
62+
public static function getOption($name)
63+
{
64+
// Convert
65+
$constantName = self::getOptionName($name);
66+
67+
if (!defined($constantName)) {
68+
throw new LdapException(sprintf('Unknown option "%s"', $name));
69+
}
70+
71+
return constant($constantName);
72+
}
73+
74+
public static function isOption($name)
75+
{
76+
return defined(self::getOptionName($name));
77+
}
78+
}

src/Symfony/Component/Ldap/Adapter/ExtLdap/Query.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,7 @@ public function __destruct()
3535
$con = $this->connection->getResource();
3636
$this->connection = null;
3737

38-
if (null === $this->search) {
38+
if (null === $this->search || false === $this->search) {
3939
return;
4040
}
4141

@@ -60,7 +60,7 @@ public function execute()
6060

6161
$con = $this->connection->getResource();
6262

63-
$this->search = ldap_search(
63+
$this->search = @ldap_search(
6464
$con,
6565
$this->dn,
6666
$this->query,

src/Symfony/Component/Ldap/Adapter/QueryInterface.php

Lines changed: 4 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,6 @@
99
* file that was distributed with this source code.
1010
*/
1111

12-
/**
13-
* @author Charles Sarrazin <charles@sarraz.in>
14-
*/
1512
namespace Symfony\Component\Ldap\Adapter;
1613

1714
use Symfony\Component\Ldap\Entry;
@@ -21,10 +18,10 @@
2118
*/
2219
interface QueryInterface
2320
{
24-
const DEREF_NEVER = 0;
25-
const DEREF_SEARCHING = 1;
26-
const DEREF_FINDING = 2;
27-
const DEREF_ALWAYS = 3;
21+
const DEREF_NEVER = 0x00;
22+
const DEREF_SEARCHING = 0x01;
23+
const DEREF_FINDING = 0x02;
24+
const DEREF_ALWAYS = 0x03;
2825

2926
/**
3027
* Executes a query and returns the list of Ldap entries.

0 commit comments

Comments
 (0)
0