Auth/LDAP, always add user DN to getLastAuthProperties() and optionally extend with properties available for the user, which might help ease debugging

This commit is contained in:
Ad Schellevis 2018-10-18 08:18:51 +02:00
parent 91fac36390
commit 1ddbb3bdbb
2 changed files with 56 additions and 9 deletions

View File

@ -100,6 +100,17 @@ class LDAP extends Base implements IAuthConnector
* @var bool if true, startTLS will be initialized
*/
private $useStartTLS = false;
/**
* when set, $lastAuthProperties will contain the authenticated user properties
*/
private $ldapReadProperties = false;
/**
* @var array internal list of authentication properties (returned by radius auth)
*/
private $lastAuthProperties = array();
/**
* close ldap handle if open
*/
@ -204,7 +215,8 @@ class LDAP extends Base implements IAuthConnector
"ldap_extended_query" => "ldapExtendedQuery",
"ldap_authcn" => "ldapAuthcontainers",
"ldap_scope" => "ldapScope",
"local_users" => "userDNmap"
"local_users" => "userDNmap",
"ldap_read_properties" => "ldapReadProperties"
);
// map properties 1-on-1
@ -356,7 +368,7 @@ class LDAP extends Base implements IAuthConnector
*/
public function getLastAuthProperties()
{
return array();
return $this->lastAuthProperties;
}
/**
@ -367,26 +379,48 @@ class LDAP extends Base implements IAuthConnector
*/
public function authenticate($username, $password)
{
// todo: implement SSL parts (legacy : ldap_setup_caenv)
$ldap_is_connected = false;
$user_dn = null;
// authenticate user
if (empty($password)) {
// prevent anonymous bind
return false;
} elseif (array_key_exists($username, $this->userDNmap)) {
// we can map $username to distinguished name, just feed to connect
$user_dn = $this->userDNmap[$username];
$ldap_is_connected = $this->connect($this->ldapBindURL, $this->userDNmap[$username], $password);
return $ldap_is_connected;
} else {
// we don't know this users distinguished name, try to find it
$ldap_is_connected = $this->connect($this->ldapBindURL, $this->ldapBindDN, $this->ldapBindPassword);
if ($ldap_is_connected) {
if ($this->connect($this->ldapBindURL, $this->ldapBindDN, $this->ldapBindPassword)) {
$result = $this->searchUsers($username, $this->ldapAttributeUser, $this->ldapExtendedQuery);
if ($result !== false && count($result) > 0) {
$user_dn = $result[0]['dn'];
$ldap_is_connected = $this->connect($this->ldapBindURL, $result[0]['dn'], $password);
return $ldap_is_connected;
}
}
return false;
}
if ($ldap_is_connected) {
$this->lastAuthProperties['dn'] = $user_dn;
if ($this->ldapReadProperties) {
$sr = @ldap_read($this->ldapHandle, $userdn, '(objectclass=*)');
$info = @ldap_get_entries($this->ldapHandle, $sr);
if ($info['count'] != 0) {
// $this->lastAuthProperties['info'] = $info[0];
foreach ($info[0] as $ldap_key => $ldap_value) {
if (!is_numeric($ldap_key) && $ldap_key !== 'count') {
if (isset($ldap_value['count'])) {
unset($ldap_value['count']);
$this->lastAuthProperties[$ldap_key] = implode("\n", $ldap_value);
} elseif ($ldap_value !== "") {
$this->lastAuthProperties[$ldap_key] = $ldap_value;
}
}
}
}
}
}
return $ldap_is_connected;
}
}

View File

@ -88,6 +88,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
if (!empty($a_server[$id]['ldap_bindpw'])) {
$pconfig['ldap_bindpw'] = $a_server[$id]['ldap_bindpw'];
}
$pconfig['ldap_read_properties'] = !empty($a_server[$id]['ldap_read_properties']);
} elseif ($pconfig['type'] == "radius") {
$pconfig['radius_host'] = $a_server[$id]['host'];
$pconfig['radius_auth_port'] = $a_server[$id]['radius_auth_port'];
@ -236,6 +237,7 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
unset($server['ldap_bindpw']);
}
}
$server['ldap_read_properties'] = !empty($pconfig['ldap_read_properties']);
} elseif ($server['type'] == "radius") {
$server['host'] = $pconfig['radius_host'];
@ -304,7 +306,8 @@ if ($_SERVER['REQUEST_METHOD'] === 'GET') {
// list of all possible fields for auth item (used for form init)
$all_authfields = array(
'type','name','ldap_caref','ldap_host','ldap_port','ldap_urltype','ldap_protver','ldap_scope',
'ldap_basedn','ldap_authcn','ldap_extended_query','ldap_binddn','ldap_bindpw','ldap_attr_user','radius_host',
'ldap_basedn','ldap_authcn','ldap_extended_query','ldap_binddn','ldap_bindpw','ldap_attr_user',
'ldap_read_properties', 'radius_host',
'radius_auth_port','radius_acct_port','radius_secret','radius_timeout','radius_srvcs'
);
@ -730,6 +733,16 @@ endif; ?>
</div>
</td>
</tr>
<tr class="auth_ldap auth_options hidden">
<td><a id="help_for_ldap_read_properties" href="#" class="showhelp"><i class="fa fa-info-circle"></i></a> <?=gettext('Read properties'); ?></td>
<td>
<input id="ldap_read_properties" name="ldap_read_properties" type="checkbox" <?= empty($pconfig['ldap_read_properties']) ? '' : 'checked="checked"';?> />
<div class="hidden" data-for="help_for_ldap_read_properties">
<?= gettext("Normally the authentication only tries to bind to the remote server, ".
"when this option is enabled also the objects properties are fetched, can be practical for debugging purposes.");?>
</div>
</td>
</tr>
<!-- RADIUS -->
<tr class="auth_radius auth_options hidden">
<td><i class="fa fa-info-circle text-muted"></i> <?=gettext("Hostname or IP address");?></td>