/**
  * Injects several fields into specific forms.
  *
  * @param   JForm  $form  The form to be altered.
  * @param   array  $data  The associated data for the form.
  *
  * @return  boolean
  *
  * @since   2.0
  */
 public function onContentPrepareForm($form, $data)
 {
     // Check we are manipulating a valid form
     if (!$form instanceof JForm) {
         $this->_subject->setError('JERROR_NOT_A_FORM');
         return false;
     }
     // Check if the password field needs injecting
     if ($this->params->get('use_ldap_password', false) && in_array($form->getName(), $this->passwordForms)) {
         // Check if this user should have a profile
         if (SHLdapHelper::isUserLdap(isset($data->id) ? $data->id : 0)) {
             if ($this->params->get('ldap_password_layout_edit', true)) {
                 // Check if this is in the 'edit' layout or in the save state
                 if (strtolower(JFactory::getApplication()->input->get('layout')) === 'edit' || strtolower(JFactory::getApplication()->input->get('task')) === 'save') {
                     $form->loadFile(realpath(__DIR__) . '/forms/ldap_password.xml', false, false);
                 }
             } else {
                 $form->loadFile(realpath(__DIR__) . '/forms/ldap_password.xml', false, false);
             }
         }
     }
     // Check if the domain field needs injecting
     if ($this->params->get('use_ldap_domain', false) && in_array($form->getName(), $this->domainForms)) {
         $form->loadFile(realpath(__DIR__) . '/forms/ldap_domain.xml', false, false);
     }
     return true;
 }
Beispiel #2
0
 /**
  * Gets the IP address of the client machine, translates it to a compatiable
  * eDirectory netadress and queries it against the LDAP server using a filter.
  *
  * @return  mixed  Username of detected user or False.
  *
  * @since   1.0
  */
 public function detectRemoteUser()
 {
     // Import languages for frontend errors
     $this->loadLanguage();
     /*
      * When legacy flag is true, it ensures compatibility with JSSOMySite 1.x by
      * only returning a string username or false can be returned. This also means
      * keeping compatibility with Joomla 1.6.
      * When it is set to False, it can return an array and compatible with Joomla 2.5.
      */
     $legacy = $this->params->get('use_legacy', false);
     if ($legacy) {
         // Use legacy way of getting paramters
         $authParams = new JRegistry();
         $authName = $this->params->get('auth_plugin', 'jmapmyldap');
         $authPlugin = JPluginHelper::getPlugin('authentication', $authName);
         $authParams->loadString($authPlugin->params);
         $ldapUid = $authParams->get('ldap_uid', 'uid');
         // Attempt to load up a LDAP instance using the legacy method
         jimport('shmanic.jldap2');
         $ldap = new JLDAP2($authParams);
         // Lets try to bind using proxy user
         if (!$ldap->connect() || !$ldap->bind($ldap->connect_username, $ldap->connect_password)) {
             JError::raiseWarning('SOME_ERROR_CODE', JText::_('PLG_EDIR_ERROR_LDAP_BIND'));
             return;
         }
         // Get IP of client machine
         $myip = JRequest::getVar('REMOTE_ADDR', 0, 'server');
         // Convert this to some net address thing that edir likes
         $na = JLDAPHelper::ipToNetAddress($myip);
         // Find the network address and return the uid for it
         $filter = "(networkAddress={$na})";
         $dn = $authParams->get('base_dn');
         // Do the LDAP filter search now
         $result = new JLDAPResult($ldap->search($dn, $filter, array($ldapUid)));
         $ldap->close();
     } else {
         try {
             // We will only check the first LDAP config
             $ldap = SHLdap::getInstance();
             $ldap->proxyBind();
             $ldapUid = $ldap->getUid;
             // Get the IP address of this client and convert to netaddress for LDAP searching
             $input = new JInput($_SERVER);
             $myIp = $input->get('REMOTE_ADDR', false, 'string');
             $na = SHLdapHelper::ipToNetAddress($myIp);
             $result = $ldap->search(null, "(networkAddress={$na})", array($ldapUid));
         } catch (Exception $e) {
             SHLog::add($e, 16010, JLog::ERROR, 'sso');
             return;
         }
     }
     if ($value = $result->getValue(0, $ldapuid, 0)) {
         // Username was found logged in on this client machine
         return $value;
     }
 }
