Exemplo n.º 1
0
 /**
  * Returns a LDAP user.
  *
  * @param string $dn
  * @return array
  */
 protected static function getLdapUser($dn = NULL)
 {
     // Restricting the list of returned attributes sometimes makes the ldap_search() method issue a PHP warning:
     //     Warning: ldap_search(): Array initialization wrong
     // so we just ask for every attribute ("TRUE" below)!
     if (TRUE || Configuration::hasExtendedMapping(static::$config['users']['mapping'])) {
         $attributes = array();
     } else {
         // Currently never called ever again due to the warning found sometimes (see above)
         $attributes = Configuration::getLdapAttributes(static::$config['users']['mapping']);
         if (strpos(static::$config['groups']['filter'], '{USERUID}') !== FALSE) {
             $attributes[] = 'uid';
             $attributes = array_unique($attributes);
         }
     }
     $users = Ldap::getInstance()->search($dn, str_replace('{USERNAME}', '*', static::$config['users']['filter']), $attributes);
     $user = is_array($users[0]) ? $users[0] : NULL;
     static::getLogger()->debug(sprintf('Retrieving LDAP user from DN "%s"', $dn), $user);
     return $user;
 }
Exemplo n.º 2
0
 /**
  * Returns groups associated to a given user (identified either by his DN or his uid attribute).
  *
  * @param string $baseDn
  * @param string $filter
  * @param string $userDn
  * @param string $userUid
  * @param array $attributes
  * @return array
  */
 public static function selectFromUser($baseDn, $filter = '', $userDn = '', $userUid = '', array $attributes = array())
 {
     $filter = str_replace('{USERDN}', Ldap::getInstance()->escapeDnForFilter($userDn), $filter);
     $filter = str_replace('{USERUID}', Ldap::getInstance()->escapeDnForFilter($userUid), $filter);
     $groups = Ldap::getInstance()->search($baseDn, $filter, $attributes);
     return $groups;
 }
Exemplo n.º 3
0
 /**
  * Returns TRUE is a previous call to @see fetchLdapUsers() returned
  * a partial result set.
  *
  * @return bool
  */
 public function hasMoreLdapUsers()
 {
     return Ldap::getInstance()->isPartialSearchResult();
 }
Exemplo n.º 4
0
 /**
  * Escapes a string for use in a LDAP filter statement.
  *
  * To find the groups of a user by filtering the groups where the
  * authenticated user is in the members list some characters
  * in the users distinguished name can make the filter expression
  * invalid.
  *
  * At the moment this problem was experienced with brackets which
  * are also used in the filter, e.g.:
  * (&(objectClass=group)(member={USERDN}))
  *
  * Additionally a single backslash (that is used for escaping special
  * characters like commas) needs to be escaped. E.g.:
  * CN=Lastname\, Firstname,DC=company,DC=tld needs to be escaped like:
  * CN=Lastname\\, Firstname,DC=company,DC=tld
  *
  * @param string $dn
  * @return string Escaped $dn
  * @deprecated since 3.0 will be removed in 3.2, use \Causal\IgLdapSsoAuth\Library\Ldap::getInstance()->escapeDnForFilter() instead
  */
 public static function escapeDnForFilter($dn)
 {
     return \Causal\IgLdapSsoAuth\Library\Ldap::getInstance()->escapeDnForFilter($dn);
 }
Exemplo n.º 5
0
 /**
  * Returns the LDAP user groups with information merged with local TYPO3 user groups.
  *
  * @param \Causal\IgLdapSsoAuth\Domain\Model\Configuration $configuration
  * @param string $mode
  * @return array
  */
 protected function getAvailableUserGroups(\Causal\IgLdapSsoAuth\Domain\Model\Configuration $configuration, $mode)
 {
     $userGroups = array();
     $config = $mode === 'be' ? Configuration::getBackendConfiguration() : Configuration::getFrontendConfiguration();
     $ldapGroups = array();
     if (!empty($config['groups']['basedn'])) {
         $filter = Configuration::replaceFilterMarkers($config['groups']['filter']);
         $attributes = Configuration::getLdapAttributes($config['groups']['mapping']);
         $ldapGroups = Ldap::getInstance()->search($config['groups']['basedn'], $filter, $attributes);
         unset($ldapGroups['count']);
     }
     // Populate an array of TYPO3 group records corresponding to the LDAP groups
     // If a given LDAP group has no associated group in TYPO3, a fresh record
     // will be created so that $ldapGroups[i] <=> $typo3Groups[i]
     $typo3GroupPid = Configuration::getPid($config['groups']['mapping']);
     $table = $mode === 'be' ? 'be_groups' : 'fe_groups';
     $typo3Groups = Authentication::getTypo3Groups($ldapGroups, $table, $typo3GroupPid);
     foreach ($ldapGroups as $index => $ldapGroup) {
         $userGroup = Authentication::merge($ldapGroup, $typo3Groups[$index], $config['groups']['mapping']);
         // Attempt to free memory by unsetting fields which are unused in the view
         $keepKeys = array('uid', 'pid', 'deleted', 'title', 'tx_igldapssoauth_dn');
         $keys = array_keys($userGroup);
         foreach ($keys as $key) {
             if (!in_array($key, $keepKeys)) {
                 unset($userGroup[$key]);
             }
         }
         $userGroups[] = $userGroup;
     }
     return $userGroups;
 }
