/**
  * 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('============================');
 }
Exemple #2
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));
				}
			}
		}
	}
Exemple #3
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));
	}