parent
df69fd2264
commit
e29a568bff
|
@ -0,0 +1,214 @@
|
|||
<?php
|
||||
|
||||
namespace Icinga\Form;
|
||||
|
||||
use Icinga\Application\Config;
|
||||
use Icinga\Logger\Logger;
|
||||
use Icinga\Protocol\Ldap\Exception as LdapException;
|
||||
use Icinga\Protocol\Ldap\Connection;
|
||||
use Icinga\Web\Request;
|
||||
use Icinga\Protocol\Dns;
|
||||
use Icinga\Web\Form\Element\Note;
|
||||
use Icinga\Web\Form;
|
||||
|
||||
/**
|
||||
* Form class for application-wide and logging specific settings
|
||||
*/
|
||||
class LdapDiscoveryForm extends Form
|
||||
{
|
||||
/**
|
||||
* The discovered server settings
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $capabilities = null;
|
||||
|
||||
/**
|
||||
* The discovered root_dn
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
private $namingContext = null;
|
||||
|
||||
/**
|
||||
* The working domain name
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
private $domain = null;
|
||||
|
||||
/**
|
||||
* The working port name
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
private $port = 389;
|
||||
|
||||
/**
|
||||
* Initialize this page
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->setName('form_ldap_discovery');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
$this->addElement(
|
||||
'text',
|
||||
'domain',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Search Domain'),
|
||||
'description' => t('Search this domain for records of available servers.'),
|
||||
)
|
||||
);
|
||||
|
||||
if (false) {
|
||||
$this->addElement(
|
||||
new Note(
|
||||
'additional_description',
|
||||
array(
|
||||
'value' => t('No Ldap servers found on this domain.'
|
||||
. ' You can try to specify host and port and try again, or just skip this step and '
|
||||
. 'configure the server manually.'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
$this->addElement(
|
||||
'text',
|
||||
'hostname',
|
||||
array(
|
||||
'required' => false,
|
||||
'label' => t('Host'),
|
||||
'description' => t('IP or host name to search.'),
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'text',
|
||||
'port',
|
||||
array(
|
||||
'required' => false,
|
||||
'label' => t('Port'),
|
||||
'description' => t('Port', 389),
|
||||
)
|
||||
);
|
||||
}
|
||||
return $this;
|
||||
}
|
||||
|
||||
public function isValid($data)
|
||||
{
|
||||
if (false === parent::isValid($data)) {
|
||||
return false;
|
||||
}
|
||||
if ($this->discover($this->getValue('domain'))) {
|
||||
return true;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
private function discover($domain)
|
||||
{
|
||||
// Attempt 1: Connect to the domain directly
|
||||
if ($this->discoverCapabilities(array(
|
||||
'hostname' => $domain,
|
||||
'port' => 389)
|
||||
)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// Attempt 2: Discover all available ldap dns records and connect to the first one
|
||||
$cap = false;
|
||||
$records = array_merge(Dns::getSrvRecords($domain, 'ldap'), Dns::getSrvRecords($domain, 'ldaps'));
|
||||
if (isset($records[0])) {
|
||||
$record = $records[0];
|
||||
if (isset($record['port'])) {
|
||||
$cap = $this->discoverCapabilities(array(
|
||||
'hostname' => $record['target'],
|
||||
'port' => $record['port']
|
||||
));
|
||||
} else {
|
||||
$cap = $this->discoverCapabilities(array(
|
||||
'hostname' => $record['target'],
|
||||
'port' => 389
|
||||
));
|
||||
}
|
||||
}
|
||||
return $cap;
|
||||
}
|
||||
|
||||
private function discoverCapabilities($config)
|
||||
{
|
||||
$conn = new Connection(new Config($config));
|
||||
try {
|
||||
$conn->connect();
|
||||
$this->capabilities = $conn->getCapabilities();
|
||||
$this->namingContext = $conn->getDefaultNamingContext();
|
||||
$this->port = $config['port'];
|
||||
$this->domain = $config['hostname'];
|
||||
return true;
|
||||
} catch (LdapException $e) {
|
||||
Logger::info(
|
||||
'Ldap discovery for ' . $config['hostname'] . ':' . $config['port'] . ' failed: ' . $e->getMessage()
|
||||
);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public function suggestResourceSettings()
|
||||
{
|
||||
if (! isset($this->capabilities)) {
|
||||
return array();
|
||||
}
|
||||
if (isset($this->capabilities->msCapabilities->ActiveDirectoryOid)) {
|
||||
return array(
|
||||
'hostname' => $this->domain,
|
||||
'port' => $this->port,
|
||||
'root_dn' => $this->namingContext
|
||||
);
|
||||
} else {
|
||||
return array(
|
||||
'hostname' => $this->domain,
|
||||
'port' => $this->port,
|
||||
'root_dn' => $this->namingContext
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function hasSuggestion()
|
||||
{
|
||||
return isset($this->capabilities);
|
||||
}
|
||||
|
||||
public function suggestBackendSettings()
|
||||
{
|
||||
if (! isset($this->capabilities)) {
|
||||
return array();
|
||||
}
|
||||
if (isset($this->capabilities->msCapabilities->ActiveDirectoryOid)) {
|
||||
return array(
|
||||
'base_dn' => $this->namingContext,
|
||||
'user_class' => 'user',
|
||||
'user_name_attribute' => 'sAMAccountName'
|
||||
);
|
||||
} else {
|
||||
return array(
|
||||
'base_dn' => $this->namingContext,
|
||||
'user_class' => 'inetOrgPerson',
|
||||
'user_name_attribute' => 'uid'
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public function isAd()
|
||||
{
|
||||
return isset($this->capabilities->msCapabilities->ActiveDirectoryOid);
|
||||
}
|
||||
}
|
|
@ -23,6 +23,13 @@ class AuthBackendPage extends Form
|
|||
*/
|
||||
protected $config;
|
||||
|
||||
/**
|
||||
* Suggested configuration settings
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $suggestions;
|
||||
|
||||
/**
|
||||
* Initialize this page
|
||||
*/
|
||||
|
@ -54,6 +61,19 @@ class AuthBackendPage extends Form
|
|||
return new Zend_Config($this->config);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set suggested configuration settings
|
||||
*
|
||||
* @param array $suggestions
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setSuggestions(array $suggestions)
|
||||
{
|
||||
$this->suggestions = $suggestions;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
|
@ -85,6 +105,10 @@ class AuthBackendPage extends Form
|
|||
$backendForm = new DbBackendForm();
|
||||
$backendForm->createElements($formData)->removeElement('resource');
|
||||
} elseif ($this->config['type'] === 'ldap') {
|
||||
if ($this->suggestions !== null) {
|
||||
$formData += $this->suggestions;
|
||||
}
|
||||
|
||||
$backendForm = new LdapBackendForm();
|
||||
$backendForm->createElements($formData)->removeElement('resource');
|
||||
} else { // $this->config['type'] === 'autologin'
|
||||
|
|
|
@ -0,0 +1,128 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Form\Setup;
|
||||
|
||||
use Icinga\Protocol\Dns;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Web\Form\Element\Note;
|
||||
use Icinga\Form\LdapDiscoveryForm;
|
||||
use Icinga\Form\Config\Resource\LdapResourceForm;
|
||||
use Icinga\Web\Request;
|
||||
|
||||
/**
|
||||
* Wizard page to define the connection details for a LDAP resource
|
||||
*/
|
||||
class LdapDiscoveryConfirmPage extends Form
|
||||
{
|
||||
const TYPE_AD = 'MS ActiveDirectory';
|
||||
const TYPE_MISC = 'LDAP';
|
||||
|
||||
private $infoTemplate = <<< 'EOT'
|
||||
<br/>
|
||||
Found LDAP server on {domain}
|
||||
<ul>
|
||||
<li><b>Type:</b> {type}</li>
|
||||
<li><b>Port:</b> {port}</li>
|
||||
<li><b>Root DN:</b> {root_dn}</li>
|
||||
<li><b>User-Class:</b> {user_class}</li>
|
||||
<li><b>User-Attribue:</b> {user_attribute}</li>
|
||||
</ul>
|
||||
EOT;
|
||||
|
||||
/**
|
||||
* The previous configuration
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $config;
|
||||
|
||||
/**
|
||||
* Initialize this page
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->setName('setup_ldap_discovery_confirm');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the resource configuration to use
|
||||
*
|
||||
* @param array $config
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setResourceConfig(array $config)
|
||||
{
|
||||
$this->config = $config;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the resource configuration as Zend_Config object
|
||||
*
|
||||
* @return Zend_Config
|
||||
*/
|
||||
public function getResourceConfig()
|
||||
{
|
||||
return new Zend_Config($this->config);
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
$resource = $this->config['resource'];
|
||||
$backend = $this->config['backend'];
|
||||
$html = $this->infoTemplate;
|
||||
$html = str_replace('{domain}', $this->config['domain'], $html);
|
||||
$html = str_replace('{type}', $this->config['type'], $html);
|
||||
$html = str_replace('{hostname}', $resource['hostname'], $html);
|
||||
$html = str_replace('{port}', $resource['port'], $html);
|
||||
$html = str_replace('{root_dn}', $resource['root_dn'], $html);
|
||||
$html = str_replace('{user_attribute}', $backend['user_name_attribute'], $html);
|
||||
$html = str_replace('{user_class}', $backend['user_class'], $html);
|
||||
|
||||
$this->addElement(
|
||||
new Note(
|
||||
'suggestion',
|
||||
array('value' => $html)
|
||||
)
|
||||
);
|
||||
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'confirm',
|
||||
array(
|
||||
'value' => '1',
|
||||
'label' => t('Use this configuration?')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the given form data and check whether a BIND-request is successful
|
||||
*
|
||||
* @param array $data The data to validate
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($data)
|
||||
{
|
||||
if (false === parent::isValid($data)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getValues($suppressArrayNotation = false)
|
||||
{
|
||||
if ($this->getValue('confirm') === '1') {
|
||||
// use configuration
|
||||
return $this->config;
|
||||
}
|
||||
return null;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,97 @@
|
|||
<?php
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
// {{{ICINGA_LICENSE_HEADER}}}
|
||||
|
||||
namespace Icinga\Form\Setup;
|
||||
|
||||
use Icinga\Protocol\Dns;
|
||||
use Icinga\Web\Form;
|
||||
use Icinga\Web\Form\Element\Note;
|
||||
use Icinga\Form\LdapDiscoveryForm;
|
||||
use Icinga\Form\Config\Resource\LdapResourceForm;
|
||||
use Icinga\Web\Request;
|
||||
|
||||
/**
|
||||
* Wizard page to define the connection details for a LDAP resource
|
||||
*/
|
||||
class LdapDiscoveryPage extends Form
|
||||
{
|
||||
/**
|
||||
* @var LdapDiscoveryForm
|
||||
*/
|
||||
private $discoveryForm;
|
||||
|
||||
/**
|
||||
* Initialize this page
|
||||
*/
|
||||
public function init()
|
||||
{
|
||||
$this->setName('setup_ldap_discovery');
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
public function createElements(array $formData)
|
||||
{
|
||||
$this->addElement(
|
||||
new Note(
|
||||
'description',
|
||||
array(
|
||||
'value' => t(
|
||||
'You can use this page to discover LDAP or ActiveDirectory servers ' .
|
||||
' for authentication. If you don\' want to execute a discovery, just skip this step.'
|
||||
)
|
||||
)
|
||||
)
|
||||
);
|
||||
|
||||
$this->discoveryForm = new LdapDiscoveryForm();
|
||||
$this->addElements($this->discoveryForm->createElements($formData)->getElements());
|
||||
|
||||
$this->addElement(
|
||||
'checkbox',
|
||||
'skip_validation',
|
||||
array(
|
||||
'required' => true,
|
||||
'label' => t('Skip'),
|
||||
'description' => t('Do not discover LDAP servers and enter all settings manually.')
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the given form data and check whether a BIND-request is successful
|
||||
*
|
||||
* @param array $data The data to validate
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isValid($data)
|
||||
{
|
||||
if ($data['skip_validation'] === '1') {
|
||||
return true;
|
||||
}
|
||||
if (false === parent::isValid($data)) {
|
||||
return false;
|
||||
}
|
||||
if (false === $this->discoveryForm->isValid($data)) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
public function getValues($suppressArrayNotation = false)
|
||||
{
|
||||
if (! isset($this->discoveryForm) || ! $this->discoveryForm->hasSuggestion()) {
|
||||
return null;
|
||||
}
|
||||
return array(
|
||||
'domain' => $this->getValue('domain'),
|
||||
'type' => $this->discoveryForm->isAd() ?
|
||||
LdapDiscoveryConfirmPage::TYPE_AD : LdapDiscoveryConfirmPage::TYPE_MISC,
|
||||
'resource' => $this->discoveryForm->suggestResourceSettings(),
|
||||
'backend' => $this->discoveryForm->suggestBackendSettings()
|
||||
);
|
||||
}
|
||||
}
|
|
@ -13,6 +13,13 @@ use Icinga\Form\Config\Resource\LdapResourceForm;
|
|||
*/
|
||||
class LdapResourcePage extends Form
|
||||
{
|
||||
/**
|
||||
* Suggested configuration settings
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $suggestions;
|
||||
|
||||
/**
|
||||
* Initialize this page
|
||||
*/
|
||||
|
@ -21,6 +28,19 @@ class LdapResourcePage extends Form
|
|||
$this->setName('setup_ldap_resource');
|
||||
}
|
||||
|
||||
/**
|
||||
* Set suggested configuration settings
|
||||
*
|
||||
* @param array $suggestions
|
||||
*
|
||||
* @return self
|
||||
*/
|
||||
public function setSuggestions(array $suggestions)
|
||||
{
|
||||
$this->suggestions = $suggestions;
|
||||
return $this;
|
||||
}
|
||||
|
||||
/**
|
||||
* @see Form::createElements()
|
||||
*/
|
||||
|
@ -59,6 +79,10 @@ class LdapResourcePage extends Form
|
|||
);
|
||||
}
|
||||
|
||||
if ($this->suggestions !== null) {
|
||||
$formData += $this->suggestions;
|
||||
}
|
||||
|
||||
$resourceForm = new LdapResourceForm();
|
||||
$this->addElements($resourceForm->createElements($formData)->getElements());
|
||||
}
|
||||
|
|
|
@ -11,6 +11,8 @@ use Icinga\Form\Setup\DbResourcePage;
|
|||
use Icinga\Form\Setup\PreferencesPage;
|
||||
use Icinga\Form\Setup\AuthBackendPage;
|
||||
use Icinga\Form\Setup\AdminAccountPage;
|
||||
use Icinga\Form\Setup\LdapDiscoveryPage;
|
||||
use Icinga\Form\Setup\LdapDiscoveryConfirmPage;
|
||||
use Icinga\Form\Setup\LdapResourcePage;
|
||||
use Icinga\Form\Setup\RequirementsPage;
|
||||
use Icinga\Form\Setup\GeneralConfigPage;
|
||||
|
@ -56,6 +58,8 @@ class WebSetup extends Wizard implements SetupWizard
|
|||
$this->addPage(new AuthenticationPage());
|
||||
$this->addPage(new PreferencesPage());
|
||||
$this->addPage(new DbResourcePage());
|
||||
$this->addPage(new LdapDiscoveryPage());
|
||||
$this->addPage(new LdapDiscoveryConfirmPage());
|
||||
$this->addPage(new LdapResourcePage());
|
||||
$this->addPage(new AuthBackendPage());
|
||||
$this->addPage(new AdminAccountPage());
|
||||
|
@ -82,7 +86,15 @@ class WebSetup extends Wizard implements SetupWizard
|
|||
$page->setResourceConfig($this->getPageData('setup_db_resource'));
|
||||
} elseif ($authData['type'] === 'ldap') {
|
||||
$page->setResourceConfig($this->getPageData('setup_ldap_resource'));
|
||||
|
||||
$suggestions = $this->getPageData('setup_ldap_discovery_confirm');
|
||||
if (isset($suggestions['backend'])) {
|
||||
$page->setSuggestions($suggestions['backend']);
|
||||
}
|
||||
}
|
||||
} else if ($page->getName() === 'setup_ldap_discovery_confirm') {
|
||||
$page->setResourceConfig($this->getPageData('setup_ldap_discovery'));
|
||||
|
||||
} elseif ($page->getName() === 'setup_admin_account') {
|
||||
$page->setBackendConfig($this->getPageData('setup_authentication_backend'));
|
||||
$authData = $this->getPageData('setup_authentication_type');
|
||||
|
@ -108,6 +120,11 @@ class WebSetup extends Wizard implements SetupWizard
|
|||
t('The given resource name must be unique and is already in use by the database resource')
|
||||
);
|
||||
}
|
||||
$suggestion = $this->getPageData('setup_ldap_discovery_confirm');
|
||||
if (isset($suggestion['resource'])) {
|
||||
$page->setSuggestions($suggestion['resource']);
|
||||
}
|
||||
|
||||
} elseif ($page->getName() === 'setup_authentication_type') {
|
||||
$authData = $this->getPageData($page->getName());
|
||||
if ($authData !== null && $request->getPost('type') !== $authData['type']) {
|
||||
|
@ -131,6 +148,8 @@ class WebSetup extends Wizard implements SetupWizard
|
|||
$prefData = $this->getPageData('setup_preferences_type');
|
||||
$authData = $this->getPageData('setup_authentication_type');
|
||||
$skip = $prefData['type'] !== 'db' && $authData['type'] !== 'db';
|
||||
} elseif ($newPage->getName() === 'setup_ldap_discovery_confirm') {
|
||||
$skip = $this->getPageData('setup_ldap_discovery') === null;
|
||||
} elseif ($newPage->getName() === 'setup_ldap_resource') {
|
||||
$authData = $this->getPageData('setup_authentication_type');
|
||||
$skip = $authData['type'] !== 'ldap';
|
||||
|
|
Loading…
Reference in New Issue