Example #1
0
 /**
  * Commits the changes to the adapter and parses the result.
  * If any errors occurred then optionally log them and throw an exception.
  *
  * @param   SHAdapter  $adapter  Adapter.
  * @param   boolean    $log      Log any errors directly to SHLog.
  * @param   boolean    $throw    Throws an exception on error OR return array on error.
  *
  * @return  true|SHAdapterResponseCommits
  *
  * @since   2.1
  */
 public static function commitChanges($adapter, $log = false, $throw = true)
 {
     $results = $adapter->commitChanges();
     $adapterName = $adapter->getName();
     if ($log) {
         // Lets log all the commits
         foreach ($results->getCommits() as $commit) {
             if ($commit->status === JLog::INFO) {
                 SHLog::addAdapter($adapter, $commit->getSummary(), 10634, JLog::INFO);
             } else {
                 SHLog::addAdapter($adapter, $commit->getSummary(), 10636, JLog::ERROR);
                 SHLog::add($commit->exception, 10637, JLog::ERROR, $adapterName);
             }
         }
     }
     // Check if any of the commits failed
     if (!$results->status) {
         if ($throw) {
             throw new RuntimeException(JText::_('LIB_SHADAPTERHELPER_ERR_10638'), 10638);
         } else {
             return $results;
         }
     }
     return true;
 }
Example #2
0
 /**
  * Method is called before user data is stored in the database.
  *
  * Changes the password in LDAP if the user changed their password.
  *
  * @param   array    $user   Holds the old user data.
  * @param   boolean  $isNew  True if a new user is stored.
  * @param   array    $new    Holds the new user data.
  *
  * @return  boolean  Cancels the save if False.
  *
  * @since   2.0
  */
 public function onUserBeforeSave($user, $isNew, $new)
 {
     if ($isNew) {
         // We dont want to deal with new users here
         return;
     }
     // Get username and password to use for authenticating with Ldap
     $username = JArrayHelper::getValue($user, 'username', false, 'string');
     $password = JArrayHelper::getValue($new, 'password_clear', null, 'string');
     if (!empty($password)) {
         $auth = array('authenticate' => SHLdap::AUTH_USER, 'username' => $username, 'password' => $password);
         try {
             // We will double check the password for double safety (breaks password reset if on)
             $authenticate = $this->params->get('authenticate', 0);
             // Get the user adapter then set the password on it
             $adapter = SHFactory::getUserAdapter($auth);
             $adapter->setPassword($password, JArrayHelper::getValue($new, 'current-password', null, 'string'), $authenticate);
             SHLog::add(JText::sprintf('PLG_LDAP_PASSWORD_INFO_12411', $username), 12411, JLog::INFO, 'ldap');
         } catch (Exception $e) {
             // Log and Error out
             SHLog::add($e, 12401, JLog::ERROR, 'ldap');
             return false;
         }
     }
 }
Example #3
0
 /**
  * Deletes the user from LDAP if the deletion in the Joomla database was successful.
  *
  * Method is called after user data is deleted from the database.
  *
  * @param   array    $user     Holds the user data.
  * @param   boolean  $success  True if user was successfully deleted from the database.
  * @param   string   $msg      An error message.
  *
  * @return  void
  *
  * @since   2.0
  * @deprecated
  */
 public function onUserAfterDelete($user, $success, $msg)
 {
     if ($success) {
         try {
             $username = $user['username'];
             SHLog::add(JText::sprintf('PLG_LDAP_DELETION_DEBUG_12905', $username), 12905, JLog::DEBUG, 'ldap');
             // Pick up the user and delete it using the User Adapter
             $adapter = SHFactory::getUserAdapter($username);
             $adapter->delete();
             SHLog::add(JText::sprintf('PLG_LDAP_DELETION_INFO_12908', $username), 12908, JLog::INFO, 'ldap');
         } catch (Exception $e) {
             SHLog::add($e, 12901, JLog::ERROR, 'ldap');
         }
     }
 }
