LDAP Wizard: autodetect base DN
This commit is contained in:
parent
7c60384f20
commit
8290929aa6
|
@ -45,6 +45,7 @@ $wizard = new \OCA\user_ldap\lib\Wizard($configuration, $ldapWrapper);
|
|||
|
||||
switch($action) {
|
||||
case 'guessPortAndTLS':
|
||||
case 'guessBaseDN':
|
||||
try {
|
||||
$result = $wizard->$action();
|
||||
if($result !== false) {
|
||||
|
|
|
@ -126,7 +126,7 @@ var LdapConfiguration = {
|
|||
|
||||
var LdapWizard = {
|
||||
checkPortInfoShown: false,
|
||||
changeIndicators: {},
|
||||
saveBlacklist: {},
|
||||
|
||||
ajax: function(param, fnOnSuccess, fnOnError) {
|
||||
$.post(
|
||||
|
@ -144,10 +144,36 @@ var LdapWizard = {
|
|||
|
||||
applyChanges: function (result) {
|
||||
for (id in result.changes) {
|
||||
LdapWizard.saveBlacklist[id] = true;
|
||||
$('#'+id).val(result.changes[id]);
|
||||
}
|
||||
},
|
||||
|
||||
checkBaseDN: function() {
|
||||
host = $('#ldap_host').val();
|
||||
user = $('#ldap_dn').val();
|
||||
pass = $('#ldap_agent_password').val();
|
||||
|
||||
if(host && user && pass) {
|
||||
param = 'action=guessBaseDN'+
|
||||
'&ldap_serverconfig_chooser='+$('#ldap_serverconfig_chooser').val();
|
||||
|
||||
LdapWizard.ajax(param,
|
||||
function(result) {
|
||||
LdapWizard.applyChanges(result);
|
||||
if($('#ldap_base').val()) {
|
||||
$('#ldap_base').removeClass('hidden');
|
||||
LdapWizard.hideInfoBox();
|
||||
}
|
||||
},
|
||||
function (result) {
|
||||
$('#ldap_base').removeClass('hidden');
|
||||
LdapWizard.showInfoBox('Please specify a port');
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
checkPort: function() {
|
||||
host = $('#ldap_host').val();
|
||||
user = $('#ldap_dn').val();
|
||||
|
@ -162,30 +188,45 @@ var LdapWizard = {
|
|||
LdapWizard.applyChanges(result);
|
||||
if($('#ldap_port').val()) {
|
||||
$('#ldap_port').removeClass('hidden');
|
||||
if(LdapWizard.checkPortInfoShown) {
|
||||
$('#ldapWizard1 .ldapWizardInfo').addClass('hidden');
|
||||
LdapWizard.checkPortInfoShown = false;
|
||||
}
|
||||
LdapWizard.hideInfoBox();
|
||||
}
|
||||
},
|
||||
function (result) {
|
||||
$('#ldap_port').removeClass('hidden');
|
||||
$('#ldapWizard1 .ldapWizardInfo').text(t('user_ldap',
|
||||
'Please specify a port'));
|
||||
$('#ldapWizard1 .ldapWizardInfo').removeClass('hidden');
|
||||
LdapWizard.checkPortInfoShown = true;
|
||||
LdapWizard.showInfoBox('Please specify the BaseDN');
|
||||
}
|
||||
);
|
||||
}
|
||||
},
|
||||
|
||||
hideInfoBox: function() {
|
||||
if(LdapWizard.checkInfoShown) {
|
||||
$('#ldapWizard1 .ldapWizardInfo').addClass('hidden');
|
||||
LdapWizard.checkInfoShown = false;
|
||||
}
|
||||
},
|
||||
|
||||
init: function() {
|
||||
if($('#ldap_port').val()) {
|
||||
$('#ldap_port').removeClass('hidden');
|
||||
}
|
||||
},
|
||||
|
||||
processChanges: function(triggerObj) {
|
||||
if(triggerObj.id == 'ldap_host'
|
||||
|| triggerObj.id == 'ldap_port'
|
||||
|| triggerObj.id == 'ldap_dn'
|
||||
|| triggerObj.id == 'ldap_agent_password') {
|
||||
LdapWizard.checkPort();
|
||||
LdapWizard.checkBaseDN();
|
||||
}
|
||||
},
|
||||
|
||||
save: function(inputObj) {
|
||||
if(LdapWizard.saveBlacklist.hasOwnProperty(inputObj.id)) {
|
||||
delete LdapWizard.saveBlacklist[inputObj.id];
|
||||
return;
|
||||
}
|
||||
param = 'cfgkey='+inputObj.id+
|
||||
'&cfgval='+$(inputObj).val()+
|
||||
'&action=save'+
|
||||
|
@ -196,16 +237,18 @@ var LdapWizard = {
|
|||
param,
|
||||
function(result) {
|
||||
if(result.status == 'success') {
|
||||
if(inputObj.id == 'ldap_host'
|
||||
|| inputObj.id == 'ldap_dn'
|
||||
|| inputObj.id == 'ldap_agent_password') {
|
||||
LdapWizard.checkPort();
|
||||
}
|
||||
LdapWizard.processChanges(inputObj);
|
||||
} else {
|
||||
// alert('Oooooooooooh :(');
|
||||
}
|
||||
}
|
||||
);
|
||||
},
|
||||
|
||||
showInfoBox: function(text) {
|
||||
$('#ldapWizard1 .ldapWizardInfo').text(t('user_ldap', text));
|
||||
$('#ldapWizard1 .ldapWizardInfo').removeClass('hidden');
|
||||
LdapWizard.checkInfoShown = true;
|
||||
}
|
||||
};
|
||||
|
||||
|
|
|
@ -161,4 +161,25 @@ class Helper {
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief extractsthe domain from a given URL
|
||||
* @param $url the URL
|
||||
* @return mixed, domain as string on success, false otherwise
|
||||
*/
|
||||
static public function getDomainFromURL($url) {
|
||||
$uinfo = parse_url($url);
|
||||
if(!is_array($uinfo)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$domain = false;
|
||||
if(isset($uinfo['host'])) {
|
||||
$domain = $uinfo['host'];
|
||||
} else if(isset($uinfo['path'])) {
|
||||
$domain = $uinfo['path'];
|
||||
}
|
||||
|
||||
return $domain;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -67,6 +67,14 @@ interface ILDAPWrapper {
|
|||
*/
|
||||
public function controlPagedResultResponse($link, $result, &$cookie);
|
||||
|
||||
/**
|
||||
* @brief Count the number of entries in a search
|
||||
* @param $link LDAP link resource
|
||||
* @param $result LDAP result resource
|
||||
* @return mixed, number of results on success, false otherwise
|
||||
*/
|
||||
public function countEntries($link, $result);
|
||||
|
||||
/**
|
||||
* @brief Return the LDAP error number of the last LDAP command
|
||||
* @param $link LDAP link resource
|
||||
|
|
|
@ -49,6 +49,10 @@ class LDAP implements ILDAPWrapper {
|
|||
$isCritical, $cookie);
|
||||
}
|
||||
|
||||
public function countEntries($link, $result) {
|
||||
return $this->invokeLDAPMethod('count_entries', $link, $result);
|
||||
}
|
||||
|
||||
public function errno($link) {
|
||||
return $this->invokeLDAPMethod('errno', $link);
|
||||
}
|
||||
|
|
|
@ -89,6 +89,10 @@ class Wizard extends LDAPUtility {
|
|||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief tries to determine a base dn from User DN or LDAP Host
|
||||
* @returns mixed WizardResult on success, false otherwise
|
||||
*/
|
||||
public function guessBaseDN() {
|
||||
if(!$this->checkRequirements(array('ldapHost',
|
||||
'ldapAgentName',
|
||||
|
@ -97,10 +101,52 @@ class Wizard extends LDAPUtility {
|
|||
))) {
|
||||
return false;
|
||||
}
|
||||
$cr = $this->getConnection();
|
||||
if(!$cr) {
|
||||
|
||||
//check whether a DN is given in the agent name (99.9% of all cases)
|
||||
$base = null;
|
||||
$i = stripos($this->configuration->ldapAgentName, 'dc=');
|
||||
if($i !== false) {
|
||||
$base = substr($this->configuration->ldapAgentName, $i);
|
||||
|
||||
if($this->testBaseDN($base)) {
|
||||
$this->applyFind('ldap_base', $base);
|
||||
$this->applyFind('ldap_base_users', $base);
|
||||
$this->applyFind('ldap_base_groups', $base);
|
||||
return $this->result;
|
||||
}
|
||||
}
|
||||
|
||||
//this did not help :(
|
||||
//Let's see whether we can parse the Host URL and convert the domain to
|
||||
//a base DN
|
||||
$domain = Helper::getDomainFromURL($this->configuration->ldapHost);
|
||||
if(!$domain) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$dparts = explode('.', $domain);
|
||||
$base2 = implode('dc=', $dparts);
|
||||
if($base !== $base2 && $this->testBaseDN($base2)) {
|
||||
$this->applyFind('ldap_base', $base2);
|
||||
$this->applyFind('ldap_base_users', $base2);
|
||||
$this->applyFind('ldap_base_groups', $base2);
|
||||
return $this->result;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief sets the found value for the configuration key in the WizardResult
|
||||
* as well as in the Configuration instance
|
||||
* @param $key the configuration key
|
||||
* @param $value the (detected) value
|
||||
* @return null
|
||||
*
|
||||
*/
|
||||
private function applyFind($key, $value) {
|
||||
$this->result->addChange($key, $value);
|
||||
$this->configuration->setConfiguration(array($key => $value));
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -116,15 +162,32 @@ class Wizard extends LDAPUtility {
|
|||
if(is_array($hostInfo) && isset($hostInfo['port'])) {
|
||||
$port = $hostInfo['port'];
|
||||
$host = str_replace(':'.$port, '', $host);
|
||||
$config = array('ldapHost' => $host,
|
||||
'ldapPort' => $port,
|
||||
);
|
||||
$this->result->addChange('ldap_host', $host);
|
||||
$this->result->addChange('ldap_port', $port);
|
||||
$this->configuration->setConfiguration($config);
|
||||
$this->applyFind('ldap_host', $host);
|
||||
$this->applyFind('ldap_port', $port);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Checks whether for a given BaseDN results will be returned
|
||||
* @param $base the BaseDN to test
|
||||
* @return bool true on success, false otherwise
|
||||
*/
|
||||
private function testBaseDN($base) {
|
||||
$cr = $this->getConnection();
|
||||
if(!$cr) {
|
||||
throw new \Excpetion('Could not connect to LDAP');
|
||||
}
|
||||
|
||||
//base is there, let's validate it. If we search for anything, we should
|
||||
//get a result set > 0 on a proper base
|
||||
$rr = $this->ldap->search($cr, $base, 'objectClass=*', array('dn'), 0, 1);
|
||||
if(!$this->ldap->isResource($rr)) {
|
||||
return false;
|
||||
}
|
||||
$entries = $this->ldap->countEntries($cr, $rr);
|
||||
return ($entries !== false) && ($entries > 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects and Binds to an LDAP Server
|
||||
* @param $port the port to connect with
|
||||
|
|
Loading…
Reference in New Issue