Beispiel #3
0
 /**
  * Gets all the LDAP configurations.
  *
  * @return  array  Array of objects containing LDAP config information.
  *
  * @since   2.0
  */
 public function getItems()
 {
     $store = $this->getStoreId();
     // Try to load the data from internal storage.
     if (isset($this->cache[$store])) {
         return $this->cache[$store];
     }
     $config = SHFactory::getConfig();
     // Config managed default domain
     $default = $config->get('ldap.defaultconfig');
     // Config managed LDAP host source
     $source = (int) $config->get('ldap.config', SHLdapHelper::CONFIG_SQL);
     if ($source === SHLdapHelper::CONFIG_SQL) {
         parent::getItems();
         foreach ($this->cache[$store] as $row) {
             /*
              * We need to mark the LDAP hosts that is default.
              */
             $row->default = $row->name == $default ? true : false;
             /*
              * Count the ID number of users in each LDAP host.
              */
             $row->users = $this->getCountDomain($row->id, $row->name);
             /*
              * Decode the paramters to get the host and port
              */
             $decode = json_decode($row->params);
             $row->host = $decode->host;
             $row->port = $decode->port;
         }
     } else {
         try {
             // Get all the Ldap config IDs and Names
             $ids = SHLdapHelper::getConfigIDs();
             $this->cache[$store] = array();
             foreach ($ids as $id => $name) {
                 // Get this specific Ldap configuration based on name
                 $config = SHLdapHelper::getConfig($name);
                 $result = new stdClass();
                 $result->id = $id;
                 $result->name = $name;
                 $result->host = $config->get('host');
                 $result->port = $config->get('port');
                 $result->users = $this->getCountDomain($result->id, $result->name);
                 // Lets add this config to our results pool
                 $this->cache[$store][] = $result;
             }
         } catch (Exception $e) {
             // We need to look for a string instead of an array on error
             return $e->getMessage();
         }
     }
     return $this->cache[$store];
 }
 /**
  * Method to get the Ldap domains field options.
  *
  * @return  array  The field option objects.
  *
  * @since   2.0
  */
 protected function getOptions()
 {
     // Initialize variables.
     $options = array();
     // Get the Ldap Domains
     $configs = SHLdapHelper::getConfigIDs();
     // Present the Ldap domains in the list
     foreach ($configs as $id => $config) {
         $options[] = JHtml::_('select.option', $config, $config, 'value', 'text');
     }
     // Merge any additional options in the XML definition.
     $options = array_merge(parent::getOptions(), $options);
     return $options;
 }
 public function testConfigInvalidSource()
 {
     $this->setExpectedException('InvalidArgumentException', 'LIB_SHLDAPHELPER_ERR_10601', 10601);
     // Change it to a invalid LDAP config source
     $platform = SHFactory::getConfig('file', array('file' => static::PLATFORM_CONFIG_FILE, 'namespace' => 'single'));
     $platform->set('ldap.config', 84);
     SHLdapHelper::getConfig(null, $platform);
 }