Example #4
0
 /**
  * Initialises and imports the Shmanic platform and project libraries.
  * This is fired on application initialise typically by the CMS.
  *
  * @return  void
  *
  * @since   2.0
  */
 public function onAfterInitialise()
 {
     // Check if the Shmanic platform has already been imported
     if (!defined('SHPATH_PLATFORM')) {
         $platform = JPATH_PLATFORM . '/shmanic/import.php';
         if (!file_exists($platform)) {
             // Failed to find the import file
             return false;
         }
         // Shmanic Platform import
         if (!(include_once $platform)) {
             // Failed to import the Shmanic platform
             return false;
         }
     }
     // Import the logging method
     SHLog::import($this->params->get('log_group', 'shlog'));
     // Container to store project specific import results
     $results = array();
     // Use the default SQL configuration
     $config = SHFactory::getConfig();
     // Get all the importable projects
     if ($imports = json_decode($config->get('platform.import'))) {
         foreach ($imports as $project) {
             // Attempts to import the specified project
             $results[] = shImport(trim($project));
         }
     }
     // Fire the onAfterInitialise for all the registered imports/projects
     JDispatcher::getInstance()->trigger('onSHPlaformInitialise');
     if (in_array(false, $results, true)) {
         // One of the specific projects failed to import
         return false;
     }
     // Everything imported successfully
     return true;
 }
Example #5
0
	/**
	 * Method is called after user data is stored in the database.
	 *
	 * Deletes the user if they're new and Joomla user creation failed.
	 *
	 * @param   array    $user     Holds the new user data.
	 * @param   boolean  $isNew    True if a new user has been stored.
	 * @param   boolean  $success  True if user was successfully stored in the database.
	 * @param   string   $msg      An error message.
	 *
	 * @return  void
	 *
	 * @since   2.0
	 */
	public function onUserAfterSave($user, $isNew, $success, $msg)
	{
		if ($isNew && !$success && $this->params->get('onfail_delete', false) && $this->username)
		{
			try
			{
				// Check the session to ensure this user was created successfully last time
				if (JFactory::getSession()->get('creation', null, 'ldap') == $this->username)
				{
					$adapter = SHFactory::getUserAdapter($this->username);
					$adapter->delete();
					SHLog::add(JTest::sprintf('PLG_LDAP_CREATION_INFO_12826', $this->username), 12826, JLog::INFO, 'ldap');
				}
			}
			catch (Exception $e)
			{
				SHLog::add($e, 12803, JLog::ERROR, 'ldap');
			}

			$this->username = null;
		}
	}
Example #6
0
	/**
	 * Method handles login logic and report back to the subject.
	 *
	 * @param   array  $user     Holds the user data.
	 * @param   array  $options  Extra options such as autoregister.
	 *
	 * @return  boolean  Cancels login on False.
	 *
	 * @since   2.0
	 */
	public function onUserLogin($user, $options = array())
	{
		// Check if we have a user adapter already established for this user
		if (!isset(SHFactory::$adapters[strtolower($user['username'])]))
		{
			// SHAdapter did not log this in, get out now
			return;
		}

		// Get the processed user adapter directly from the static adapter holder
		$adapter = SHFactory::$adapters[strtolower($user['username'])];

		if (!(isset($user['type']) && $adapter::getType($user['type']) && $adapter::getType('LDAP')))
		{
			// Incorrect authentication type for this adapter OR is not compatible with LDAP
			return;
		}

		// Lets pass the getUser method the adapter so it can get extra values
		$options['adapter'] = $adapter;

		try
		{
			// Get a handle to the Joomla User object ready to be passed to the individual plugins
			$instance = SHUserHelper::getUser($user, $options);
		}
		catch (Exception $e)
		{
			// Failed to get the user either due to save error or autoregister
			SHLog::add($e, 10991, JLog::ERROR, 'ldap');

			return false;
		}

		// Fire the ldap specific on login events
		$result = SHLdapHelper::triggerEvent('onUserLogin', array(&$instance, $options));

		if ($result === false)
		{
			// Due to Joomla's inbuilt User Plugin, we have to raise an exception to abort login
			throw new RuntimeException(JText::sprintf('LIB_SHLDAPEVENTBOUNCER_ERR_10999', $user['username']), 10999);
		}

		// Check if any changes were made that need to be saved
		if ($result === true || isset($options['change']))
		{
			SHLog::add(JText::sprintf('LIB_SHLDAPEVENTBOUNCER_DEBUG_10984', $user['username']), 10984, JLog::DEBUG, 'ldap');

			try
			{
				// Save the user back to the Joomla database
				if (!SHUserHelper::save($instance))
				{
					SHLog::add(JText::sprintf('LIB_SHLDAPEVENTBOUNCER_ERR_10988', $user['username']), 10988, JLog::ERROR, 'ldap');
				}
			}
			catch (Exception $e)
			{
				SHLog::add($e, 10989, JLog::ERROR, 'ldap');
			}
		}

		// Allow Ldap events to be called
		$this->isLdap = true;

		return true;
	}
