/** * Deletes all users for a given LDAP configuration. * * This method is meant to be called before a full synchronization, so that existing users which are not * updated will be marked as deleted. * * @param $table * @param $uid */ public static function deleteForConfiguration($table, $uid) { if (isset($GLOBALS['TCA'][$table]['ctrl']['delete'])) { $fields = array($GLOBALS['TCA'][$table]['ctrl']['delete'] => 1); if (isset($GLOBALS['TCA'][$table]['ctrl']['tstamp'])) { $fields[$GLOBALS['TCA'][$table]['ctrl']['tstamp']] = $GLOBALS['EXEC_TIME']; } static::getDatabaseConnection()->exec_UPDATEquery($table, 'tx_igldapssoauth_id = ' . intval($uid), $fields); NotificationUtility::dispatch(__CLASS__, 'userDeleted', array('table' => $table, 'configuration' => $uid)); } }
/** * Find a user (eg. look up the user record in database when a login is sent) * * @return mixed user array or FALSE * @throws UnsupportedLoginSecurityLevelException */ public function getUser() { $user = FALSE; $userRecordOrIsValid = FALSE; $enableFrontendSso = TYPO3_MODE === 'FE' && (bool) $this->config['enableFESSO'] && !empty($_SERVER['REMOTE_USER']); // This simple check is the key to prevent your log being filled up with warnings // due to the AJAX calls to maintain the session active if your configuration forces // the authentication stack to always fetch the user: // $TYPO3_CONF_VARS['SVCONF']['auth']['setup']['BE_alwaysFetchUser'] = true; // This is the case, e.g., when using EXT:crawler. if ($this->login['status'] !== 'login' && !$enableFrontendSso) { return $user; } /** @var \Causal\IgLdapSsoAuth\Domain\Repository\ConfigurationRepository $configurationRepository */ $configurationRepository = GeneralUtility::makeInstance('Causal\\IgLdapSsoAuth\\Domain\\Repository\\ConfigurationRepository'); $configurationRecords = $configurationRepository->findAll(); if (count($configurationRecords) === 0) { // Early return since LDAP is not configured static::getLogger()->warning('Skipping LDAP authentication as extension is not yet configured'); $this->cleanUpExtbaseDataMapper(); return FALSE; } foreach ($configurationRecords as $configurationRecord) { Configuration::initialize(TYPO3_MODE, $configurationRecord); if (!Configuration::isEnabledForCurrentHost()) { $msg = sprintf('Configuration record #%s is not enabled for domain %s', $configurationRecord->getUid(), GeneralUtility::getIndpEnv('TYPO3_HOST_ONLY')); static::getLogger()->info($msg); continue; } // Enable feature $userRecordOrIsValid = FALSE; // Single Sign-On authentication if ($enableFrontendSso) { $remoteUser = $_SERVER['REMOTE_USER']; // Strip the domain name if ($pos = strpos($remoteUser, '@')) { $remoteUser = substr($remoteUser, 0, $pos); } elseif ($pos = strrpos($remoteUser, '\\')) { $remoteUser = substr($remoteUser, $pos + 1); } $userRecordOrIsValid = Authentication::ldapAuthenticate($remoteUser); if (is_array($userRecordOrIsValid)) { // Useful for debugging purpose $this->login['uname'] = $remoteUser; } // Authenticate user from LDAP } elseif ($this->login['status'] === 'login' && $this->login['uident']) { // Configuration of authentication service. $loginSecurityLevel = $GLOBALS['TYPO3_CONF_VARS'][TYPO3_MODE]['loginSecurityLevel']; // normal case // Check if $loginSecurityLevel is set to "challenged" or "superchallenged" and throw an error if the configuration allows it // By default, it will not throw an exception if (isset($this->config['throwExceptionAtLogin']) && $this->config['throwExceptionAtLogin'] == 1) { if ($loginSecurityLevel === 'challenged' || $loginSecurityLevel === 'superchallenged') { $message = "ig_ldap_sso_auth error: current login security level '" . $loginSecurityLevel . "' is not supported."; $message .= " Try to use 'normal' or 'rsa' (highly recommended): "; $message .= "\$GLOBALS['TYPO3_CONF_VARS']['" . TYPO3_MODE . "']['loginSecurityLevel'] = 'rsa';"; $this->cleanUpExtbaseDataMapper(); throw new UnsupportedLoginSecurityLevelException($message, 1324313489); } } // normal case $password = $this->login['uident_text']; try { if ($password !== NULL) { $userRecordOrIsValid = Authentication::ldapAuthenticate($this->login['uname'], $password); } else { // Could not decrypt password $userRecordOrIsValid = FALSE; } } catch (UnresolvedPhpDependencyException $e) { // Possible known exception: 1409566275, LDAP extension is not available for PHP $userRecordOrIsValid = FALSE; } } if (is_array($userRecordOrIsValid)) { $user = $userRecordOrIsValid; break; } elseif ($userRecordOrIsValid) { // Authentication is valid break; } else { $diagnostic = Authentication::getLastAuthenticationDiagnostic(); $info = array('username' => $this->login['uname'], 'remote' => sprintf('%s (%s)', $this->authInfo['REMOTE_ADDR'], $this->authInfo['REMOTE_HOST']), 'diagnostic' => $diagnostic, 'configUid' => $configurationRecord->getUid()); static::getLogger()->error('Authentication failed', $info); NotificationUtility::dispatch(__CLASS__, 'authenticationFailed', $info); } // Continue and try with next configuration record... } if (!$user && $userRecordOrIsValid) { $user = $this->fetchUserRecord($this->login['uname']); } if (is_array($user)) { static::getLogger()->debug(sprintf('User found: "%s"', $this->login['uname'])); } $this->cleanUpExtbaseDataMapper(); return $user; }
/** * Updates a BE/FE group in the database and returns a success flag. * * @param string $table Either 'be_groups' or 'fe_groups' * @param array $data * @return bool TRUE on success, otherwise FALSE * @throws InvalidUserGroupTableException */ public static function update($table, array $data = array()) { if (!GeneralUtility::inList('be_groups,fe_groups', $table)) { throw new InvalidUserGroupTableException('Invalid table "' . $table . '"', 1404891867); } $databaseConnection = static::getDatabaseConnection(); $databaseConnection->exec_UPDATEquery($table, 'uid=' . intval($data['uid']), $data, FALSE); $success = $databaseConnection->sql_errno() == 0; if ($success) { NotificationUtility::dispatch(__CLASS__, 'groupUpdated', array('table' => $table, 'group' => $data)); } return $success; }