Introduce Groups from LDAP to User Object

This commit is contained in:
Alexander Fuhr 2014-10-01 15:58:53 +02:00
parent f315e10f5a
commit 017d4b8c9d
3 changed files with 121 additions and 18 deletions

View File

@ -18,6 +18,10 @@ backend = ldap
resource = internal_ldap
user_class = @ldap_user_objectclass@
user_name_attribute = @ldap_attribute_username@
group_base_dn = @ldap_group_base_dn@
group_attribute = @ldap_group_attribute@
group_member_attribute = @ldap_group_member_attribute@
group_class = @ldap_group_class@
[internal_db_authentication]
@internal_auth_disabled@

View File

@ -4,6 +4,7 @@
namespace Icinga\Authentication\Backend;
use Icinga\Logger\Logger;
use Icinga\User;
use Icinga\Authentication\UserBackend;
use Icinga\Protocol\Ldap\Connection;
@ -23,11 +24,14 @@ class LdapUserBackend extends UserBackend
protected $userNameAttribute;
public function __construct(Connection $conn, $userClass, $userNameAttribute)
protected $groupOptions;
public function __construct(Connection $conn, $userClass, $userNameAttribute, $groupOptions = null)
{
$this->conn = $conn;
$this->userClass = $userClass;
$this->userNameAttribute = $userNameAttribute;
$this->groupOptions = $groupOptions;
}
/**
@ -83,6 +87,41 @@ class LdapUserBackend extends UserBackend
}
}
/**
* Retrieve the user groups
*
* @param string $dn
*
* @return array|null
*/
public function getGroups($dn)
{
if (empty($this->groupOptions)) {
return null;
}
$q = $this->conn->select()
->setBase($this->groupOptions['group_base_dn'])
->from(
$this->groupOptions['group_class'],
array($this->groupOptions['group_attribute'])
)
->where(
$this->groupOptions['group_member_attribute'],
$dn
);
$result = $this->conn->fetchAll($q);
$groups = array();
foreach ($result as $group) {
$groups[] = $group->{$this->groupOptions['group_attribute']};
}
return $groups;
}
/**
* Test whether the given user exists
*
@ -127,10 +166,15 @@ class LdapUserBackend extends UserBackend
return false;
}
try {
return $this->conn->testCredentials(
$this->conn->fetchDN($this->createQuery($user->getUsername())),
$userDn = $this->conn->fetchDN($this->createQuery($user->getUsername()));
$authenticated = $this->conn->testCredentials(
$userDn,
$password
);
if ($authenticated) {
$user->setGroups($this->getGroups($userDn));
}
return $authenticated;
} catch (LdapException $e) {
// Error during authentication of this specific user
throw new AuthenticationException(
@ -160,4 +204,3 @@ class LdapUserBackend extends UserBackend
);
}
}

View File

@ -93,26 +93,34 @@ abstract class UserBackend implements Countable
$backend = new DbUserBackend($resource);
break;
case 'msldap':
self::checkLdapConfiguration($name, $backendConfig);
$groupOptions = array(
'group_base_dn' => $backendConfig->group_base_dn,
'group_attribute' => $backendConfig->group_attribute,
'group_member_attribute' => $backendConfig->group_member_attribute,
'group_class' => $backendConfig->group_class
);
$backend = new LdapUserBackend(
$resource,
$backendConfig->get('user_class', 'user'),
$backendConfig->get('user_name_attribute', 'sAMAccountName')
$backendConfig->get('user_name_attribute', 'sAMAccountName'),
$groupOptions
);
break;
case 'ldap':
if (($userClass = $backendConfig->user_class) === null) {
throw new ConfigurationError(
'Authentication configuration for backend "%s" is missing the user_class directive',
$name
);
}
if (($userNameAttribute = $backendConfig->user_name_attribute) === null) {
throw new ConfigurationError(
'Authentication configuration for backend "%s" is missing the user_name_attribute directive',
$name
);
}
$backend = new LdapUserBackend($resource, $userClass, $userNameAttribute);
self::checkLdapConfiguration($name, $backendConfig);
$groupOptions = array(
'group_base_dn' => $backendConfig->group_base_dn,
'group_attribute' => $backendConfig->group_attribute,
'group_member_attribute' => $backendConfig->group_member_attribute,
'group_class' => $backendConfig->group_class
);
$backend = new LdapUserBackend(
$resource,
$backendConfig->user_class,
$backendConfig->user_name_attribute,
$groupOptions
);
break;
default:
throw new ConfigurationError(
@ -144,4 +152,52 @@ abstract class UserBackend implements Countable
* @return bool
*/
abstract public function authenticate(User $user, $password);
/**
* Checks the ldap configuration
*
* @param $name
* @param Zend_Config $backendConfig
*
* @throws \Icinga\Exception\ConfigurationError
*/
protected static function checkLdapConfiguration($name, Zend_Config $backendConfig)
{
if ($backendConfig->user_class === null) {
throw new ConfigurationError(
'Authentication configuration for backend "%s" is missing the user_class directive',
$name
);
}
if ($backendConfig->user_name_attribute === null) {
throw new ConfigurationError(
'Authentication configuration for backend "%s" is missing the user_name_attribute directive',
$name
);
}
if ($backendConfig->group_base_dn === null) {
throw new ConfigurationError(
'Authentication configuration for backend "%s" is missing the group_base_dn directive',
$name
);
}
if ($backendConfig->group_attribute === null) {
throw new ConfigurationError(
'Authentication configuration for backend "%s" is missing the group_attribute directive',
$name
);
}
if ($backendConfig->group_member_attribute === null) {
throw new ConfigurationError(
'Authentication configuration for backend "%s" is missing the group_member_attribute directive',
$name
);
}
if ($backendConfig->group_class === null) {
throw new ConfigurationError(
'Authentication configuration for backend "%s" is missing the group_class directive',
$name
);
}
}
}