Example #7
0
 /**
  * This method handles the user adapter authorisation and reports
  * back to the subject. This method is also used for single sign on.
  *
  * There is no custom logging in the authentication.
  *
  * @param   array  $response  Authentication response object from onUserAuthenticate()
  * @param   array  $options   Array of extra options
  *
  * @return  JAuthenticationResponse  Authentication response object
  *
  * @since   2.0
  */
 public function onUserAuthorisation($response, $options = array())
 {
     // Create a new authentication response
     $retResponse = new JAuthenticationResponse();
     // Check if some other authentication system is dealing with this request
     if (!empty($response->type) && strtoupper($response->type) !== self::AUTH_TYPE) {
         return $retResponse;
     }
     // Check the Shmanic platform has been imported
     if (!$this->_checkPlatform()) {
         // Failed to import the platform
         $response->status = JAuthentication::STATUS_FAILURE;
         $response->error_message = JText::_('PLG_AUTHENTICATION_SHADAPTER_ERR_12601');
         return false;
     }
     $response->type = self::AUTH_TYPE;
     /*
      * Attempt to authorise with User Adapter. This method will automatically detect
      * the correct configuration (if multiple ones are specified) and return a
      * SHUserAdapter object. If this method returns false, then the authorise was
      * unsuccessful - basically the user was not found or configuration was
      * bad.
      */
     try {
         // Setup user adapter injecting the domain from SSO if specified
         $credentials = array('username' => $response->username);
         if (isset($options['domain'])) {
             $credentials['domain'] = $options['domain'];
         }
         $adapter = SHFactory::getUserAdapter($credentials);
         // Get the authorising user dn
         $id = $adapter->getId(false);
     } catch (Exception $e) {
         // Configuration or authorisation failure
         $response->status = JAuthentication::STATUS_FAILURE;
         $response->error_message = JText::_('JGLOBAL_AUTH_NO_USER');
         return;
     }
     try {
         // Let's get the user attributes
         $attributes = $adapter->getAttributes();
         if (!is_array($attributes) || !count($attributes)) {
             // No attributes therefore error
             throw new Exception(JText::_('PLG_AUTHENTICATION_SHADAPTER_ERR_12611'), 12611);
         }
     } catch (Exception $e) {
         // Error getting user attributes.
         $response->status = JAuthentication::STATUS_FAILURE;
         $response->error_message = JText::_('PLG_AUTHENTICATION_SHADAPTER_ERR_12611');
         // Process a error log
         SHLog::add($e, 12622, JLog::ERROR, 'auth');
         return false;
     }
     // Set the required Joomla specific user fields with the returned User Adapter Attributes
     $response->username = $adapter->getUid();
     $response->fullname = $adapter->getFullname();
     $response->email = $adapter->getEmail();
     // The adapter type needs to be set before returning the response
     $response->type = $adapter->getType();
     if (SHFactory::getConfig()->get('user.nullpassword')) {
         // Do not store password in Joomla database
         $response->password_clear = '';
     }
     /*
      * Everything appears to be a success and therefore we shall log the user login
      * then report back to the subject.
      */
     SHLog::add(JText::sprintf('PLG_AUTHENTICATION_SHADAPTER_INFO_12612', $response->username), 12612, JLog::INFO, 'auth');
     $retResponse->status = JAuthentication::STATUS_SUCCESS;
     unset($adapter);
     return $retResponse;
 }