Beispiel #6
0
	/**
	 * Loads the profile XML and passes it to the form to load the fields (excluding data).
	 *
	 * @param   JForm  $form  The form to be altered.
	 * @param   array  $data  The associated data for the form.
	 *
	 * @return  boolean
	 *
	 * @since   2.0
	 */
	public function onContentPrepareForm($form, $data)
	{
		// Check if the profile parameter is enabled
		if (!$this->use_profile)
		{
			return true;
		}

		if (!($form instanceof JForm))
		{
			$this->_subject->setError('JERROR_NOT_A_FORM');

			return false;
		}

		// Check we are manipulating a valid form
		if (!in_array($form->getName(), $this->permittedForms))
		{
			return true;
		}

		$showForm = true;
		$domain = null;

		// Check if this user should have a profile
		if ($userId = isset($data->id) ? $data->id : 0)
		{
			if (SHLdapHelper::isUserLdap($userId))
			{
				$domain = SHUserHelper::getDomainParam($data);
			}
			else
			{
				$showForm = false;
			}
		}
		elseif (!JFactory::getUser()->guest)
		{
			/*
			 * Sometimes the $data variable is not populated even when an edit is required.
			 * This means we have to check the form post data directly for the user ID.
			 * We do not worry about frontend registrations as we check for guest.
			 * If there is no form posted then this could be a backend registration.
			 */
			if ($inForm = JFactory::getApplication()->input->get('jform', false, 'array'))
			{
				$id = SHUtilArrayhelper::getValue($inForm, 'id', 0, 'int');

				if ($id === 0)
				{
					// Ask all plugins if there is a plugin willing to deal with user creation for ldap
					if (count($results = SHFactory::getDispatcher('ldap')->trigger('askUserCreation')))
					{
						// Due to being unaware of the domain for this new user, we are forced to use the default domain
						$domain = SHFactory::getConfig()->get('ldap.defaultconfig');
					}
					else
					{
						// LDAP creation not enabled
						$showForm = false;
					}
				}
				else
				{
					if (SHLdapHelper::isUserLdap($id))
					{
						// Existing ldap user
						$domain = SHUserHelper::getDomainParam($id);
					}
					else
					{
						// Existing non-ldap user
						$showForm = false;
					}
				}
			}
		}

		if ($showForm)
		{
			// We have to launch the getxmlfields to correctly include languages
			$this->getXMLFields($domain);

			// Get the File and Path for the Profile XML
			$file 		= $this->getXMLFileName($domain);
			$xmlPath 	= $this->profile_base . '/' . $file . '.xml';

			// Load in the profile XML file to the form
			if (($xml = JFactory::getXML($xmlPath, true)) && ($form->load($xml, false, false)))
			{
				// Successfully loaded in the XML
				return true;
			}
		}
	}
