Added the possibility to configure all Ldap options for connection
This commit is contained in:
parent
cab3f45a77
commit
a8bae3175f
@ -24,22 +24,40 @@ abstract class AbstractConnection implements ConnectionInterface
|
|||||||
public function __construct(array $config = array())
|
public function __construct(array $config = array())
|
||||||
{
|
{
|
||||||
$resolver = new OptionsResolver();
|
$resolver = new OptionsResolver();
|
||||||
$resolver->setDefaults(array(
|
|
||||||
'host' => null,
|
|
||||||
'port' => 389,
|
|
||||||
'version' => 3,
|
|
||||||
'useSsl' => false,
|
|
||||||
'useStartTls' => false,
|
|
||||||
'optReferrals' => false,
|
|
||||||
));
|
|
||||||
$resolver->setNormalizer('host', function (Options $options, $value) {
|
|
||||||
if ($value && $options['useSsl']) {
|
|
||||||
return 'ldaps://'.$value;
|
|
||||||
}
|
|
||||||
|
|
||||||
return $value;
|
$this->configureOptions($resolver);
|
||||||
});
|
|
||||||
|
|
||||||
$this->config = $resolver->resolve($config);
|
$this->config = $resolver->resolve($config);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Configures the adapter's options.
|
||||||
|
*
|
||||||
|
* @param OptionsResolver $resolver An OptionsResolver instance
|
||||||
|
*/
|
||||||
|
protected function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
$resolver->setDefaults(array(
|
||||||
|
'host' => 'localhost',
|
||||||
|
'version' => 3,
|
||||||
|
'connection_string' => null,
|
||||||
|
'encryption' => 'none',
|
||||||
|
'options' => array(),
|
||||||
|
));
|
||||||
|
|
||||||
|
$resolver->setDefault('port', function (Options $options) {
|
||||||
|
return 'ssl' === $options['encryption'] ? 636 : 389;
|
||||||
|
});
|
||||||
|
|
||||||
|
$resolver->setDefault('connection_string', function (Options $options) {
|
||||||
|
return sprintf('ldap%s://%s:%s', 'ssl' === $options['encryption'] ? 's' : '', $options['host'], $options['port']);
|
||||||
|
});
|
||||||
|
|
||||||
|
$resolver->setAllowedTypes('host', 'string');
|
||||||
|
$resolver->setAllowedTypes('port', 'numeric');
|
||||||
|
$resolver->setAllowedTypes('connection_string', 'string');
|
||||||
|
$resolver->setAllowedTypes('version', 'numeric');
|
||||||
|
$resolver->setAllowedValues('encryption', array('none', 'ssl', 'tls'));
|
||||||
|
$resolver->setAllowedTypes('options', 'array');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,6 +14,8 @@ namespace Symfony\Component\Ldap\Adapter\ExtLdap;
|
|||||||
use Symfony\Component\Ldap\Adapter\AbstractConnection;
|
use Symfony\Component\Ldap\Adapter\AbstractConnection;
|
||||||
use Symfony\Component\Ldap\Exception\ConnectionException;
|
use Symfony\Component\Ldap\Exception\ConnectionException;
|
||||||
use Symfony\Component\Ldap\Exception\LdapException;
|
use Symfony\Component\Ldap\Exception\LdapException;
|
||||||
|
use Symfony\Component\OptionsResolver\Options;
|
||||||
|
use Symfony\Component\OptionsResolver\OptionsResolver;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @author Charles Sarrazin <charles@sarraz.in>
|
* @author Charles Sarrazin <charles@sarraz.in>
|
||||||
@ -67,24 +69,75 @@ class Connection extends AbstractConnection
|
|||||||
return $this->connection;
|
return $this->connection;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public function setOption($name, $value)
|
||||||
|
{
|
||||||
|
if (!@ldap_set_option($this->connection, ConnectionOptions::getOption($name), $value)) {
|
||||||
|
throw new LdapException(sprintf('Could not set value "%s" for option "%s".', $value, $name));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getOption($name)
|
||||||
|
{
|
||||||
|
if (!@ldap_get_option($this->connection, ConnectionOptions::getOption($name), $ret)) {
|
||||||
|
throw new LdapException(sprintf('Could not retrieve value for option "%s".', $name));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected function configureOptions(OptionsResolver $resolver)
|
||||||
|
{
|
||||||
|
parent::configureOptions($resolver);
|
||||||
|
|
||||||
|
$resolver->setDefault('debug', false);
|
||||||
|
$resolver->setAllowedTypes('debug', 'bool');
|
||||||
|
$resolver->setDefault('referrals', false);
|
||||||
|
$resolver->setAllowedTypes('referrals', 'bool');
|
||||||
|
|
||||||
|
$resolver->setNormalizer('options', function (Options $options, $value) {
|
||||||
|
if (true === $options['debug']) {
|
||||||
|
$value['debug_level'] = 7;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($value['protocol_version'])) {
|
||||||
|
$value['protocol_version'] = $options['version'];
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!isset($value['referrals'])) {
|
||||||
|
$value['referrals'] = $options['referrals'];
|
||||||
|
}
|
||||||
|
|
||||||
|
return $value;
|
||||||
|
});
|
||||||
|
|
||||||
|
$resolver->setAllowedValues('options', function (array $values) {
|
||||||
|
foreach ($values as $name => $value) {
|
||||||
|
if (!ConnectionOptions::isOption($name)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private function connect()
|
private function connect()
|
||||||
{
|
{
|
||||||
if ($this->connection) {
|
if ($this->connection) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
$host = $this->config['host'];
|
$this->connection = ldap_connect($this->config['connection_string']);
|
||||||
|
|
||||||
ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, $this->config['version']);
|
foreach ($this->config['options'] as $name => $value) {
|
||||||
ldap_set_option($this->connection, LDAP_OPT_REFERRALS, $this->config['optReferrals']);
|
$this->setOption($name, $value);
|
||||||
|
}
|
||||||
$this->connection = ldap_connect($host, $this->config['port']);
|
|
||||||
|
|
||||||
if (false === $this->connection) {
|
if (false === $this->connection) {
|
||||||
throw new LdapException(sprintf('Could not connect to Ldap server: %s', ldap_error($this->connection)));
|
throw new LdapException(sprintf('Could not connect to Ldap server: %s', ldap_error($this->connection)));
|
||||||
}
|
}
|
||||||
|
|
||||||
if ($this->config['useStartTls'] && false === ldap_start_tls($this->connection)) {
|
if ('tls' === $this->config['encryption'] && false === ldap_start_tls($this->connection)) {
|
||||||
throw new LdapException(sprintf('Could not initiate TLS connection: %s', ldap_error($this->connection)));
|
throw new LdapException(sprintf('Could not initiate TLS connection: %s', ldap_error($this->connection)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,78 @@
|
|||||||
|
<?php
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This file is part of the Symfony package.
|
||||||
|
*
|
||||||
|
* (c) Fabien Potencier <fabien@symfony.com>
|
||||||
|
*
|
||||||
|
* For the full copyright and license information, please view the LICENSE
|
||||||
|
* file that was distributed with this source code.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Symfony\Component\Ldap\Adapter\ExtLdap;
|
||||||
|
|
||||||
|
use Symfony\Component\Ldap\Exception\LdapException;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class representing the Ldap extension's options, which can be used with
|
||||||
|
* ldap_set_option or ldap_get_option.
|
||||||
|
*
|
||||||
|
* @author Charles Sarrazin <charles@sarraz.in>
|
||||||
|
*
|
||||||
|
* @internal
|
||||||
|
*/
|
||||||
|
final class ConnectionOptions
|
||||||
|
{
|
||||||
|
const API_INFO = 0x00;
|
||||||
|
const DEREF = 0x02;
|
||||||
|
const SIZELIMIT = 0x03;
|
||||||
|
const TIMELIMIT = 0x04;
|
||||||
|
const REFERRALS = 0x08;
|
||||||
|
const RESTART = 0x09;
|
||||||
|
const PROTOCOL_VERSION = 0x11;
|
||||||
|
const SERVER_CONTROLS = 0x12;
|
||||||
|
const CLIENT_CONTROLS = 0x13;
|
||||||
|
const API_FEATURE_INFO = 0x15;
|
||||||
|
const HOST_NAME = 0x30;
|
||||||
|
const ERROR_NUMBER = 0x31;
|
||||||
|
const ERROR_STRING = 0x32;
|
||||||
|
const MATCHED_DN = 0x33;
|
||||||
|
const DEBUG_LEVEL = 0x5001;
|
||||||
|
const NETWORK_TIMEOUT = 0x5005;
|
||||||
|
const X_SASL_MECH = 0x6100;
|
||||||
|
const X_SASL_REALM = 0x6101;
|
||||||
|
const X_SASL_AUTHCID = 0x6102;
|
||||||
|
const X_SASL_AUTHZID = 0x6103;
|
||||||
|
|
||||||
|
public static function getOptionName($name)
|
||||||
|
{
|
||||||
|
return sprintf('%s::%s', self::class, strtoupper($name));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Fetches an option's corresponding constant value from an option name.
|
||||||
|
* The option name can either be in snake or camel case.
|
||||||
|
*
|
||||||
|
* @param string $name
|
||||||
|
*
|
||||||
|
* @return int
|
||||||
|
*
|
||||||
|
* @throws LdapException
|
||||||
|
*/
|
||||||
|
public static function getOption($name)
|
||||||
|
{
|
||||||
|
// Convert
|
||||||
|
$constantName = self::getOptionName($name);
|
||||||
|
|
||||||
|
if (!defined($constantName)) {
|
||||||
|
throw new LdapException(sprintf('Unknown option "%s"', $name));
|
||||||
|
}
|
||||||
|
|
||||||
|
return constant($constantName);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static function isOption($name)
|
||||||
|
{
|
||||||
|
return defined(self::getOptionName($name));
|
||||||
|
}
|
||||||
|
}
|
@ -35,7 +35,7 @@ class Query extends AbstractQuery
|
|||||||
$con = $this->connection->getResource();
|
$con = $this->connection->getResource();
|
||||||
$this->connection = null;
|
$this->connection = null;
|
||||||
|
|
||||||
if (null === $this->search) {
|
if (null === $this->search || false === $this->search) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -60,7 +60,7 @@ class Query extends AbstractQuery
|
|||||||
|
|
||||||
$con = $this->connection->getResource();
|
$con = $this->connection->getResource();
|
||||||
|
|
||||||
$this->search = ldap_search(
|
$this->search = @ldap_search(
|
||||||
$con,
|
$con,
|
||||||
$this->dn,
|
$this->dn,
|
||||||
$this->query,
|
$this->query,
|
||||||
|
@ -9,9 +9,6 @@
|
|||||||
* file that was distributed with this source code.
|
* file that was distributed with this source code.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
|
||||||
* @author Charles Sarrazin <charles@sarraz.in>
|
|
||||||
*/
|
|
||||||
namespace Symfony\Component\Ldap\Adapter;
|
namespace Symfony\Component\Ldap\Adapter;
|
||||||
|
|
||||||
use Symfony\Component\Ldap\Entry;
|
use Symfony\Component\Ldap\Entry;
|
||||||
@ -21,10 +18,10 @@ use Symfony\Component\Ldap\Entry;
|
|||||||
*/
|
*/
|
||||||
interface QueryInterface
|
interface QueryInterface
|
||||||
{
|
{
|
||||||
const DEREF_NEVER = 0;
|
const DEREF_NEVER = 0x00;
|
||||||
const DEREF_SEARCHING = 1;
|
const DEREF_SEARCHING = 0x01;
|
||||||
const DEREF_FINDING = 2;
|
const DEREF_FINDING = 0x02;
|
||||||
const DEREF_ALWAYS = 3;
|
const DEREF_ALWAYS = 0x03;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Executes a query and returns the list of Ldap entries.
|
* Executes a query and returns the list of Ldap entries.
|
||||||
|
Reference in New Issue
Block a user