Example #8
0
	/**
	 * Save the users profile to the database.
	 *
	 * @param   integer        $userId    Joomla user ID to save.
	 * @param   string         $username  Joomla username to save.
	 * @param   SHUserAdapter  $adapter   User adapter of LDAP user.
	 * @param   array          $options   An optional set of options.
	 *
	 * @return  boolean  True on success
	 *
	 * @since   2.0
	 */
	protected function saveProfile($userId, $username, $adapter, $options = array())
	{
		$xml = $this->getXMLFields($adapter->getDomain());

		SHLog::add(JText::sprintf('PLG_LDAP_PROFILE_DEBUG_12221', $username), 12221, JLog::DEBUG, 'ldap');

		$addRecords		= array();
		$updateRecords 	= array();
		$deleteRecords	= array();

		$db = JFactory::getDBO();
		$query = $db->getQuery(true);

		// Lets get a list of current SQL entries
		if (is_null($current = $this->queryProfile($userId, true)))
		{
			return false;
		}

		/* We want to process each attribute in the XML
		* then find out if it exists in the LDAP directory.
		* If it does, then we compare that to the value
		* currently in the SQL database.
		*/
		$attributes = $this->getAttributes($xml);

		foreach ($attributes as $attribute)
		{
			// Lets check for a delimiter (this is the indicator that multiple values are supported)
			$delimiter = null;
			$xmlField = $xml->xpath("fieldset/field[@name='$attribute']");
			$value = null;

			if ($delimiter = (string) $xmlField[0]['delimiter'])
			{
				// These are potentially multiple values

				if (strToUpper($delimiter) == 'NEWLINE')
				{
					$delimiter = "\n";
				}

				$value = '';

				if ($v = $adapter->getAttributes($attribute))
				{
					if (is_array($v[$attribute]))
					{
						foreach ($v[$attribute] as $values)
						{
							$value .= $values . $delimiter;
						}
					}
				}
			}
			else
			{
				// These are single values
				if ($v = $adapter->getAttributes($attribute))
				{
					if (isset($v[$attribute][0]))
					{
						$value = $v[$attribute][0];
					}
				}
			}

			// Get the action status required against the SQL table
			$status = $this->checkSqlField($current, $attribute, $value);

			switch ($status)
			{
				case 1:
					$updateRecords[$attribute] = $value;
					break;

				case 2:
					$addRecords[$attribute] = $value;
					break;

				case 3:
					$deleteRecords[] = $attribute;
					break;
			}
		}

		/* Lets commit these differences to the database
		 * in steps (delete, add, update) and return the
		 * result.
		 */
		$results = array();

		if (count($deleteRecords))
		{
			$results[] = $this->deleteRecords($userId, $deleteRecords);
		}

		if (count($addRecords))
		{
			$results[] = $this->addRecords($userId, $addRecords, count($current) + 1);
		}

		if (count($updateRecords))
		{
			$results[] = $this->updateRecords($userId, $updateRecords);
		}

		$return = (!in_array(false, $results, true));

		if (count($results))
		{
			// Changes occurred so lets log it
			SHLog::add(
				JText::sprintf(
					'PLG_LDAP_PROFILE_DEBUG_12225',
					$username,
					$return == 1 ? JText::_('PLG_LDAP_PROFILE_SUCCESS') : JText::_('PLG_LDAP_PROFILE_FAIL')
				), 12225, JLog::DEBUG, 'ldap'
			);

			if (!$return)
			{
				// There was an error
				return false;
			}

			// Everything went well - we have updated both LDAP and the J! database.
			SHLog::add(JText::sprintf('PLG_LDAP_PROFILE_INFO_12224', $username), 12224, JLog::INFO, 'ldap');

			// Return this was successful and something was updated
			return true;
		}
		else
		{
			// No changes occurred so log that the profile was up to date
			SHLog::add(
				JText::sprintf('PLG_LDAP_PROFILE_DEBUG_12226', $username), 12226, JLog::DEBUG, 'ldap'
			);

			return;
		}
	}
Example #9
0
	/**
	 * Inform any listening loggers of the debug message and add to debug stack.
	 *
	 * @param   string  $message  String to push to stack
	 *
	 * @return  void
	 *
	 * @since  2.0
	 */
	public function addDebug($message)
	{
		// Add the debug message to any listening loggers
		SHLog::add($message, 101, JLog::DEBUG, 'ldap');

		$this->debug[] = $message;
	}