Beispiel #7
0
 /**
  * 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);
 }
 public function testConfigSqlStringInvalid()
 {
     $this->setExpectedException('InvalidArgumentException', 'LIB_SHLDAPHELPER_ERR_10606', 10606);
     $config = SHLdapHelper::getConfig('notexist');
 }
 /**
  * Entry point for the script.
  *
  * @return  void
  *
  * @since   2.0
  */
 public function doExecute()
 {
     // Setup some stats
     $failed = 0;
     $success = 0;
     $errors = array();
     // It appears we have to tell the system we are running with the site otherwise bad things happen
     JFactory::getApplication('site');
     $this->out(JText::_('CLI_SHMANIC_LDAP_INFO_13001'));
     // Get all the valid configurations
     if (!($configs = SHLdapHelper::getConfig())) {
         // Failed to find any Ldap configs
         $this->out(JText::_('CLI_SHMANIC_LDAP_ERR_13003'));
         $this->close(1);
     }
     // Check if only a single config was found
     if ($configs instanceof JRegistry) {
         /*
          * To make things easier, we pretend we returned multiple Ldap configs
          * by casting the single entry into an array.
          */
         $configs = array($configs);
     }
     $count = count($configs);
     $this->out(JText::sprintf('CLI_SHMANIC_LDAP_INFO_13002', $count))->out();
     // Loop around each LDAP configuration
     foreach ($configs as $config) {
         try {
             // Get a new Ldap object
             $ldap = new SHLdap($config);
             // Bind with the proxy user
             if (!$ldap->authenticate(SHLdap::AUTH_PROXY)) {
                 // Something is wrong with this LDAP configuration - cannot bind to proxy user
                 $errors[] = new Exception(JText::sprintf('CLI_SHMANIC_LDAP_ERR_13011', $ldap->info), 13011);
                 unset($ldap);
                 continue;
             }
             // Get all the Ldap users in the directory
             if (!($result = $ldap->search(null, $ldap->allUserFilter, array('dn', $ldap->keyUid)))) {
                 // Failed to search for all users in the directory
                 $errors[] = new Exception(JText::sprintf('CLI_SHMANIC_LDAP_ERR_13012', $ldap->getErrorMsg()), 13012);
                 unset($ldap);
                 continue;
             }
             // Loop around each Ldap user
             for ($i = 0; $i < $result->countEntries(); ++$i) {
                 // Get the Ldap username (case insensitive)
                 if (!($username = strtolower($result->getValue($i, $ldap->keyUid, 0)))) {
                     continue;
                 }
                 try {
                     // Check if this user is in the blacklist
                     if ($blacklist = (array) json_decode(SHFactory::getConfig()->get('user.blacklist'))) {
                         if (in_array($username, $blacklist)) {
                             throw new RuntimeException(JText::_('CLI_SHMANIC_LDAP_ERR_13025'), 13025);
                         }
                     }
                     // Create the new user adapter
                     $adapter = new SHUserAdaptersLdap(array('username' => $username), $config);
                     // Get the Ldap DN
                     if (!($dn = $adapter->getId(false))) {
                         continue;
                     }
                     $this->out(JText::sprintf('CLI_SHMANIC_LDAP_INFO_13020', $username));
                     // Get the Ldap user attributes
                     $source = $adapter->getAttributes();
                     // Get the core mandatory J! user fields
                     $username = $adapter->getUid();
                     $fullname = $adapter->getFullname();
                     $email = $adapter->getEmail();
                     if (empty($fullname)) {
                         // Full name doesnt exist; use the username instead
                         $fullname = $username;
                     }
                     if (empty($email)) {
                         // Email doesnt exist; cannot proceed
                         throw new Exception(JText::_('CLI_SHMANIC_LDAP_ERR_13022'), 13022);
                     }
                     // Create the user array to enable creating a JUser object
                     $user = array('fullname' => $fullname, 'username' => $username, 'password_clear' => null, 'email' => $email);
                     // Create a JUser object from the Ldap user
                     $options = array('adapter' => &$adapter);
                     $instance = SHUserHelper::getUser($user, $options);
                     if ($instance === false) {
                         // Failed to get the user either due to save error or autoregister
                         throw new Exception(JText::_('CLI_SHMANIC_LDAP_ERR_13024'), 13024);
                     }
                     // Fire the Ldap specific on Sync feature
                     $sync = SHLdapHelper::triggerEvent('onLdapSync', array(&$instance, $options));
                     // Check if the synchronise was successfully and report
                     if ($sync !== false) {
                         // Even if the sync does not need a save, do it anyway as Cron efficiency doesnt matter too much
                         SHUserHelper::save($instance);
                         // Update the user map linker
                         SHAdapterMap::setUser($adapter, $instance->id);
                         // Above should throw an exception on error so therefore we can report success
                         $this->out(JText::sprintf('CLI_SHMANIC_LDAP_INFO_13029', $username));
                         ++$success;
                     } else {
                         throw new Exception(JText::_('CLI_SHMANIC_LDAP_ERR_13026'), 13026);
                     }
                     unset($adapter);
                 } catch (Exception $e) {
                     unset($adapter);
                     ++$failed;
                     $errors[] = new Exception(JText::sprintf('CLI_SHMANIC_LDAP_ERR_13028', $username, $e->getMessage()), $e->getCode());
                 }
             }
         } catch (Exception $e) {
             $errors[] = new Exception(JText::_('CLI_SHMANIC_LDAP_ERR_13004'), 13004);
         }
     }
     // Print out some results and stats
     $this->out()->out()->out(JText::_('CLI_SHMANIC_LDAP_INFO_13032'))->out();
     $this->out(JText::_('CLI_SHMANIC_LDAP_INFO_13038'));
     foreach ($errors as $error) {
         if ($error instanceof Exception) {
             $this->out(' ' . $error->getCode() . ': ' . $error->getMessage());
         } else {
             $this->out(' ' . (string) $error);
         }
     }
     $this->out()->out(JText::sprintf('CLI_SHMANIC_LDAP_INFO_13034', $success));
     $this->out(JText::sprintf('CLI_SHMANIC_LDAP_INFO_13036', $failed));
     $this->out()->out('============================');
 }
