/** * This method is similar to SHLdap::getInstance but also it stores * all instantiated SHLdap objects in a static variable for later use. * * @param integer|string $domain Optional domain or configuration record ID. * @param JRegistry $config Optional LDAP config (can also be single JRegistry without array). * @param JRegistry $registry Optional override for platform configuration registry. * * @return SHLdap[] An array of SHLdap objects. * * @since 2.1 * @throws InvalidArgumentException Invalid configurations */ public static function getLdapClient($domain = null, $config = array(), JRegistry $registry = null) { // Get the platform registry config from the factory $domain . d $registry = is_null($registry) ? self::getConfig() : $registry; $cache = JFactory::getCache('shldap', ''); $domain = is_null($domain) ? $domain : strtolower($domain); // Generate a unique hash for this configuration depending on the domain requested $domainHash = empty($domain) ? '' : $domain; if (!empty($domain)) { $hash = md5($domain . serialize($config) . serialize($registry)); if (isset(self::$ldap[$hash])) { return array(self::$ldap[$hash]); } // Reconstruct the LDAP configuration object from cache and ensure it is valid if ($cachedConfig = $cache->get($hash) && $cachedConfig instanceof SHLdap) { self::$ldap[$hash] = $cachedConfig; return array(self::$ldap[$hash]); } } else { $hash = md5('all_domains' . serialize($config) . serialize($registry)); if (isset(self::$ldap[$hash])) { $valid = true; $configs = array(); // Reconstruct all domains in order foreach (self::$ldap[$hash] as $hash) { if (isset(self::$ldap[$hash])) { $configs[] = self::$ldap[$hash]; } else { // One of the configs are invalid and therefore we must run everything again $valid = false; break; } if ($valid) { return $configs; } } } else { // Check if we have done a "all domain" LDAP config retrieve if (($cachedConfigs = $cache->get($hash)) && is_array($cachedConfigs)) { $valid = true; $configs = array(); foreach ($cachedConfigs as $configHash) { // Reconstruct the "all domain" configurations from cache and check they are valid if (($cachedConfig = $cache->get($configHash)) && $cachedConfig instanceof SHLdap) { $configs[] = $cachedConfig; } else { // One of the configs are invalid and therefore we must run everything again $valid = false; break; } } if ($valid) { return $configs; } } } } // Potentially we will need the original input config later $inputConfig = $config; if (empty($config)) { /* * Get all the Ldap configs that are enabled and available. An optional * domain is passed - when this is passed, only one config will be returned. */ $configs = SHLdapHelper::getConfig($domain, $registry); } else { // Use the specified config $configs = $config instanceof JRegistry ? $config : new JRegistry($config); } if (!empty($configs)) { // If only 1 config result, wrap around an array so we can use the same code $configs = $configs instanceof JRegistry ? array($configs) : $configs; // This will be all the LDAP clients that match the domain $clients = array(); // Store all the hashes that we generate for caching purposes $hashes = array(); // Loop around each of the Ldap configs until one authenticates foreach ($configs as $config) { // Validate the config from any registered listeners (this can also change the config) SHUtilValidate::getInstance()->validate($config); /* * We won't catch exceptions now as it will mean either ldap * extension missing OR a very bad problem with this LDAP configuraiton. */ $ldap = new SHLdap($config); $hash = md5(strtolower($ldap->domain) . serialize($inputConfig) . serialize($registry)); if (!isset(self::$ldap[$hash])) { // We want to store this client for potential use later on self::$ldap[$hash] = $ldap; // Lets cache the LDAP client for future use $cache->store(self::$ldap[$hash], $hash); } $hashes[] = $hash; $clients[] = self::$ldap[$hash]; unset($ldap); } if (count($clients)) { if (empty($domain)) { // Cache all domains in the correct order so we can use it for future use $hash = md5('all_domains' . serialize($inputConfig) . serialize($registry)); $cache->store($hashes, $hash); self::$ldap[$hash] = $hashes; } // Found some LDAP configs - lets return them return $clients; } } // No errors happened, but unable to find suitable LDAP config for the domain throw new InvalidArgumentException(JText::_('LIB_SHFACTORY_ERR_2131'), 2131); }
/** * Class constructor. * * @param array $credentials Ldap credentials to use for this object (this is not a proxy user). * @param mixed $config Ldap configuration options such as host, proxy user and core attributes. * @param array $options Extra options such as isNew. * * @since 2.0 */ public function __construct(array $credentials, $config = null, array $options = array()) { parent::__construct($credentials, $config, $options); // Register a callback for validating LDAP parameters SHUtilValidate::getInstance()->register(__CLASS__ . '::validate'); if (is_array($config) && count($config)) { // Check if Ldap plugins should be disabled when collecting attributes later if (isset($config['disable_use_of_plugins'])) { $this->_usePlugins = false; unset($config['disable_use_of_plugins']); } // Override the Ldap parameters with this later on $this->_config = $config; } // If the user is new then the user creation script needs to provide a dn for the new object if ($this->isNew) { $this->_dn = JArrayHelper::getValue($credentials, 'dn'); /* * If the Ldap parameter override has been set then directly instantiate * the Ldap library otherwise use pre-configured platform configurations * through the Ldap library. */ $client = SHFactory::getLdapClient($this->domain, $this->_config); $this->client = $client[0]; $this->client->connect(); $this->client->proxyBind(); // We need to check that this ldap client config has the required user based parameters $this->_userParams = (array) $this->client->userParams; // Check whether the user already exists if ($this->_checkUserExists()) { $this->state = self::STATE_EXISTS; throw new RuntimeException(JText::sprintf('LIB_SHUSERADAPTERSLDAP_ERR_10909', $this->username), 10909); } // Emulate dn as an attribute $this->_attributes['dn'] = array($this->_dn); $this->state = self::STATE_NEW; } }