Example #10
0
 /**
  * Attempts to login a user via Single Sign On.
  * Only if a username is detected can a login been attempted.
  *
  * @param   array  $detection  Optional SSO user.
  * @param   array  $options    An optional array of options to override config settings.
  *
  * @return  boolean  True on successful login or False on fail.
  *
  * @since   1.0
  * @throws  RuntimeException
  */
 public function login($detection = null, $options = array())
 {
     $config = SHFactory::getConfig();
     // Get the SSO username and optional details from the plug-ins
     if (is_null($detection)) {
         $detection = $this->detect();
     }
     if (!$detection) {
         return false;
     }
     SHLog::add(JText::sprintf('LIB_SHSSO_DEBUG_15066', $detection['username'], $detection['sso']), 15066, JLog::DEBUG, 'sso');
     // Set the action if its currently unset
     if (!isset($options['action'])) {
         $options['action'] = JFactory::getApplication()->isAdmin() ? 'core.login.admin' : 'core.login.site';
     }
     // Set the autoregister if its currently unset
     if (!isset($options['autoregister'])) {
         $options['autoregister'] = $config->get('sso.autoregister', false);
     }
     // Set the doauthorise if its currently unset
     if (!isset($options['doauthorise'])) {
         $options['doauthorise'] = $config->get('sso.doauthorise', self::AUTHORISE_INHERIT);
     }
     $username = $detection['username'];
     // Check if do authorised is based on the plug-in
     if ((int) $options['doauthorise'] === self::AUTHORISE_INHERIT) {
         if (isset($detection['doauthorise'])) {
             // Set the do authorised to the plug-in option
             $options['doauthorise'] = (bool) $detection['doauthorise'] ? self::AUTHORISE_TRUE : self::AUTHORISE_FALSE;
         } else {
             // Default the doauthorise to true
             $options['doauthorise'] = self::AUTHORISE_TRUE;
         }
     }
     // Check for a domain
     if (isset($detection['domain'])) {
         $options['domain'] = $detection['domain'];
     }
     // Check for any extra user attributes gathered from SSO
     if (isset($detection['attributes'])) {
         $options['attributes'] = $detection['attributes'];
     }
     /*
      * Authorising will call on onUserAuthorise() to attempt
      * to authorise the detected SSO user. If this
      * is disabled, then it will attempt to authorise with the
      * Joomla database. If autoregister is turned on then
      * it'll attempt to create the user in the Joomla database.
      */
     if ($options['doauthorise'] !== self::AUTHORISE_FALSE) {
         // Do authentication plug-in authorisation
         $response = $this->authorise($username, $options);
     } else {
         // Do Joomla database authorisation
         $response = $this->jAuthorise($username, $options);
     }
     // Check the response status for invalid status'
     if (!(JAuthentication::STATUS_SUCCESS + JAuthentication::STATUS_UNKNOWN & $response->status)) {
         // We can only process success and unknown status'
         throw new RuntimeException(JText::sprintf('LIB_SHSSO_ERR_15072', $username), 15072);
     } elseif ($response->status === JAuthentication::STATUS_UNKNOWN && !$options['autoregister']) {
         // The user is unknown and there is no autoregister - fail.
         throw new RuntimeException(JText::sprintf('LIB_SHSSO_ERR_15074', $username), 15074);
     } elseif (empty($response->email)) {
         // There is not email set for this user - fail.
         throw new RuntimeException(JText::sprintf('LIB_SHSSO_ERR_15076', $username), 15076);
     }
     /*
      * Username has been authorised. We can now proceed with the
      * standard Joomla log-on by calling the onUserLogin event.
      */
     $options[SHSsoHelper::SESSION_PLUGIN_KEY] = $detection['sso'];
     JPluginHelper::importPlugin('user');
     $results = JFactory::getApplication()->triggerEvent('onUserLogin', array((array) $response, $options));
     // Save the SSO plug-in name for logout later
     $session = JFactory::getSession();
     $session->set(SHSsoHelper::SESSION_PLUGIN_KEY, $detection['sso']);
     // Check if any of the events failed
     if (in_array(false, $results, true)) {
         throw new RuntimeException(JText::sprintf('LIB_SHSSO_ERR_15078', $username), 15078);
     }
     SHLog::add(JText::sprintf('LIB_SHSSO_INFO_15079', $username), 15079, JLog::INFO, 'sso');
     // Do a check if URL redirect is required
     SHSsoHelper::redirect();
     // Everything successful - user should be logged on.
     return true;
 }
Example #11
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;
     }
 }