Beispiel #10
0
 /**
  * Gets all the LDAP configs and attempts to bind with each.
  * This is presented on the dashboard.
  *
  * @return  array  Array of objects containing LDAP config information.
  *
  * @since   2.0
  */
 public function getBinds()
 {
     try {
         $results = array();
         // Get all the Ldap config IDs and Names
         $ids = SHLdapHelper::getConfigIDs();
         foreach ($ids as $name) {
             // Get this specific Ldap configuration based on name
             $config = SHLdapHelper::getConfig($name);
             $result = new stdClass();
             $result->name = $name;
             $result->host = $config->get('host');
             $result->port = $config->get('port');
             $result->connect = false;
             $ldap = new SHLdap($config);
             // Need to process the ldap formatting for the host configuration ready for a fsockopen
             $processed = str_replace(array('ldap://', 'ldaps://'), '', $config->get('host'));
             if ($pos = strpos($processed, chr(32))) {
                 $processed = substr($processed, 0, $pos);
             }
             // Check if we can open a socket to the LDAP server:port to check the connection
             if (@fsockopen($processed, $config->get('port'))) {
                 $result->connect = true;
             }
             // Attempt to connect and bind and record the result
             if ($ldap->connect()) {
                 if ($ldap->proxyBind()) {
                     $result->bind = true;
                 }
             }
             // Lets add this config to our results pool
             $results[] = $result;
         }
         return $results;
     } catch (Exception $e) {
         // We need to look for a string instead of an array on error
         return $e->getMessage();
     }
 }
Beispiel #11
0
	/**
	 * Get a user's distinguished name by attempting to replace the username keyword
	 * in the query. Supports multiple distinguished names in a list.
	 *
	 * @param   string  $username  Authenticating username.
	 *
	 * @return  array  An array containing distinguished names.
	 *
	 * @since   1.0
	 * @throws  InvalidArgumentException  Invalid argument in config related error
	 */
	public function getUserDnDirectly($username)
	{
		$return = array();

		// Fixes special usernames and provides protection against distinguished name injection
		$username = SHLdapHelper::escape($username, true);

		// Replace the username placeholder with the authenticating username
		$search = str_replace(self::USERNAME_REPLACE, $username, $this->user_qry);

		// Splits each of the distinguished names into indivdual elements
		$DNs = explode(';', $search);

		// We need to find the correct distinguished name from the set of elements
		foreach ($DNs as $dn)
		{
			// Remove whitespacing from the distinguished name and check there is a length > 1
			if ($dn = trim($dn))
			{
				$return[] = $dn;
			}
		}

		return $return;
	}
Beispiel #12
0
 /**
  * Get an array of all the nested groups through the use of group recursion.
  * This is required usually only for Active Directory, however there could
  * be other LDAP platforms that cannot pick up nested groups.
  *
  * @param   shldap  &$ldap           Reference to the LDAP object.
  * @param   array   $searchDNs       Initial user groups (or ones that have already been discovered).
  * @param   string  $depth           How far to search down until it should give up (0 means unlimited).
  * @param   array   &$result         Holds the result of every alliteration (by reference).
  * @param   string  $attribute       The LDAP attribute to store after each ldap search.
  * @param   string  $queryAttribute  The LDAP filter attribute to query.
  *
  * @return  array  All user groups including the initial user groups.
  *
  * @since   1.0
  * @throws  SHLdapException
  */
 public static function getRecursiveGroups(SHLdap &$ldap, $searchDNs, $depth, &$result, $attribute, $queryAttribute = null)
 {
     $search = null;
     $next = array();
     $filters = array();
     // As this is recursive, we want to be able to specify a optional depth
     --$depth;
     if (!isset($searchDNs)) {
         return $result;
     }
     foreach ($searchDNs as $dn) {
         // Build one or more partial filters from the DN user groups
         $filters[] = $queryAttribute . '=' . $dn;
     }
     if (!count($filters)) {
         // If there is no filter to process then we are finished
         return $result;
     }
     // Build the full filter using the OR operator
     $search = SHLdapHelper::buildFilter($filters, '|');
     // Search for any groups that also contain the groups we have in the filter
     $results = $ldap->search(null, $search, array($attribute));
     // Lets process each group that was found
     $entryCount = $results->countEntries();
     for ($i = 0; $i < $entryCount; ++$i) {
         $dn = $results->getDN($i);
         // We don't want to re-process a group that was processed previously
         if (!in_array($dn, $result)) {
             $result[] = $dn;
             // Check if there are more groups we should process from the groups just discovered
             $valueCount = $results->countValues($i, $attribute);
             for ($j = 0; $j < $valueCount; ++$j) {
                 // We want to process this object
                 $value = $results->getValue($i, $attribute, $j);
                 $next[] = $value;
             }
         }
     }
     /*
      * Only start the recursion when we have something to process next
      * otherwise, we would loop forever.
      */
     if (count($next) && $depth != 0) {
         self::getRecursiveGroups($ldap, $next, $depth, $result, $attribute, $queryAttribute);
     }
     return $result;
 }
