mirror of
https://github.com/Icinga/icingaweb2.git
synced 2025-07-28 16:24:04 +02:00
commit
4a5e6bfc7c
@ -55,7 +55,7 @@ class LdapBackendForm extends Form
|
|||||||
'required' => true,
|
'required' => true,
|
||||||
'label' => $this->translate('Backend Name'),
|
'label' => $this->translate('Backend Name'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The name of this authentication provider that is used to differentiate it from others'
|
'The name of this authentication provider that is used to differentiate it from others.'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -64,8 +64,10 @@ class LdapBackendForm extends Form
|
|||||||
'resource',
|
'resource',
|
||||||
array(
|
array(
|
||||||
'required' => true,
|
'required' => true,
|
||||||
'label' => $this->translate('LDAP Resource'),
|
'label' => $this->translate('LDAP Connection'),
|
||||||
'description' => $this->translate('The resource to use for authenticating with this provider'),
|
'description' => $this->translate(
|
||||||
|
'The LDAP connection to use for authenticating with this provider.'
|
||||||
|
),
|
||||||
'multiOptions' => false === empty($this->resources)
|
'multiOptions' => false === empty($this->resources)
|
||||||
? array_combine($this->resources, $this->resources)
|
? array_combine($this->resources, $this->resources)
|
||||||
: array()
|
: array()
|
||||||
@ -77,10 +79,40 @@ class LdapBackendForm extends Form
|
|||||||
array(
|
array(
|
||||||
'required' => true,
|
'required' => true,
|
||||||
'label' => $this->translate('LDAP User Object Class'),
|
'label' => $this->translate('LDAP User Object Class'),
|
||||||
'description' => $this->translate('The object class used for storing users on the ldap server'),
|
'description' => $this->translate('The object class used for storing users on the LDAP server.'),
|
||||||
'value' => 'inetOrgPerson'
|
'value' => 'inetOrgPerson'
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
$this->addElement(
|
||||||
|
'text',
|
||||||
|
'filter',
|
||||||
|
array(
|
||||||
|
'allowEmpty' => true,
|
||||||
|
'label' => $this->translate('LDAP Filter'),
|
||||||
|
'description' => $this->translate(
|
||||||
|
'An additional filter to use when looking up users using the specified connection. '
|
||||||
|
. 'Leave empty to not to use any additional filter rules.'
|
||||||
|
),
|
||||||
|
'requirement' => $this->translate(
|
||||||
|
'The filter needs to be expressed as standard LDAP expression, without'
|
||||||
|
. ' outer parentheses. (e.g. &(foo=bar)(bar=foo) or foo=bar)'
|
||||||
|
),
|
||||||
|
'validators' => array(
|
||||||
|
array(
|
||||||
|
'Callback',
|
||||||
|
false,
|
||||||
|
array(
|
||||||
|
'callback' => function ($v) {
|
||||||
|
return strpos($v, '(') !== 0;
|
||||||
|
},
|
||||||
|
'messages' => array(
|
||||||
|
'callbackValue' => $this->translate('The filter must not be wrapped in parantheses.')
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
);
|
||||||
$this->addElement(
|
$this->addElement(
|
||||||
'text',
|
'text',
|
||||||
'user_name_attribute',
|
'user_name_attribute',
|
||||||
@ -88,7 +120,7 @@ class LdapBackendForm extends Form
|
|||||||
'required' => true,
|
'required' => true,
|
||||||
'label' => $this->translate('LDAP User Name Attribute'),
|
'label' => $this->translate('LDAP User Name Attribute'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The attribute name used for storing the user name on the ldap server'
|
'The attribute name used for storing the user name on the LDAP server.'
|
||||||
),
|
),
|
||||||
'value' => 'uid'
|
'value' => 'uid'
|
||||||
)
|
)
|
||||||
@ -106,10 +138,10 @@ class LdapBackendForm extends Form
|
|||||||
'base_dn',
|
'base_dn',
|
||||||
array(
|
array(
|
||||||
'required' => false,
|
'required' => false,
|
||||||
'label' => $this->translate('Base DN'),
|
'label' => $this->translate('LDAP Base DN'),
|
||||||
'description' => $this->translate(
|
'description' => $this->translate(
|
||||||
'The path where users can be found on the ldap server. Leave ' .
|
'The path where users can be found on the LDAP server. Leave ' .
|
||||||
'empty to select all users available on the specified resource.'
|
'empty to select all users available using the specified connection.'
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
@ -142,11 +174,17 @@ class LdapBackendForm extends Form
|
|||||||
ResourceFactory::createResource($form->getResourceConfig()),
|
ResourceFactory::createResource($form->getResourceConfig()),
|
||||||
$form->getElement('user_class')->getValue(),
|
$form->getElement('user_class')->getValue(),
|
||||||
$form->getElement('user_name_attribute')->getValue(),
|
$form->getElement('user_name_attribute')->getValue(),
|
||||||
$form->getElement('base_dn')->getValue()
|
$form->getElement('base_dn')->getValue(),
|
||||||
|
$form->getElement('filter')->getValue()
|
||||||
);
|
);
|
||||||
$ldapUserBackend->assertAuthenticationPossible();
|
$ldapUserBackend->assertAuthenticationPossible();
|
||||||
} catch (AuthenticationException $e) {
|
} catch (AuthenticationException $e) {
|
||||||
$form->addError($e->getMessage());
|
if (($previous = $e->getPrevious()) !== null) {
|
||||||
|
$form->addError($previous->getMessage());
|
||||||
|
} else {
|
||||||
|
$form->addError($e->getMessage());
|
||||||
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
} catch (Exception $e) {
|
} catch (Exception $e) {
|
||||||
$form->addError(sprintf($form->translate('Unable to validate authentication: %s'), $e->getMessage()));
|
$form->addError(sprintf($form->translate('Unable to validate authentication: %s'), $e->getMessage()));
|
||||||
|
@ -9,6 +9,7 @@ use Icinga\Protocol\Ldap\Query;
|
|||||||
use Icinga\Protocol\Ldap\Connection;
|
use Icinga\Protocol\Ldap\Connection;
|
||||||
use Icinga\Exception\AuthenticationException;
|
use Icinga\Exception\AuthenticationException;
|
||||||
use Icinga\Protocol\Ldap\Exception as LdapException;
|
use Icinga\Protocol\Ldap\Exception as LdapException;
|
||||||
|
use Icinga\Protocol\Ldap\Expression;
|
||||||
|
|
||||||
class LdapUserBackend extends UserBackend
|
class LdapUserBackend extends UserBackend
|
||||||
{
|
{
|
||||||
@ -25,14 +26,23 @@ class LdapUserBackend extends UserBackend
|
|||||||
|
|
||||||
protected $userNameAttribute;
|
protected $userNameAttribute;
|
||||||
|
|
||||||
|
protected $customFilter;
|
||||||
|
|
||||||
protected $groupOptions;
|
protected $groupOptions;
|
||||||
|
|
||||||
public function __construct(Connection $conn, $userClass, $userNameAttribute, $baseDn, $groupOptions = null)
|
public function __construct(
|
||||||
{
|
Connection $conn,
|
||||||
|
$userClass,
|
||||||
|
$userNameAttribute,
|
||||||
|
$baseDn,
|
||||||
|
$cutomFilter,
|
||||||
|
$groupOptions = null
|
||||||
|
) {
|
||||||
$this->conn = $conn;
|
$this->conn = $conn;
|
||||||
$this->baseDn = trim($baseDn) !== '' ? $baseDn : $conn->getDN();
|
$this->baseDn = trim($baseDn) ?: $conn->getDN();
|
||||||
$this->userClass = $userClass;
|
$this->userClass = $userClass;
|
||||||
$this->userNameAttribute = $userNameAttribute;
|
$this->userNameAttribute = $userNameAttribute;
|
||||||
|
$this->customFilter = trim($cutomFilter);
|
||||||
$this->groupOptions = $groupOptions;
|
$this->groupOptions = $groupOptions;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -43,12 +53,18 @@ class LdapUserBackend extends UserBackend
|
|||||||
*/
|
*/
|
||||||
protected function selectUsers()
|
protected function selectUsers()
|
||||||
{
|
{
|
||||||
return $this->conn->select()->setBase($this->baseDn)->from(
|
$query = $this->conn->select()->setBase($this->baseDn)->from(
|
||||||
$this->userClass,
|
$this->userClass,
|
||||||
array(
|
array(
|
||||||
$this->userNameAttribute
|
$this->userNameAttribute
|
||||||
)
|
)
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ($this->customFilter) {
|
||||||
|
$query->addFilter(new Expression($this->customFilter));
|
||||||
|
}
|
||||||
|
|
||||||
|
return $query;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -88,9 +104,10 @@ class LdapUserBackend extends UserBackend
|
|||||||
|
|
||||||
if ($result === null) {
|
if ($result === null) {
|
||||||
throw new AuthenticationException(
|
throw new AuthenticationException(
|
||||||
'No objects with objectClass="%s" in DN="%s" found.',
|
'No objects with objectClass="%s" in DN="%s" found. (Filter: %s)',
|
||||||
$this->userClass,
|
$this->userClass,
|
||||||
$this->baseDn
|
$this->baseDn,
|
||||||
|
$this->customFilter ?: 'None'
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -103,6 +103,7 @@ abstract class UserBackend implements Countable
|
|||||||
$backendConfig->get('user_class', 'user'),
|
$backendConfig->get('user_class', 'user'),
|
||||||
$backendConfig->get('user_name_attribute', 'sAMAccountName'),
|
$backendConfig->get('user_name_attribute', 'sAMAccountName'),
|
||||||
$backendConfig->get('base_dn', $resource->getDN()),
|
$backendConfig->get('base_dn', $resource->getDN()),
|
||||||
|
$backendConfig->get('filter'),
|
||||||
$groupOptions
|
$groupOptions
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
@ -130,6 +131,7 @@ abstract class UserBackend implements Countable
|
|||||||
$backendConfig->user_class,
|
$backendConfig->user_class,
|
||||||
$backendConfig->user_name_attribute,
|
$backendConfig->user_name_attribute,
|
||||||
$backendConfig->get('base_dn', $resource->getDN()),
|
$backendConfig->get('base_dn', $resource->getDN()),
|
||||||
|
$backendConfig->get('filter'),
|
||||||
$groupOptions
|
$groupOptions
|
||||||
);
|
);
|
||||||
break;
|
break;
|
||||||
|
30
library/Icinga/Protocol/Ldap/Expression.php
Normal file
30
library/Icinga/Protocol/Ldap/Expression.php
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
<?php
|
||||||
|
/* Icinga Web 2 | (c) 2013-2015 Icinga Development Team | GPLv2+ */
|
||||||
|
|
||||||
|
namespace Icinga\Protocol\Ldap;
|
||||||
|
|
||||||
|
class Expression
|
||||||
|
{
|
||||||
|
protected $value;
|
||||||
|
|
||||||
|
public function __construct($value)
|
||||||
|
{
|
||||||
|
$this->value = $value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function setValue($value)
|
||||||
|
{
|
||||||
|
$this->value = $value;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function getValue()
|
||||||
|
{
|
||||||
|
return $this->value;
|
||||||
|
}
|
||||||
|
|
||||||
|
public function __toString()
|
||||||
|
{
|
||||||
|
return (string) $this->getValue();
|
||||||
|
}
|
||||||
|
}
|
@ -306,6 +306,19 @@ class Query
|
|||||||
return $paginator;
|
return $paginator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add a filter expression to this query
|
||||||
|
*
|
||||||
|
* @param Expression $expression
|
||||||
|
*
|
||||||
|
* @return Query
|
||||||
|
*/
|
||||||
|
public function addFilter(Expression $expression)
|
||||||
|
{
|
||||||
|
$this->filters[] = $expression;
|
||||||
|
return $this;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns the LDAP filter that will be applied
|
* Returns the LDAP filter that will be applied
|
||||||
*
|
*
|
||||||
@ -318,11 +331,15 @@ class Query
|
|||||||
throw new Exception('Object class is mandatory');
|
throw new Exception('Object class is mandatory');
|
||||||
}
|
}
|
||||||
foreach ($this->filters as $key => $value) {
|
foreach ($this->filters as $key => $value) {
|
||||||
$parts[] = sprintf(
|
if ($value instanceof Expression) {
|
||||||
'%s=%s',
|
$parts[] = (string) $value;
|
||||||
LdapUtils::quoteForSearch($key),
|
} else {
|
||||||
LdapUtils::quoteForSearch($value, true)
|
$parts[] = sprintf(
|
||||||
);
|
'%s=%s',
|
||||||
|
LdapUtils::quoteForSearch($key),
|
||||||
|
LdapUtils::quoteForSearch($value, true)
|
||||||
|
);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (count($parts) > 1) {
|
if (count($parts) > 1) {
|
||||||
return '(&(' . implode(')(', $parts) . '))';
|
return '(&(' . implode(')(', $parts) . '))';
|
||||||
|
@ -272,7 +272,8 @@ class AdminAccountPage extends Form
|
|||||||
ResourceFactory::createResource(new ConfigObject($this->resourceConfig)),
|
ResourceFactory::createResource(new ConfigObject($this->resourceConfig)),
|
||||||
$this->backendConfig['user_class'],
|
$this->backendConfig['user_class'],
|
||||||
$this->backendConfig['user_name_attribute'],
|
$this->backendConfig['user_name_attribute'],
|
||||||
$this->backendConfig['base_dn']
|
$this->backendConfig['base_dn'],
|
||||||
|
$this->backendConfig['filter']
|
||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
throw new LogicException(
|
throw new LogicException(
|
||||||
|
@ -126,11 +126,15 @@ class AuthenticationStep extends Step
|
|||||||
. '</tr>'
|
. '</tr>'
|
||||||
. ($authType === 'ldap' ? (
|
. ($authType === 'ldap' ? (
|
||||||
'<tr>'
|
'<tr>'
|
||||||
. '<td><strong>' . t('User Object Class') . '</strong></td>'
|
. '<td><strong>' . mt('setup', 'User Object Class') . '</strong></td>'
|
||||||
. '<td>' . $this->data['backendConfig']['user_class'] . '</td>'
|
. '<td>' . $this->data['backendConfig']['user_class'] . '</td>'
|
||||||
. '</tr>'
|
. '</tr>'
|
||||||
. '<tr>'
|
. '<tr>'
|
||||||
. '<td><strong>' . t('User Name Attribute') . '</strong></td>'
|
. '<td><strong>' . mt('setup', 'Custom Filter') . '</strong></td>'
|
||||||
|
. '<td>' . trim($this->data['backendConfig']['filter']) ?: t('None', 'auth.ldap.filter') . '</td>'
|
||||||
|
. '</tr>'
|
||||||
|
. '<tr>'
|
||||||
|
. '<td><strong>' . mt('setup', 'User Name Attribute') . '</strong></td>'
|
||||||
. '<td>' . $this->data['backendConfig']['user_name_attribute'] . '</td>'
|
. '<td>' . $this->data['backendConfig']['user_name_attribute'] . '</td>'
|
||||||
. '</tr>'
|
. '</tr>'
|
||||||
) : ($authType === 'external' ? (
|
) : ($authType === 'external' ? (
|
||||||
|
Loading…
x
Reference in New Issue
Block a user