Example #12
0
 /**
  * Method to initialise all the properties based on the parameters
  * specified in the plugin.
  *
  * @return  boolean  True on valid entries in the mapping list.
  *
  * @since   2.0
  */
 protected function doSetup()
 {
     static $done = null;
     if (is_null($done)) {
         // Assign class properties based on parameters from the plugin
         $this->sync_groups = (bool) $this->params->get('sync_groups', false);
         $this->addition = (bool) $this->params->get('addition', true);
         $this->removal = (int) $this->params->get('removal', self::YESDEFAULT);
         $this->unmanaged = array_map('intval', explode(';', $this->params->get('unmanaged')));
         $this->public_id = (int) $this->params->get('public_id');
         $this->dn_validate = $this->params->get('dn_validate', 1);
         $this->lookup_type = (int) $this->params->get('lookup_type', self::LOOKUP_FORWARD);
         $this->memberof_attribute = $this->params->get('memberof_attribute');
         $this->member_attribute = $this->params->get('member_attribute', 'member');
         $this->member_dn = $this->params->get('member_dn', 'dn');
         $this->recursion = (bool) $this->params->get('recursion', false);
         $this->dn_attribute = $this->params->get('dn_attribute', 'distinguishedName');
         $this->recursion_depth = (int) $this->params->get('recursion_depth', 0);
         $this->entries = array();
         $this->list = array();
         $list = preg_split('/\\r\\n|\\n|\\r/', $this->params->get('list'));
         // Loops around each mapping entry parameter
         foreach ($list as $item) {
             // Remove any accidental whitespace from the entry
             $item = trim($item);
             // Find the right most (outside of the distinguished name) to split groups
             if ($pos = strrpos($item, ':')) {
                 // Store distinguished name in a string and Joomla groups in an array
                 $entryDn = trim(substr($item, 0, $pos));
                 if ($entryGroups = array_map('intval', explode(',', substr($item, $pos + 1)))) {
                     // Store as a parameter for validation later
                     $this->list[$entryDn] = $entryGroups;
                 }
             }
         }
         // Get all the Joomla user groups
         $JUserGroups = SHUserHelper::getJUserGroups();
         $JUserGroupsKey = array_fill_keys($JUserGroups, '');
         /*
          * Process the map list parameter into validated entries.
          * Then ensure that there is atleast 1 valid entry to
          * proceed with the mapping process.
          */
         foreach ($this->list as $dn => $groups) {
             foreach ($groups as $key => $group) {
                 if (!isset($JUserGroupsKey[$group])) {
                     // This isn't a valid Joomla group
                     unset($this->list[$dn][$key]);
                     continue;
                 }
             }
             if (empty($this->list[$dn])) {
                 // This DN doesn't have any valid Joomla groups
                 unset($this->list[$dn]);
                 continue;
             }
             /*
              * Add the entry to a new mapping entry object then check if it is
              * valid. If so then we can assume this entry has no syntax errors.
              */
             $entry = new SHLdapMappingEntry($dn, $this->list[$dn], $this->dn_validate);
             if ($entry->isValid()) {
                 // Add as a valid entry
                 $this->entries[] = $entry;
                 // Add as a managed group
                 if ($this->removal === self::YES) {
                     /*
                      * Yes means we want to add only groups that are defined in the mapping list.
                      * Looping around dn group parameter list, ensuring its not already there and not in unmanaged.
                      */
                     $this->managed = array_merge($this->managed, array_diff(array_diff($this->list[$dn], $this->unmanaged), $this->managed));
                 }
             }
         }
         if ($this->removal === self::YESDEFAULT) {
             // Yesdefault means we want to add all Joomla groups to the managed pool
             $this->managed = array_diff($JUserGroups, $this->unmanaged);
         }
         $done = true;
         if (!count($this->entries)) {
             // No valid entries here
             SHLog::add(JText::_('PLG_LDAP_MAPPING_DEBUG_12006'), 12006, JLog::DEBUG, 'ldap');
             $done = false;
         }
     }
     return $done;
 }