Beispiel #13
0
	/**
	 * Return specified user attributes from LDAP.
	 *
	 * @param   string|array  $input    Optional string or array of attributes to return.
	 * @param   boolean       $null     Include null or non existent values.
	 * @param   boolean       $changes  Use the attribute changes (before change commit).
	 *
	 * @return  mixed  Ldap attribute results.
	 *
	 * @since   2.0
	 * @throws  SHLdapException
	 */
	public function getAttributes($input = null, $null = false, $changes = false)
	{
		if (is_null($this->_dn))
		{
			$this->getId(false);
		}
		elseif ($this->_dn instanceof Exception)
		{
			// Do not retry. Ldap configuration or user has problems.
			throw $this->_dn;
		}

		$needToFind = array();
		$inputFilled = array();

		if (!is_null($input))
		{
			// Have to make sure that unless its null then its in an array
			$input = is_string($input) ? array($input) : $input;

			$inputFilled = array_fill_keys($input, null);

			// This array is what we must find (i.e. not in the cached variable)
			$needToFind = (array_keys(array_diff_key($inputFilled, $this->_attributes)));

			/*
			 * Combines the current cached attributes with the input attributes with null values.
			 * This will stop the input values from being re-queried on another method call even
			 * if they don't exist.
			 */
			$this->_attributes = (array_merge($inputFilled, $this->_attributes));
		}

		/*
		 * We use the "plugin get attributes" method for efficiency purposes. On the
		 * first execution of this method, we attempt to gather Ldap user attributes
		 * that are required from this call in addition to what the Ldap plugins require.
		 *
		 * This means we should only have to call for the user attributes once from Ldap.
		 */
		if ($this->_usePlugins)
		{
			// Only run the sequence once
			$this->_usePlugins = false;

			/*
			 * -- Get the Ldap user attributes via plugins --
			 * This section will get an array of user detail attributes for the user
			 * using Ldap plugins to help with discovery of required Ldap attributes.
			 */
			$extras = SHFactory::getDispatcher('ldap')->trigger(
				'onLdapBeforeRead', array(&$this, array('dn' => $this->_dn, 'source' => __METHOD__))
			);

			// For each of the LDAP plug-ins returned, merge their extra attributes.
			foreach ($extras as $extra)
			{
				$needToFind = array_merge($needToFind, $extra);
			}

			// Add both of the uid and fullname to the set of attributes to get.
			$needToFind[] = $this->client->ldap_fullname;
			$needToFind[] = $this->client->ldap_uid;

			// Check for a fake email
			$fakeEmail = (strpos($this->client->ldap_email, (SHLdap::USERNAME_REPLACE)) !== false) ? true : false;

			// Add the email attribute only if not a fake email is supplied.
			if (!$fakeEmail)
			{
				$needToFind[] = $this->client->ldap_email;
			}

			// Re-order array to ensure an LDAP read is successful and no duplicates exist.
			$needToFind = array_values(array_unique($needToFind));

			// Swap the attribute names to array keys ready for the result
			$filled = array_fill_keys($needToFind, null);

			/*
			 * Combines the current cached attributes with the input attributes with null values.
			 * This will stop the input values from being re-queried on another method call even
			 * if they don't exist.
			 */
			$this->_attributes = (array_merge($filled, $this->_attributes));

			// Get Ldap user attributes
			$result	= $this->client->read($this->_dn, null, $needToFind);

			if ($result->countEntries())
			{
				// Merge the extra attributes to the cache ready for returning
				$this->_attributes = array_replace($this->_attributes, array_intersect_key($result->getEntry(0), $this->_attributes));
			}

			/*
			 * Save any attributes that weren't found in Ldap and then make it unique
			 * so theres no duplicates in the null attributes list.
			 */
			$unreturnedVals = array_diff($needToFind, array_keys($result->getEntry(0, array())));
			$this->_nullAttributes = array_merge(array_diff($unreturnedVals, $this->_nullAttributes), $this->_nullAttributes);

			if ($fakeEmail)
			{
				// Inject the fake email by replacing the username placeholder with the username from ldap
				$email = str_replace(SHLdap::USERNAME_REPLACE, $this->_attributes[$this->client->ldap_uid][0], $this->client->ldap_email);
				$this->_attributes[$this->client->ldap_email] = array($email);

				// As the last instruction from the fakeEmail condition added email to null, lets remove it
				if (($index = array_search($this->client->ldap_email, $this->_nullAttributes)) !== false)
				{
					unset ($this->_nullAttributes[$index]);
				}
			}

			if (SHLdapHelper::triggerEvent(
				'onLdapAfterRead', array(&$this, &$this->_attributes, array('dn' => $this->_dn, 'source' => __METHOD__))
			) === false)
			{
				// Cancelled login due to plug-in
				throw new RuntimeException(JText::_('LIB_SHUSERADAPTERSLDAP_ERR_10912'), 10912);
			}

			// Blank need to find as there isn't anything more need finding
			$needToFind = array();
		}

		// Check if extra attributes are required
		if (count($needToFind))
		{
			$result = $this->client->read($this->_dn, null, $needToFind);

			if ($result->countEntries())
			{
				// Merge the extra attributes to the cache ready for returning
				$this->_attributes = array_replace($this->_attributes, array_intersect_key($result->getEntry(0), $this->_attributes));
			}

			/*
			 * Save any attributes that weren't found in Ldap and then make it unique
			 * so theres no duplicates in the null attributes list.
			 */
			$unreturnedVals = array_diff($needToFind, array_keys($result->getEntry(0, array())));
			$this->_nullAttributes = array_merge(array_diff($unreturnedVals, $this->_nullAttributes), $this->_nullAttributes);
		}
		else
		{
			// If there are no attributes then get them all from LDAP
			if (!count($this->_attributes))
			{
				$this->_attributes = $this->client->read($this->_dn, null)->getEntry(0, array());
			}
		}

		$return = $this->_attributes;

		// Remove null values from the attributes if we dont want them
		if (!$null)
		{
			$return = array_diff_key($this->_attributes, array_flip($this->_nullAttributes));
			$inputFilled = array_diff_key($inputFilled, array_flip($this->_nullAttributes));
		}

		// Include staged changes to the attributes
		$return = $changes ? array_merge($return, $this->_changes) : $return;

		// Returns only the specified inputs unless all attributes are wanted
		return is_null($input) ? $return : array_replace($inputFilled, array_intersect_key($return, $inputFilled));
	}
