View source
<?php
namespace Drupal\ldap_authentication\Controller;
use Drupal\Component\Utility\SafeMarkup;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Extension\ModuleHandler;
use Drupal\Core\StringTranslation\StringTranslationTrait;
use Drupal\ldap_authentication\Helper\LdapAuthenticationConfiguration;
use Drupal\ldap_servers\Entity\Server;
use Drupal\ldap_servers\Helper\CredentialsStorage;
use Drupal\ldap_servers\Logger\LdapDetailLog;
use Drupal\ldap_user\Helper\ExternalAuthenticationHelper;
use Drupal\ldap_user\Helper\LdapConfiguration;
use Drupal\ldap_servers\LdapUserAttributesInterface;
use Drupal\ldap_user\Processor\DrupalUserProcessor;
use Drupal\user\Entity\User;
use Drupal\Core\Form\FormStateInterface;
use Psr\Log\LoggerInterface;
final class LoginValidator implements LdapUserAttributesInterface {
use StringTranslationTrait;
const AUTHENTICATION_FAILURE_CONNECTION = 1;
const AUTHENTICATION_FAILURE_BIND = 2;
const AUTHENTICATION_FAILURE_FIND = 3;
const AUTHENTICATION_FAILURE_DISALLOWED = 4;
const AUTHENTICATION_FAILURE_CREDENTIALS = 5;
const AUTHENTICATION_SUCCESS = 6;
const AUTHENTICATION_FAILURE_GENERIC = 7;
const AUTHENTICATION_FAILURE_SERVER = 8;
protected $authName = FALSE;
protected $drupalUserAuthMapped = FALSE;
protected $drupalUserName = FALSE;
protected $serverDrupalUser;
protected $drupalUser = FALSE;
protected $ldapUser = FALSE;
protected $emailTemplateUsed = FALSE;
protected $emailTemplateTokens = [];
protected $formState;
protected $configFactory;
protected $config;
protected $detailLog;
protected $logger;
protected $entityTypeManager;
protected $moduleHandler;
public function __construct(ConfigFactoryInterface $configFactory, LdapDetailLog $detailLog, LoggerInterface $logger, EntityTypeManagerInterface $entity_type_manager, ModuleHandler $module_handler) {
$this->configFactory = $configFactory;
$this->config = $configFactory
->get('ldap_authentication.settings');
$this->detailLog = $detailLog;
$this->logger = $logger;
$this->entityTypeManager = $entity_type_manager;
$this->moduleHandler = $module_handler;
}
public function validateLogin(FormStateInterface $formState) {
$this->authName = trim($formState
->getValue('name'));
$this->formState = $formState;
$this->detailLog
->log('%auth_name : Beginning authentication', [
'%auth_name' => $this->authName,
], 'ldap_authentication');
$this
->processLogin();
return $this->formState;
}
private function processLogin() {
if (!$this
->validateAlreadyAuthenticated()) {
return FALSE;
}
if (!$this
->validateCommonLoginConstraints()) {
return FALSE;
}
$credentialsAuthenticationResult = $this
->testCredentials($this->formState
->getValue('pass'));
if ($credentialsAuthenticationResult == self::AUTHENTICATION_FAILURE_FIND && $this->config
->get('authenticationMode') == LdapAuthenticationConfiguration::MODE_EXCLUSIVE) {
$this->formState
->setErrorByName('non_ldap_login_not_allowed', $this
->t('User disallowed'));
}
if ($credentialsAuthenticationResult != self::AUTHENTICATION_SUCCESS) {
return FALSE;
}
if (!$this
->deriveDrupalUserName()) {
return FALSE;
}
if (!$this->drupalUser && $this->serverDrupalUser) {
$this
->updateAuthNameFromPuid();
}
if ($this->drupalUser && !$this->drupalUserAuthMapped) {
if (!$this
->matchExistingUserWithLdap()) {
return FALSE;
}
}
$this
->fixOutdatedEmailAddress();
if (!$this->drupalUser) {
if (!$this
->provisionDrupalUser()) {
return FALSE;
}
}
if ($this->drupalUser) {
$this->formState
->set('uid', $this->drupalUser
->id());
}
return TRUE;
}
public function processSsoLogin($authName) {
$this->authName = $authName;
if (!$this
->validateCommonLoginConstraints()) {
return FALSE;
}
$credentialsAuthenticationResult = $this
->testSsoCredentials($this->authName);
if ($credentialsAuthenticationResult == self::AUTHENTICATION_FAILURE_FIND && $this->config
->get('authenticationMode') == LdapAuthenticationConfiguration::MODE_EXCLUSIVE) {
$this->formState
->setErrorByName('non_ldap_login_not_allowed', $this
->t('User disallowed'));
}
if ($credentialsAuthenticationResult != self::AUTHENTICATION_SUCCESS) {
return FALSE;
}
if (!$this
->deriveDrupalUserName()) {
return FALSE;
}
if (!$this->drupalUser && $this->serverDrupalUser) {
$this
->updateAuthNameFromPuid();
}
if ($this->drupalUser && !$this->drupalUserAuthMapped) {
if (!$this
->matchExistingUserWithLdap()) {
return FALSE;
}
}
$this
->fixOutdatedEmailAddress();
if (!$this->drupalUser) {
if (!$this
->provisionDrupalUser()) {
return FALSE;
}
}
return TRUE;
}
private function initializeDrupalUserFromAuthName() {
$this->drupalUser = user_load_by_name($this->authName);
if (!$this->drupalUser) {
$uid = ExternalAuthenticationHelper::getUidFromIdentifierMap($this->authName);
if ($uid) {
$this->drupalUser = $this->entityTypeManager
->getStorage('user')
->load($uid);
}
}
if ($this->drupalUser) {
$this->drupalUserAuthMapped = ExternalAuthenticationHelper::getUserIdentifierFromMap($this->drupalUser
->id());
}
}
private function verifyAccountCreation() {
if (is_object($this->drupalUser)) {
if ($this->drupalUser
->id() == 1) {
$this->detailLog
->log('%username: Drupal user name maps to user 1, so do not authenticate with LDAP.', [
'%username' => $this->authName,
], 'ldap_authentication');
return FALSE;
}
else {
$this->detailLog
->log('%username: Drupal user account found. Continuing on to attempt LDAP authentication.', [
'%username' => $this->authName,
], 'ldap_authentication');
return TRUE;
}
}
else {
$ldapUserConfig = $this->configFactory
->get('ldap_user.settings');
if ($ldapUserConfig
->get('acctCreation') == self::ACCOUNT_CREATION_LDAP_BEHAVIOUR || $ldapUserConfig
->get('register') == USER_REGISTER_VISITORS) {
$this->detailLog
->log('%username: Existing Drupal user account not found. Continuing on to attempt LDAP authentication', [
'%username' => $this->authName,
], 'ldap_authentication');
return TRUE;
}
else {
$this->detailLog
->log('%username: Drupal user account not found and configuration is set to not create new accounts.', [
'%username' => $this->authName,
], 'ldap_authentication');
return FALSE;
}
}
}
private function testCredentials($password) {
$authenticationResult = self::AUTHENTICATION_FAILURE_GENERIC;
foreach (LdapAuthenticationConfiguration::getEnabledAuthenticationServers() as $server) {
$authenticationResult = self::AUTHENTICATION_FAILURE_GENERIC;
$this->serverDrupalUser = Server::load($server);
$this->detailLog
->log('%username: Trying server %id with %bind_method', [
'%username' => $this->authName,
'%id' => $this->serverDrupalUser
->id(),
'%bind_method' => $this->serverDrupalUser
->getFormattedBind(),
], 'ldap_authentication');
if (!$this
->connectToServer()) {
continue;
}
$bindStatus = $this
->bindToServer($password);
if ($bindStatus != 'success') {
$authenticationResult = $bindStatus;
continue;
}
$this->ldapUser = $this->serverDrupalUser
->matchUsernameToExistingLdapEntry($this->authName);
if (!$this->ldapUser) {
$this->detailLog
->log('%username: User not found for server %id with %bind_method.', [
'%username' => $this->authName,
'%error' => $this->serverDrupalUser
->formattedError($this->serverDrupalUser
->ldapErrorNumber()),
'%bind_method' => $this->serverDrupalUser
->getFormattedBind(),
'%id' => $this->serverDrupalUser
->id(),
], 'ldap_authentication');
if ($this->serverDrupalUser
->hasError()) {
$authenticationResult = self::AUTHENTICATION_FAILURE_SERVER;
break;
}
$authenticationResult = self::AUTHENTICATION_FAILURE_FIND;
continue;
}
if (!$this
->checkAllowedExcluded($this->authName, $this->ldapUser)) {
$authenticationResult = self::AUTHENTICATION_FAILURE_DISALLOWED;
break;
}
$credentials_pass = $this
->testUserPassword($password);
if (!$credentials_pass) {
$authenticationResult = self::AUTHENTICATION_FAILURE_CREDENTIALS;
continue;
}
else {
$authenticationResult = self::AUTHENTICATION_SUCCESS;
if ($this->serverDrupalUser
->get('bind_method') == 'anon_user') {
$this->ldapUser = $this->serverDrupalUser
->matchUsernameToExistingLdapEntry($this->authName);
}
if ($this->serverDrupalUser
->get('bind_method') == 'service_account' || $this->serverDrupalUser
->get('bind_method') == 'anon_user') {
$this->serverDrupalUser
->disconnect();
}
break;
}
}
$this->detailLog
->log('%username: Authentication result is "%err_text"', [
'%username' => $this->authName,
'%err_text' => $this
->authenticationHelpText($authenticationResult) . ' ' . $this
->additionalDebuggingResponse($authenticationResult),
], 'ldap_authentication');
if ($authenticationResult != self::AUTHENTICATION_SUCCESS) {
$this
->failureResponse($authenticationResult);
}
return $authenticationResult;
}
private function testUserPassword($password) {
$loginValid = FALSE;
if ($this->serverDrupalUser
->get('bind_method') == 'user') {
$loginValid = TRUE;
}
else {
CredentialsStorage::storeUserDn($this->ldapUser['dn']);
CredentialsStorage::testCredentials(TRUE);
$bindResult = $this->serverDrupalUser
->bind();
CredentialsStorage::testCredentials(FALSE);
if ($bindResult == Server::LDAP_SUCCESS) {
$loginValid = TRUE;
}
else {
$this->detailLog
->log('%username: Error testing user credentials on server %id with %bind_method. Error: %err_text', [
'%username' => $this->authName,
'%bind_method' => $this->serverDrupalUser
->getFormattedBind(),
'%id' => $this->serverDrupalUser
->id(),
'%err_text' => $this->serverDrupalUser
->formattedError($bindResult),
], 'ldap_authentication');
}
}
return $loginValid;
}
public function testSsoCredentials($authName) {
$authenticationResult = self::AUTHENTICATION_FAILURE_GENERIC;
foreach (LdapAuthenticationConfiguration::getEnabledAuthenticationServers() as $server) {
$authenticationResult = self::AUTHENTICATION_FAILURE_GENERIC;
$this->serverDrupalUser = Server::load($server);
$this->detailLog
->log('%username: Trying server %id where bind_method = %bind_method', [
'%username' => $authName,
'%id' => $this->serverDrupalUser
->id(),
'%bind_method' => $this->serverDrupalUser
->get('bind_method'),
], 'ldap_authentication');
if (!$this
->connectToServer()) {
continue;
}
$bindResult = $this
->bindToServerSso();
if ($bindResult != 'success') {
$authenticationResult = $bindResult;
continue;
}
$this->ldapUser = $this->serverDrupalUser
->matchUsernameToExistingLdapEntry($authName);
if (!$this->ldapUser) {
$this->detailLog
->log('%username: Trying server %id where bind_method = %bind_method. Error: %err_text', [
'%username' => $authName,
'%bind_method' => $this->serverDrupalUser
->get('bind_method'),
'%err_text' => $this->serverDrupalUser
->formattedError($this->serverDrupalUser
->ldapErrorNumber()),
], 'ldap_authentication');
if ($this->serverDrupalUser
->hasError()) {
$authenticationResult = self::AUTHENTICATION_FAILURE_SERVER;
break;
}
$authenticationResult = self::AUTHENTICATION_FAILURE_FIND;
continue;
}
if (!$this
->checkAllowedExcluded($this->authName, $this->ldapUser)) {
$authenticationResult = self::AUTHENTICATION_FAILURE_DISALLOWED;
break;
}
$authenticationResult = self::AUTHENTICATION_SUCCESS;
if ($this->serverDrupalUser
->get('bind_method') == 'anon_user') {
$this->ldapUser = $this->serverDrupalUser
->matchUsernameToExistingLdapEntry($authName);
}
if ($this->serverDrupalUser
->get('bind_method') == 'service_account' || $this->serverDrupalUser
->get('bind_method') == 'anon_user') {
$this->serverDrupalUser
->disconnect();
}
break;
}
$this->detailLog
->log('Authentication result for %username is: %err_text', [
'%username' => $authName,
'%err_text' => $this
->authenticationHelpText($authenticationResult) . ' ' . $this
->additionalDebuggingResponse($authenticationResult),
], 'ldap_authentication');
return $authenticationResult;
}
private function additionalDebuggingResponse($authenticationResult) {
$information = '';
switch ($authenticationResult) {
case self::AUTHENTICATION_FAILURE_FIND:
$information = $this
->t('(not found)');
break;
case self::AUTHENTICATION_FAILURE_CREDENTIALS:
$information = $this
->t('(wrong credentials)');
break;
case self::AUTHENTICATION_FAILURE_GENERIC:
$information = $this
->t('(generic)');
break;
}
return $information;
}
private function failureResponse($authenticationResult) {
if ($this->config
->get('authenticationMode') == LdapAuthenticationConfiguration::MODE_EXCLUSIVE) {
$this->detailLog
->log('%username: Error raised because failure at LDAP and exclusive authentication is set to true.', [
'%username' => $this->authName,
], 'ldap_authentication');
drupal_set_message($this
->t('Error: %err_text', [
'%err_text' => $this
->authenticationHelpText($authenticationResult),
]), "error");
}
else {
$this->detailLog
->log('%username: Failed LDAP authentication. User may have authenticated successfully by other means in a mixed authentication site.', [
'%username' => $this->authName,
], 'ldap_authentication');
}
}
private function authenticationHelpText($error) {
switch ($error) {
case self::AUTHENTICATION_FAILURE_CONNECTION:
$msg = $this
->t('Failed to connect to LDAP server');
break;
case self::AUTHENTICATION_FAILURE_BIND:
$msg = $this
->t('Failed to bind to LDAP server');
break;
case self::AUTHENTICATION_FAILURE_DISALLOWED:
$msg = $this
->t('User disallowed');
break;
case self::AUTHENTICATION_FAILURE_FIND:
case self::AUTHENTICATION_FAILURE_CREDENTIALS:
case self::AUTHENTICATION_FAILURE_GENERIC:
$msg = $this
->t('Sorry, unrecognized username or password.');
break;
case self::AUTHENTICATION_FAILURE_SERVER:
$msg = $this
->t('Authentication Server or Configuration Error.');
break;
case self::AUTHENTICATION_SUCCESS:
$msg = $this
->t('Authentication successful');
break;
default:
$msg = $this
->t('unknown error: @error', [
'@error' => $error,
]);
break;
}
return $msg;
}
public function checkAllowedExcluded($authName, $ldap_user) {
foreach ($this->config
->get('excludeIfTextInDn') as $test) {
if (stripos($ldap_user['dn'], $test) !== FALSE) {
return FALSE;
}
}
if (count($this->config
->get('allowOnlyIfTextInDn'))) {
$fail = TRUE;
foreach ($this->config
->get('allowOnlyIfTextInDn') as $test) {
if (stripos($ldap_user['dn'], $test) !== FALSE) {
$fail = FALSE;
}
}
if ($fail) {
return FALSE;
}
}
if ($this->moduleHandler
->moduleExists('ldap_authorization') && $this->config
->get('excludeIfNoAuthorizations')) {
$user = FALSE;
$id = ExternalAuthenticationHelper::getUidFromIdentifierMap($authName);
if ($id) {
$user = $this->entityTypeManager
->getStorage('user')
->load($id);
}
if (!$user) {
$user = User::create([
'name' => $authName,
]);
}
$controller = \Drupal::service('authorization.manager');
$controller
->setUser($user);
$profiles = $this->entityTypeManager
->getStorage('authorization_profile')
->getQuery()
->condition('provider', 'ldap_provider')
->execute();
foreach ($profiles as $profile) {
$controller
->queryIndividualProfile($profile);
}
$authorizations = $controller
->getProcessedAuthorizations();
$controller
->clearAuthorizations();
$valid_profile = FALSE;
foreach ($authorizations as $authorization) {
if (!empty($authorization
->getAuthorizationsApplied())) {
$valid_profile = TRUE;
}
}
if (!$valid_profile) {
drupal_set_message($this
->t('The site logon is currently not working due to a configuration error. Please see logs for additional details.'), 'warning');
$this->logger
->notice('LDAP Authentication is configured to deny users without LDAP Authorization mappings, but 0 LDAP Authorization consumers are configured.');
return FALSE;
}
}
$hook_result = TRUE;
$this->moduleHandler
->alter('ldap_authentication_allowuser_results', $ldap_user, $authName, $hook_result);
if ($hook_result === FALSE) {
$this->logger
->notice('Authentication Allow User Result=refused for %name', [
'%name' => $authName,
]);
return FALSE;
}
return TRUE;
}
private function fixOutdatedEmailAddress() {
if ($this->config
->get('emailTemplateUsageNeverUpdate') && $this->emailTemplateUsed) {
return FALSE;
}
if (!$this->drupalUser) {
return FALSE;
}
if ($this->drupalUser
->getEmail() == $this->ldapUser['mail']) {
return FALSE;
}
if ($this->config
->get('emailUpdate') == LdapAuthenticationConfiguration::$emailUpdateOnLdapChangeEnableNotify || $this->config
->get('emailUpdate') == LdapAuthenticationConfiguration::$emailUpdateOnLdapChangeEnable) {
$this->drupalUser
->set('mail', $this->ldapUser['mail']);
if (!$this->drupalUser
->save()) {
$this->logger
->error('Failed to make changes to user %username updated %changed.', [
'%username' => $this->drupalUser
->getAccountName(),
'%changed' => $this->ldapUser['mail'],
]);
return FALSE;
}
elseif ($this->config
->get('emailUpdate') == LdapAuthenticationConfiguration::$emailUpdateOnLdapChangeEnableNotify) {
drupal_set_message($this
->t('Your e-mail has been updated to match your current account (%mail).', [
'%mail' => $this->ldapUser['mail'],
]), 'status');
return TRUE;
}
}
}
private function updateAuthNameFromPuid() {
$puid = $this->serverDrupalUser
->userPuidFromLdapEntry($this->ldapUser['attr']);
if ($puid) {
$this->drupalUser = $this->serverDrupalUser
->userAccountFromPuid($puid);
if ($this->drupalUser) {
$oldName = $this->drupalUser
->getAccountName();
$this->drupalUser
->setUsername($this->drupalUserName);
$this->drupalUser
->save();
ExternalAuthenticationHelper::setUserIdentifier($this->drupalUser, $this->authName);
$this->drupalUserAuthMapped = TRUE;
drupal_set_message($this
->t('Your existing account %username has been updated to %new_username.', [
'%username' => $oldName,
'%new_username' => $this->drupalUserName,
]), 'status');
}
}
}
private function validateAlreadyAuthenticated() {
if (!empty($this->formState
->get('uid'))) {
if ($this->config
->get('authenticationMode') == LdapAuthenticationConfiguration::MODE_MIXED) {
$this->detailLog
->log('%username: Previously authenticated in mixed mode, pass on validation.', [
'%username' => $this->authName,
], 'ldap_authentication');
return FALSE;
}
}
return TRUE;
}
private function validateCommonLoginConstraints() {
if (!LdapAuthenticationConfiguration::hasEnabledAuthenticationServers()) {
$this->logger
->error('No LDAP servers configured.');
if ($this->formState) {
$this->formState
->setErrorByName('name', 'Server Error: No LDAP servers configured.');
}
return FALSE;
}
$this
->initializeDrupalUserFromAuthName();
return $this
->verifyAccountCreation();
}
private function deriveDrupalUserName() {
if (!empty($this->serverDrupalUser
->get('account_name_attr'))) {
$processedName = mb_strtolower($this->serverDrupalUser
->get('account_name_attr'));
$userNameFromAttribute = $this->ldapUser['attr'][$processedName][0];
if (!$userNameFromAttribute) {
$this->logger
->error('Derived Drupal username from attribute %account_name_attr returned no username for authname %authname.', [
'%authname' => $this->authName,
'%account_name_attr' => $this->serverDrupalUser
->get('account_name_attr'),
]);
return FALSE;
}
else {
$this->drupalUserName = $userNameFromAttribute;
}
}
else {
$this->drupalUserName = $this->authName;
}
$this
->prepareEmailTemplateToken();
return TRUE;
}
private function prepareEmailTemplateToken() {
$this->emailTemplateTokens = [
'@username' => $this->drupalUserName,
];
if (!empty($this->config
->get('emailTemplate'))) {
$handling = $this->config
->get('emailTemplateHandling');
if ($handling == 'if_empty' && empty($this->ldapUser['mail']) || $handling == 'always') {
$this
->replaceUserMailWithTemplate();
$this->detailLog
->log('Using template generated email for %username', [
'%username' => $this->drupalUserName,
], 'ldap_authentication');
$this->emailTemplateUsed = TRUE;
}
}
}
private function matchExistingUserWithLdap() {
if ($this->configFactory
->get('ldap_user.settings')
->get('userConflictResolve') == self::USER_CONFLICT_LOG) {
if ($account_with_same_email = user_load_by_mail($this->ldapUser['mail'])) {
$this->logger
->error('LDAP user with DN %dn has a naming conflict with a local Drupal user %conflict_name', [
'%dn' => $this->ldapUser['dn'],
'%conflict_name' => $account_with_same_email
->getAccountName(),
]);
}
drupal_set_message($this
->t('Another user already exists in the system with the same login name. You should contact the system administrator in order to solve this conflict.'), 'error');
return FALSE;
}
else {
ExternalAuthenticationHelper::setUserIdentifier($this->drupalUser, $this->authName);
$this->drupalUserAuthMapped = TRUE;
$this->detailLog
->log('Set authmap for LDAP user %username', [
'%username' => $this->authName,
], 'ldap_authentication');
}
return TRUE;
}
private function replaceUserMailWithTemplate() {
$template = '@username@localhost';
if (!empty($this->config
->get('emailTemplate'))) {
$template = $this->config
->get('emailTemplate');
}
$this->ldapUser['mail'] = SafeMarkup::format($template, $this->emailTemplateTokens)
->__toString();
}
private function provisionDrupalUser() {
if ($accountDuplicateMail = user_load_by_mail($this->ldapUser['mail'])) {
$emailAvailable = FALSE;
if ($this->config
->get('emailTemplateUsageResolveConflict') && !$this->emailTemplateUsed) {
$this->detailLog
->log('Conflict detected, using template generated email for %username', [
'%duplicate_name' => $accountDuplicateMail
->getAccountName(),
], 'ldap_authentication');
$this
->replaceUserMailWithTemplate();
$this->emailTemplateUsed = TRUE;
if ($accountDuplicateMail = user_load_by_mail($this->ldapUser['mail'])) {
$emailAvailable = FALSE;
}
else {
$emailAvailable = TRUE;
}
}
if (!$emailAvailable) {
$this->logger
->error('LDAP user with DN %dn has email address (%mail) conflict with a Drupal user %duplicate_name', [
'%dn' => $this->ldapUser['dn'],
'%duplicate_name' => $accountDuplicateMail
->getAccountName(),
]);
drupal_set_message($this
->t('Another user already exists in the system with the same email address. You should contact the system administrator in order to solve this conflict.'), 'error');
return FALSE;
}
}
if (!LdapConfiguration::provisionAvailableToDrupal(self::PROVISION_DRUPAL_USER_ON_USER_AUTHENTICATION)) {
$this->logger
->error('Drupal account for authname=%authname does not exist and provisioning of Drupal accounts on authentication is not enabled', [
'%authname' => $this->authName,
]);
return FALSE;
}
if ($this->configFactory
->get('ldap_user.settings')
->get('acctCreation') == self::ACCOUNT_CREATION_USER_SETTINGS_FOR_LDAP && $this->configFactory
->get('user.settings')
->get('register') == USER_REGISTER_VISITORS_ADMINISTRATIVE_APPROVAL) {
$user_values = [
'name' => $this->drupalUserName,
'status' => 0,
];
}
else {
$user_values = [
'name' => $this->drupalUserName,
'status' => 1,
];
}
if ($this->emailTemplateUsed) {
$user_values['mail'] = $this->ldapUser['mail'];
}
$processor = new DrupalUserProcessor();
$result = $processor
->provisionDrupalAccount($user_values);
if (!$result) {
$this->logger
->error('Failed to find or create %drupal_accountname on logon.', [
'%drupal_accountname' => $this->drupalUserName,
]);
if ($this->formState) {
$this->formState
->setErrorByName('name', $this
->t('Server Error: Failed to create Drupal user account for %drupal_accountname', [
'%drupal_accountname' => $this->drupalUserName,
]));
}
return FALSE;
}
else {
$this->drupalUser = $processor
->getUserAccount();
return TRUE;
}
}
private function connectToServer() {
$result = $this->serverDrupalUser
->connect();
if ($result != Server::LDAP_SUCCESS) {
$this->detailLog
->log('%username: Failed connecting to %id.', [
'%username' => $this->authName,
'%id' => $this->serverDrupalUser
->id(),
], 'ldap_authentication');
return FALSE;
}
else {
$this->detailLog
->log('%username: Success at connecting to %id', [
'%username' => $this->authName,
'%id' => $this->serverDrupalUser
->id(),
], 'ldap_authentication');
}
return TRUE;
}
private function bindToServer($password) {
$bindResult = FALSE;
$bindMethod = $this->serverDrupalUser
->get('bind_method');
if ($bindMethod == 'user') {
foreach ($this->serverDrupalUser
->getBaseDn() as $basedn) {
$search = [
'%basedn',
'%username',
];
$replace = [
$basedn,
$this->authName,
];
CredentialsStorage::storeUserDn(str_replace($search, $replace, $this->serverDrupalUser
->get('user_dn_expression')));
CredentialsStorage::testCredentials(TRUE);
$bindResult = $this->serverDrupalUser
->bind();
if ($bindResult == Server::LDAP_SUCCESS) {
break;
}
}
}
else {
$bindResult = $this->serverDrupalUser
->bind();
}
if ($bindResult != Server::LDAP_SUCCESS) {
$this->detailLog
->log('%username: Trying server %id (bind method: %bind_method). Error: %err_text', [
'%username' => $this->authName,
'%id' => $this->serverDrupalUser
->id(),
'%err_text' => $this->serverDrupalUser
->formattedError($bindResult),
'%bind_method' => $this->serverDrupalUser
->get('bind_method'),
], 'ldap_authentication');
if ($this->serverDrupalUser
->get('bind_method') == 'user') {
return self::AUTHENTICATION_FAILURE_CREDENTIALS;
}
else {
return self::AUTHENTICATION_FAILURE_BIND;
}
}
return 'success';
}
private function bindToServerSso() {
$bindResult = FALSE;
if ($this->serverDrupalUser
->get('bind_method') == 'user') {
$this->logger
->error('Trying to use SSO with user bind method.');
$this->logger
->debug('No bind method set in ldap_server->bind_method in ldap_authentication_user_login_authenticate_validate.');
return self::AUTHENTICATION_FAILURE_CREDENTIALS;
}
else {
$bindResult = $this->serverDrupalUser
->bind();
}
if ($bindResult != Server::LDAP_SUCCESS) {
$this->detailLog
->log('%username: Trying server %id where bind_method = %bind_method. Error: %err_text', [
'%username' => $this->authName,
'%bind_method' => $this->serverDrupalUser
->get('bind_method'),
'%err_text' => $this->serverDrupalUser
->formattedError($bindResult),
], 'ldap_authentication');
return self::AUTHENTICATION_FAILURE_BIND;
}
return 'success';
}
public function getDrupalUser() {
return $this->drupalUser;
}
}