Example #13
0
 /**
  * Method for attempting single sign on.
  *
  * @return  boolean  True on successful SSO or False on failure.
  *
  * @since   2.0
  */
 protected function _attemptSSO()
 {
     // Check the required SSO libraries exist
     if (!(class_exists('SHSsoHelper') && class_exists('SHSso'))) {
         // Error: classes missing
         SHLog::add(JText::_('LIB_SHSSOMONITOR_ERR_15001'), 15001, JLog::ERROR, 'sso');
         return;
     }
     try {
         $config = SHFactory::getConfig();
         // Check if SSO is disabled via the session
         if (SHSsoHelper::status() !== SHSsoHelper::STATUS_ENABLE) {
             // It is disabled so do not continue
             return;
         }
         SHSsoHelper::enable();
         $forceLogin = false;
         $userId = JFactory::getUser()->get('id');
         if ($config->get('sso.forcelogin', false)) {
             if ($userId) {
                 // Log out current user if detect user is not equal
                 $forceLogin = true;
             }
         } else {
             if ($userId) {
                 // User already logged in and no forcelogout
                 return;
             }
         }
         /*
          * Lets check the IP rule is valid before we continue -
          * if the IP rule is false then SSO is not allowed here.
          */
         jimport('joomla.application.input');
         $input = new JInput($_SERVER);
         // Get the IP address of this client
         $myIp = $input->get('REMOTE_ADDR', false, 'string');
         // Get a list of the IP addresses specific to the specified rule
         $ipList = json_decode($config->get('sso.iplist'));
         // Get the rule value
         $ipRule = $config->get('sso.iprule', SHSsoHelper::RULE_ALLOW_ALL);
         if (!SHSsoHelper::doIPCheck($myIp, $ipList, $ipRule)) {
             if (!$forceLogin) {
                 // This IP isn't allowed
                 SHLog::add(JText::_('LIB_SHSSO_DEBUG_15004'), 15004, JLog::DEBUG, 'sso');
             }
             return;
         }
         /*
          * We are going to check if we are in backend.
          * If so then we need to check if sso is allowed
          * to execute on the backend.
          */
         if (JFactory::getApplication()->isAdmin()) {
             if (!$config->get('sso.backend', false)) {
                 if (!$forceLogin) {
                     // Not allowed to SSO on backend
                     SHLog::add(JText::_('LIB_SHSSO_DEBUG_15006'), 15006, JLog::DEBUG, 'sso');
                 }
                 return;
             }
         }
         // Instantiate the main SSO library for detection & authentication
         $sso = new SHSso($config->get('sso.plugintype', 'sso'));
         $detection = $sso->detect();
         if ($detection) {
             // Check the detected user is not blacklisted
             $blacklist = (array) json_decode($config->get('user.blacklist'));
             if (in_array($detection['username'], $blacklist)) {
                 SHLog::add(JText::sprintf('LIB_SHSSO_DEBUG_15007', $detection['username']), 15007, JLog::DEBUG, 'sso');
                 // Detected user is blacklisted
                 return;
             }
             // Check if the current logged in user matches the detection
             if ($forceLogin && strtolower($detection['username']) != strtolower(JFactory::getUser()->get('username'))) {
                 SHLog::add(JText::sprintf('LIB_SHSSO_DEBUG_15008', $detection['username']), 15008, JLog::DEBUG, 'sso');
                 // Need to logout the current user
                 JFactory::getApplication()->logout();
             }
         }
         // Attempt the login
         return $sso->login($detection);
     } catch (Exception $e) {
         SHLog::add($e, 15002, JLog::ERROR, 'sso');
     }
 }
Example #14
0
 public function onUserBeforeSaveGroup($form, $table, $isNew)
 {
     $groupname = $table->title;
     try {
         // We want to check if this group is an existing group in an Adapter
         $adapter = SHFactory::getGroupAdapter($groupname);
         $adapter->getId();
         // We need to gather the adapter name to call the correct dispatcher
         $adapterName = $adapter::getName();
     } catch (Exception $e) {
         // We will assume this group doesnt exist in an Adapter
         $adapterName = false;
     }
     if ($adapterName) {
         $event = SHAdapterEventHelper::triggerEvent($adapterName, 'onGroupBeforeSave', array($groupname, $isNew));
         if ($event !== false) {
             try {
                 // Commit the changes to the Adapter if present
                 SHAdapterHelper::commitChanges($adapter, true, true);
                 //TODO: newId
                 SHLog::add(JText::sprintf('LIB_SHADAPTEREVENTBOUNCER_DEBUG_10986', $groupname), 10986, JLog::DEBUG, $adapterName);
                 return true;
             } catch (Excpetion $e) {
                 //TODO: newId
                 SHLog::add($e, 10981, JLog::ERROR, $adapterName);
             }
         }
         return $event;
     } elseif ($isNew) {
         // Use a default group adapter
         $name = SHFactory::getConfig()->get('user.type');
         // We must create and save the group as plugins may talk to adapter driver and expect a group object
         if (SHAdapterEventHelper::triggerEvent($name, 'onGroupCreation', array($groupname)) === true) {
             JFactory::getSession()->set('created', $groupname, SHGroupHelper::SESSION_KEY);
             $event = SHAdapterEventHelper::triggerEvent($adapterName, 'onGroupBeforeSave', array($groupname, $isNew));
             if ($event !== false) {
                 try {
                     // Commit the changes to the Adapter if present
                     $adapter = SHFactory::getGroupAdapter($groupname);
                     SHAdapterHelper::commitChanges($adapter, true, true);
                     return true;
                 } catch (Exception $e) {
                     //TODO: newId
                     SHLog::add($e, 10981, JLog::ERROR, $name);
                 }
             }
             return $event;
         }
         // Something went wrong with the group creation
         return false;
     }
 }
Example #15
0
 /**
  * Method prepares a form in the way of fields.
  * Note: Ldap user validation, if required, has to be done in plugin.
  *
  * @param   JForm   $form  The form to be alterted.
  * @param   object  $data  The associated data for the form.
  *
  * @return  boolean  True on success or False on error.
  *
  * @since   2.0
  */
 public function onContentPrepareForm($form, $data)
 {
     SHLog::add(JText::sprintf('LIB_SHLDAPEVENTDEBUG_CALLED', __METHOD__), 11910, JLog::DEBUG, 'ldap');
 }