Beispiel #14
0
	/**
	 * Method is called on user login failure.
	 *
	 * @param   array  $response  The authentication response.
	 *
	 * @return  void
	 *
	 * @since   2.0
	 */
	public function onUserLoginFailure($response)
	{
		// Check if the attempted login was an Ldap user, if so then fire the event
		if ($username = SHUtilArrayhelper::getValue($response, 'username', false, 'string'))
		{
			// Check if the user exists in the J! database
			if ($id = JUserHelper::getUserId($username))
			{
				if (SHLdapHelper::isUserLdap($id))
				{
					SHLdapHelper::triggerEvent('onUserLoginFailure', array($response));
				}
			}
		}
	}
Beispiel #15
0
 /**
  * Returns the distinguished name.
  *
  * @param   array  $form  Registration form.
  *
  * @return  string  Distinguished name.
  *
  * @since   2.0
  */
 public function getMandatoryDN($form)
 {
     $name = SHLdapHelper::escape($form['name'], true);
     return "CN={$name},OU=People,DC=shmanic,DC=net";
 }
Beispiel #16
0
	/**
	 * Create the user to LDAP (before onUserBeforeSave).
	 *
	 * @param   array  $user  Populated LDAP attributes from the form.
	 *
	 * @return  boolean  Cancels the user creation to Joomla if False.
	 *
	 * @since   2.0
	 */
	public function onUserCreation($user)
	{
		try
		{
			$dn = null;
			$attributes = array();

			// Populate defaults for the mandatory
			$mandatory = array(
				'username' => SHUtilArrayhelper::getValue($user, 'username'),
				'password' => SHUtilArrayhelper::getValue($user, 'password_clear'),
				'email' => SHUtilArrayhelper::getValue($user, 'email'),
				'name' => SHUtilArrayhelper::getValue($user, 'name')
			);

			// Include the helper file only if it exists
			if ($this->helper = $this->_getHelperFile())
			{
				// Calculate the correct domain to insert user on
				if (method_exists($this->helper, 'getDomain'))
				{
					$this->domain = $this->helper->getDomain($user);
				}
			}

			$fields = $this->_getXMLFields();

			// Loops around everything in the template XML
			foreach ($fields as $key => $value)
			{
				// Convert the value to a string
				$stringValue = (string) $value;

				// Convert the key to a string
				$stringKey = (string) $key;

				$name = (string) $value->attributes()->name;

				if ($stringKey == 'dn')
				{
					$name = 'mandatory' . $stringKey;

					// The dn which isn't an array
					$attribute =& $dn;
				}
				elseif ($stringKey == 'username' || $stringKey == 'password' || $stringKey == 'email' || $stringKey == 'name')
				{
					$name = 'mandatory' . $stringKey;

					// The mandatory fields use something a bit different
					$attribute =& $mandatory[$stringKey];
				}
				else
				{
					// Standard multi-array attributes
					if (!isset($attributes[$name]))
					{
						$attributes[$name] = array();
					}

					$attribute =& $attributes[$name][];
				}

				// Get the value of the attributes using a variety of types
				switch ((string) $value->attributes()->type)
				{
					case 'form':
						$attribute = $user[$stringValue];
						break;

					case 'string':
						$attribute = $stringValue;
						break;

					case 'eval':
						$attribute = $this->_execEval($stringValue, $user);
						break;

					case 'helper':
						$method = 'get' . (string) $name;
						$attribute = $this->helper->{$method}($user);
						break;
				}
			}

			$credentials = array(
				'username' => $mandatory['username'],
				'password' => $mandatory['password'],
				'domain' => $this->domain,
				'dn' => $dn
			);

			// Kill any previous adapters for this user (though this plugin should be ordered first!!)
			SHFactory::$adapters[strtolower($user['username'])] = null;

			// Create an adapter and save core attributes
			$adapter = SHFactory::getUserAdapter($credentials, 'ldap', array('isNew' => true));

			// Add core Joomla fields
			$adapter->setAttributes(
				array(
					'username' => $mandatory['username'],
					'password' => $mandatory['password'],
					'fullname' => $mandatory['name'],
					'email' => $mandatory['email']
				)
			);

			// Add extra fields based from the template xml
			$adapter->setAttributes($attributes);

			// Create the LDAP user now
			SHLdapHelper::commitChanges($adapter, true, true);
			SHLog::add(JText::sprintf('PLG_LDAP_CREATION_INFO_12821', $mandatory['username']), 12821, JLog::INFO, 'ldap');

			$this->username = $mandatory['username'];

			/*
			 * Call onAfterCreation method in the helper which can be used to run
			 * external scripts (such as creating home directories) and/or adding
			 * groups to the new user.
			 *
			 * This method will be passed:
			 * - $user        Values directly from the user registration form.
			 * - $attributes  The attributes passed to the LDAP server for creation.
			 * - $adapter     The user adapter object.
			 */
			if ($this->helper && method_exists($this->helper, 'onAfterCreation'))
			{
				$this->helper->onAfterCreation($user, $attributes, $adapter);
			}

			return true;
		}
		catch (Exception $e)
		{
			SHLog::add($e, 12802, JLog::ERROR, 'ldap');

			return false;
		}
	}
Beispiel #17
0
 /**
  * Returns the distinguished name.
  *
  * @param   array  $form  Registration form.
  *
  * @return  string  Distinguished name.
  *
  * @since   2.0
  */
 public function getMandatoryDN($form)
 {
     $username = SHLdapHelper::escape($form['username'], true);
     return "uid={$username},ou=People,dc=shmanic,dc=net";
 }