Exemplo n.º 6
0
 /**
  * Performs the synchronization of LDAP users according to selected parameters.
  *
  * @return boolean Returns TRUE on successful execution, FALSE on error
  * @throws ImportUsersException
  */
 public function execute()
 {
     // Assemble a list of configuration and contexts for import
     /** @var \Causal\IgLdapSsoAuth\Domain\Repository\ConfigurationRepository $configurationRepository */
     $configurationRepository = GeneralUtility::makeInstance('Causal\\IgLdapSsoAuth\\Domain\\Repository\\ConfigurationRepository');
     if (empty($this->configuration)) {
         $ldapConfigurations = $configurationRepository->findAll();
     } else {
         $configuration = $configurationRepository->findByUid($this->configuration);
         $ldapConfigurations = array();
         if ($configuration !== NULL) {
             $ldapConfigurations[] = $configuration;
         }
     }
     if ($this->context === 'both') {
         $executionContexts = array('fe', 'be');
     } else {
         $executionContexts = array($this->context);
     }
     $mode = $this->getMode();
     // Start a database transaction with all our changes
     // Syntax is compatible with MySQL, Oracle, MSSQL and PostgreSQL
     $this->getDatabaseConnection()->sql_query('START TRANSACTION');
     // Loop on each configuration and context and import the related users
     $failures = 0;
     foreach ($ldapConfigurations as $configuration) {
         foreach ($executionContexts as $aContext) {
             /** @var \Causal\IgLdapSsoAuth\Utility\UserImportUtility $importUtility */
             $importUtility = GeneralUtility::makeInstance('Causal\\IgLdapSsoAuth\\Utility\\UserImportUtility', $configuration, $aContext);
             $config = $importUtility->getConfiguration();
             if (empty($config['users']['filter'])) {
                 // Current context is not configured for this LDAP configuration record
                 static::getLogger()->debug(sprintf('Configuration record %s is not configured for context "%s"', $configuration->getUid(), $aContext));
                 unset($importUtility);
                 continue;
             }
             // Start by connecting to the designated LDAP/AD server
             $success = Ldap::getInstance()->connect(Configuration::getLdapConfiguration());
             // Proceed with import if successful
             if (!$success) {
                 $failures++;
                 unset($importUtility);
                 continue;
             }
             $ldapUsers = $importUtility->fetchLdapUsers();
             // Consider that fetching no users from LDAP is an error
             if (count($ldapUsers) === 0) {
                 static::getLogger()->error(sprintf('No users (%s) found for configuration record %s', $aContext, $configuration->getUid()));
                 $failures++;
             } else {
                 // Disable or delete users, according to settings
                 if ($this->missingUsersHandling === 'disable') {
                     static::getLogger()->debug(sprintf('Disabling users (%s) for configuration record %s', $aContext, $configuration->getUid()));
                     $importUtility->disableUsers();
                 } elseif ($this->missingUsersHandling === 'delete') {
                     static::getLogger()->debug(sprintf('Deleting users (%s) for configuration record %s', $aContext, $configuration->getUid()));
                     $importUtility->deleteUsers();
                 }
                 // Proceed with import (handle partial result sets until every LDAP record has been returned)
                 do {
                     $typo3Users = $importUtility->fetchTypo3Users($ldapUsers);
                     // Loop on all users and import them
                     foreach ($ldapUsers as $index => $aUser) {
                         if ($mode === 'sync' && empty($typo3Users[$index]['uid'])) {
                             // New LDAP user => skip it since only existing TYPO3 users should get synchronized
                             continue;
                         }
                         // Merge LDAP and TYPO3 information
                         $user = Authentication::merge($aUser, $typo3Users[$index], $config['users']['mapping']);
                         // Import the user using information from LDAP
                         $importUtility->import($user, $aUser, $this->restoredUsersHandling);
                     }
                     static::getLogger()->info(sprintf('Configuration record %s: processed %s LDAP users (%s)', $configuration->getUid(), count($ldapUsers), $aContext));
                     // Free memory before going on
                     $typo3Users = NULL;
                     $ldapUsers = NULL;
                     $ldapUsers = $importUtility->hasMoreLdapUsers() ? $importUtility->fetchLdapUsers(TRUE) : array();
                 } while (count($ldapUsers) > 0);
             }
             // Clean up
             unset($importUtility);
             Ldap::getInstance()->disconnect();
         }
     }
     // If some failures were registered, rollback the whole transaction and report error
     if ($failures > 0) {
         $this->getDatabaseConnection()->sql_query('ROLLBACK');
         $message = 'Some or all imports failed. Synchronisation was aborted. Check your settings or your network connection';
         static::getLogger()->error($message);
         throw new ImportUsersException($message, 1410774015);
     } else {
         // Everything went fine, commit the changes
         $this->getDatabaseConnection()->sql_query('COMMIT');
     }
     return TRUE;
 }