Example #16
0
 /**
  * Get a users Ldap distinguished name with optional bind authentication.
  *
  * @param   boolean  $authenticate  Attempt to authenticate the user (i.e.
  *						bind the user with the password supplied)
  *
  * @return  string  User DN.
  *
  * @since   2.1
  * @throws  InvalidArgumentException  Invalid argument in config related error
  * @throws  SHLdapException           Ldap specific error.
  * @throws  SHExceptionInvaliduser    User invalid error.
  */
 private function _getDn($authenticate = false)
 {
     $replaced = str_replace(SHLdap::USERNAME_REPLACE, $this->username, $this->_userParams['user_query']);
     /*
      * A basic detection check for LDAP filter.
      * (i.e. distinguished names do not start and end with brackets).
      */
     $useSearch = preg_match('/(?<!\\S)[\\(]([\\S]+)[\\)](?!\\S)/', $this->_userParams['user_query']) ? true : false;
     SHLog::add("Attempt to retrieve user distinguished name using '{$replaced}' " . ($useSearch ? ' with search.' : ' with direct bind.'), 102, JLog::DEBUG, 'ldap');
     // Get a array of distinguished names from either the search or direct bind methods.
     $DNs = $useSearch ? $this->_getDnBySearch() : $this->_getDnDirect();
     if (empty($DNs)) {
         /*
          * Cannot find the specified username. We are going to throw
          * a special user not found error to try to split between
          * configuration errors and invalid errors. However, this might
          * still be a configuration error.
          */
         throw new SHExceptionInvaliduser(JText::_('LIB_SHLDAP_ERR_10302'), 10302, $this->username);
     }
     // Check if we have to authenticate the distinguished name with a password
     if ($authenticate) {
         // Attempt to bind each distinguished name with the specified password then return it
         foreach ($DNs as $dn) {
             if ($this->client->bind($dn, $this->password)) {
                 // Successfully binded with this distinguished name
                 SHLog::add("Successfully authenticated {$this->username} with distinguished name {$dn}.", 102, JLog::DEBUG, 'ldap');
                 return $dn;
             }
         }
         if ($useSearch) {
             // User found, but was unable to bind with the supplied password
             throw new SHExceptionInvaliduser(JText::_('LIB_SHLDAP_ERR_10303'), 10303, $this->username);
         } else {
             // Unable to bind directly to the given distinguished name parameters
             throw new SHExceptionInvaliduser(JText::_('LIB_SHLDAP_ERR_10304'), 10304, $this->username);
         }
     } else {
         $result = false;
         if ($useSearch) {
             /* We can be sure the distinguished name(s) exists in the Ldap
              * directory. However, we cannot be sure if the correct
              * distinguished name is returned for the specified user without
              * authenticating. Therefore, we have to assume the first (and
              * hopefully only) distinguished name is correct.
              * If the correct configuration has been given and the Ldap
              * directory is well organised, this will always be correct.
              */
             $result = $DNs[0];
         } else {
             /* Unlike searching, binding directly means we cannot be sure
              * if the distinguished name(s) exists in the Ldap directory.
              * Therefore, lets attempt to bind with a proxy user, then Ldap
              * read each distinguished name's entity to check if it exists.
              * If binding with the proxy user fails, then we have no option
              * but to assume the first distinguished name exists.
              */
             if ($this->client->proxyBind()) {
                 foreach ($DNs as $dn) {
                     try {
                         $read = $this->client->read($dn, null, array('dn'));
                     } catch (Exception $e) {
                         // We don't need to worry about the exception too much
                         SHLog::add("Failed to read direct bind without auth DN {$dn}.", 102, JLog::DEBUG, 'ldap');
                         continue;
                     }
                     // Check if the distinguished name entity exists
                     if ($read->countEntries() > 0) {
                         // It exists so we assume this is the correct distinguished name.
                         $result = $dn;
                         break;
                     }
                 }
                 if ($result === false) {
                     // Failed to find any of the distinguished name(s) in the Ldap directory.
                     throw new SHExceptionInvaliduser(JText::_('LIB_SHLDAP_ERR_10305'), 10305, $this->username);
                 }
             } else {
                 // Unable to check Ldap directory, so have to assume the first is correct
                 $result = $DNs[0];
             }
         }
         SHLog::add("Using distinguished name {$result} for user {$this->username}.", 102, JLog::DEBUG, 'ldap');
         return $result;
     }
 }