[ Index ] |
PHP Cross Reference of Joomla 4.2.2 documentation |
[Summary view] [Print] [Text view]
1 <?php 2 3 /** 4 * @package Joomla.Plugin 5 * @subpackage Authentication.ldap 6 * 7 * @copyright (C) 2006 Open Source Matters, Inc. <https://www.joomla.org> 8 * @license GNU General Public License version 2 or later; see LICENSE.txt 9 10 * @phpcs:disable PSR1.Classes.ClassDeclaration.MissingNamespace 11 */ 12 13 use Joomla\CMS\Authentication\Authentication; 14 use Joomla\CMS\Language\Text; 15 use Joomla\CMS\Plugin\CMSPlugin; 16 use Symfony\Component\Ldap\Entry; 17 use Symfony\Component\Ldap\Exception\ConnectionException; 18 use Symfony\Component\Ldap\Exception\LdapException; 19 use Symfony\Component\Ldap\Ldap; 20 21 // phpcs:disable PSR1.Files.SideEffects 22 \defined('_JEXEC') or die; 23 // phpcs:enable PSR1.Files.SideEffects 24 25 /** 26 * LDAP Authentication Plugin 27 * 28 * @since 1.5 29 */ 30 class PlgAuthenticationLdap extends CMSPlugin 31 { 32 /** 33 * This method should handle any authentication and report back to the subject 34 * 35 * @param array $credentials Array holding the user credentials 36 * @param array $options Array of extra options 37 * @param object &$response Authentication response object 38 * 39 * @return boolean 40 * 41 * @since 1.5 42 */ 43 public function onUserAuthenticate($credentials, $options, &$response) 44 { 45 // If LDAP not correctly configured then bail early. 46 if (!$this->params->get('host')) { 47 return false; 48 } 49 50 // For JLog 51 $response->type = 'LDAP'; 52 53 // Strip null bytes from the password 54 $credentials['password'] = str_replace(chr(0), '', $credentials['password']); 55 56 // LDAP does not like Blank passwords (tries to Anon Bind which is bad) 57 if (empty($credentials['password'])) { 58 $response->status = Authentication::STATUS_FAILURE; 59 $response->error_message = Text::_('JGLOBAL_AUTH_EMPTY_PASS_NOT_ALLOWED'); 60 61 return false; 62 } 63 64 // Load plugin params info 65 $ldap_email = $this->params->get('ldap_email'); 66 $ldap_fullname = $this->params->get('ldap_fullname'); 67 $ldap_uid = $this->params->get('ldap_uid'); 68 $auth_method = $this->params->get('auth_method'); 69 70 $ldap = Ldap::create( 71 'ext_ldap', 72 [ 73 'host' => $this->params->get('host'), 74 'port' => (int) $this->params->get('port'), 75 'version' => $this->params->get('use_ldapV3', '0') == '1' ? 3 : 2, 76 'referrals' => (bool) $this->params->get('no_referrals', '0'), 77 'encryption' => $this->params->get('negotiate_tls', '0') == '1' ? 'tls' : 'none', 78 ] 79 ); 80 81 switch ($auth_method) { 82 case 'search': 83 try { 84 $dn = str_replace('[username]', $this->params->get('username', ''), $this->params->get('users_dn', '')); 85 86 $ldap->bind($dn, $this->params->get('password', '')); 87 } catch (ConnectionException | LdapException $exception) { 88 $response->status = Authentication::STATUS_FAILURE; 89 $response->error_message = Text::_('JGLOBAL_AUTH_NOT_CONNECT'); 90 91 return; 92 } 93 94 // Search for users DN 95 try { 96 $entry = $this->searchByString( 97 str_replace( 98 '[search]', 99 str_replace(';', '\3b', $ldap->escape($credentials['username'], '', LDAP_ESCAPE_FILTER)), 100 $this->params->get('search_string') 101 ), 102 $ldap 103 ); 104 } catch (LdapException $exception) { 105 $response->status = Authentication::STATUS_FAILURE; 106 $response->error_message = Text::_('JGLOBAL_AUTH_UNKNOWN_ACCESS_DENIED'); 107 108 return; 109 } 110 111 if (!$entry) { 112 $response->status = Authentication::STATUS_FAILURE; 113 $response->error_message = Text::_('JGLOBAL_AUTH_NOT_CONNECT'); 114 115 return; 116 } 117 118 try { 119 // Verify Users Credentials 120 $ldap->bind($entry->getDn(), $credentials['password']); 121 } catch (ConnectionException $exception) { 122 $response->status = Authentication::STATUS_FAILURE; 123 $response->error_message = Text::_('JGLOBAL_AUTH_INVALID_PASS'); 124 125 return; 126 } 127 128 break; 129 130 case 'bind': 131 // We just accept the result here 132 try { 133 $ldap->bind($ldap->escape($credentials['username'], '', LDAP_ESCAPE_DN), $credentials['password']); 134 } catch (ConnectionException | LdapException $exception) { 135 $response->status = Authentication::STATUS_FAILURE; 136 $response->error_message = Text::_('JGLOBAL_AUTH_INVALID_PASS'); 137 138 return; 139 } 140 141 try { 142 $entry = $this->searchByString( 143 str_replace( 144 '[search]', 145 str_replace(';', '\3b', $ldap->escape($credentials['username'], '', LDAP_ESCAPE_FILTER)), 146 $this->params->get('search_string') 147 ), 148 $ldap 149 ); 150 } catch (LdapException $exception) { 151 $response->status = Authentication::STATUS_FAILURE; 152 $response->error_message = Text::_('JGLOBAL_AUTH_UNKNOWN_ACCESS_DENIED'); 153 154 return; 155 } 156 157 break; 158 159 default: 160 // Unsupported configuration 161 $response->status = Authentication::STATUS_FAILURE; 162 $response->error_message = Text::_('JGLOBAL_AUTH_UNKNOWN_ACCESS_DENIED'); 163 164 return; 165 } 166 167 // Grab some details from LDAP and return them 168 $response->username = $entry->getAttribute($ldap_uid)[0] ?? false; 169 $response->email = $entry->getAttribute($ldap_email)[0] ?? false; 170 $response->fullname = $entry->getAttribute($ldap_fullname)[0] ?? trim($entry->getAttribute($ldap_fullname)[0]) ?: $credentials['username']; 171 172 // Were good - So say so. 173 $response->status = Authentication::STATUS_SUCCESS; 174 $response->error_message = ''; 175 176 // The connection is no longer needed, destroy the object to close it 177 unset($ldap); 178 } 179 180 /** 181 * Shortcut method to perform a LDAP search based on a semicolon separated string 182 * 183 * Note that this method requires that semicolons which should be part of the search term to be escaped 184 * to correctly split the search string into separate lookups 185 * 186 * @param string $search search string of search values 187 * @param Ldap $ldap The LDAP client 188 * 189 * @return Entry|null The search result entry if a matching record was found 190 * 191 * @since 3.8.2 192 */ 193 private function searchByString($search, Ldap $ldap) 194 { 195 $dn = $this->params->get('base_dn'); 196 197 // We return the first entry from the first search result which contains data 198 foreach (explode(';', $search) as $key => $result) { 199 $results = $ldap->query($dn, '(' . str_replace('\3b', ';', $result) . ')')->execute(); 200 201 if (count($results)) { 202 return $results[0]; 203 } 204 } 205 } 206 }
title
Description
Body
title
Description
Body
title
Description
Body
title
Body
Generated: Wed Sep 7 05:41:13 2022 | Chilli.vc Blog - For Webmaster,Blog-Writer,System Admin and Domainer |