1 | <?php |
||
2 | /** |
||
3 | * XOOPS Authentification base class |
||
4 | * |
||
5 | * You may not change or alter any portion of this comment or credits |
||
6 | * of supporting developers from this source code or any supporting source code |
||
7 | * which is considered copyrighted (c) material of the original comment or credit authors. |
||
8 | * This program is distributed in the hope that it will be useful, |
||
9 | * but WITHOUT ANY WARRANTY; without even the implied warranty of |
||
10 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. |
||
11 | * |
||
12 | * @copyright The XOOPS Project (https://xoops.org) |
||
13 | * @license GNU GPL 2 (https://www.gnu.org/licenses/gpl-2.0.html) |
||
14 | * @package kernel |
||
15 | * @subpackage auth |
||
16 | * @since 2.0 |
||
17 | * @author Pierre-Eric MENUET <[email protected]> |
||
18 | */ |
||
19 | defined('XOOPS_ROOT_PATH') || exit('Restricted access'); |
||
20 | |||
21 | /** |
||
22 | * |
||
23 | * @package kernel |
||
24 | * @subpackage auth |
||
25 | * @description Authentification class for standard LDAP Server V2 or V3 |
||
26 | * @author Pierre-Eric MENUET <[email protected]> |
||
27 | * @copyright (c) 2000-2016 XOOPS Project (www.xoops.org) |
||
28 | */ |
||
29 | if (file_exists($file = $GLOBALS['xoops']->path('class/auth/auth_provisionning.php'))) { |
||
30 | include_once $file; |
||
31 | } |
||
32 | |||
33 | if (!class_exists('XoopsAuthProvisionning')) { |
||
34 | trigger_error('Required class XoopsAuthProvisionning was not found at line ' . __FILE__ . ' at line ' . __LINE__, E_USER_WARNING); |
||
35 | |||
36 | return false; |
||
37 | } |
||
38 | |||
39 | /** |
||
40 | * XoopsAuthLdap |
||
41 | * |
||
42 | * @package |
||
43 | * @author John |
||
44 | * @copyright (c) 2000-2016 XOOPS Project (www.xoops.org) |
||
45 | * @access public |
||
46 | */ |
||
47 | class XoopsAuthLdap extends XoopsAuth |
||
48 | { |
||
49 | public $cp1252_map = array( |
||
50 | "\xc2\x80" => "\xe2\x82\xac", |
||
51 | /** |
||
52 | * EURO SIGN |
||
53 | */ |
||
54 | "\xc2\x82" => "\xe2\x80\x9a", |
||
55 | /** |
||
56 | * SINGLE LOW-9 QUOTATION MARK |
||
57 | */ |
||
58 | "\xc2\x83" => "\xc6\x92", |
||
59 | /** |
||
60 | * LATIN SMALL LETTER F WITH HOOK |
||
61 | */ |
||
62 | "\xc2\x84" => "\xe2\x80\x9e", |
||
63 | /** |
||
64 | * DOUBLE LOW-9 QUOTATION MARK |
||
65 | */ |
||
66 | "\xc2\x85" => "\xe2\x80\xa6", |
||
67 | /** |
||
68 | * HORIZONTAL ELLIPSIS |
||
69 | */ |
||
70 | "\xc2\x86" => "\xe2\x80\xa0", |
||
71 | /** |
||
72 | * DAGGER |
||
73 | */ |
||
74 | "\xc2\x87" => "\xe2\x80\xa1", |
||
75 | /** |
||
76 | * DOUBLE DAGGER |
||
77 | */ |
||
78 | "\xc2\x88" => "\xcb\x86", |
||
79 | /** |
||
80 | * MODIFIER LETTER CIRCUMFLEX ACCENT |
||
81 | */ |
||
82 | "\xc2\x89" => "\xe2\x80\xb0", |
||
83 | /** |
||
84 | * PER MILLE SIGN |
||
85 | */ |
||
86 | "\xc2\x8a" => "\xc5\xa0", |
||
87 | /** |
||
88 | * LATIN CAPITAL LETTER S WITH CARON |
||
89 | */ |
||
90 | "\xc2\x8b" => "\xe2\x80\xb9", |
||
91 | /** |
||
92 | * SINGLE LEFT-POINTING ANGLE QUOTATION |
||
93 | */ |
||
94 | "\xc2\x8c" => "\xc5\x92", |
||
95 | /** |
||
96 | * LATIN CAPITAL LIGATURE OE |
||
97 | */ |
||
98 | "\xc2\x8e" => "\xc5\xbd", |
||
99 | /** |
||
100 | * LATIN CAPITAL LETTER Z WITH CARON |
||
101 | */ |
||
102 | "\xc2\x91" => "\xe2\x80\x98", |
||
103 | /** |
||
104 | * LEFT SINGLE QUOTATION MARK |
||
105 | */ |
||
106 | "\xc2\x92" => "\xe2\x80\x99", |
||
107 | /** |
||
108 | * RIGHT SINGLE QUOTATION MARK |
||
109 | */ |
||
110 | "\xc2\x93" => "\xe2\x80\x9c", |
||
111 | /** |
||
112 | * LEFT DOUBLE QUOTATION MARK |
||
113 | */ |
||
114 | "\xc2\x94" => "\xe2\x80\x9d", |
||
115 | /** |
||
116 | * RIGHT DOUBLE QUOTATION MARK |
||
117 | */ |
||
118 | "\xc2\x95" => "\xe2\x80\xa2", |
||
119 | /** |
||
120 | * BULLET |
||
121 | */ |
||
122 | "\xc2\x96" => "\xe2\x80\x93", |
||
123 | /** |
||
124 | * EN DASH |
||
125 | */ |
||
126 | "\xc2\x97" => "\xe2\x80\x94", |
||
127 | /** |
||
128 | * EM DASH |
||
129 | */ |
||
130 | "\xc2\x98" => "\xcb\x9c", |
||
131 | /** |
||
132 | * SMALL TILDE |
||
133 | */ |
||
134 | "\xc2\x99" => "\xe2\x84\xa2", |
||
135 | /** |
||
136 | * TRADEMARK SIGN |
||
137 | */ |
||
138 | "\xc2\x9a" => "\xc5\xa1", |
||
139 | /** |
||
140 | * LATIN SMALL LETTER S WITH CARON |
||
141 | */ |
||
142 | "\xc2\x9b" => "\xe2\x80\xba", |
||
143 | /** |
||
144 | * SINGLE RIGHT-POINTING ANGLE QUOTATION |
||
145 | */ |
||
146 | "\xc2\x9c" => "\xc5\x93", |
||
147 | /** |
||
148 | * LATIN SMALL LIGATURE OE |
||
149 | */ |
||
150 | "\xc2\x9e" => "\xc5\xbe", |
||
151 | /** |
||
152 | * LATIN SMALL LETTER Z WITH CARON |
||
153 | */ |
||
154 | "\xc2\x9f" => "\xc5\xb8"); |
||
155 | /** |
||
156 | * LATIN CAPITAL LETTER Y WITH DIAERESIS |
||
157 | */ |
||
158 | |||
159 | public $ldap_server; |
||
160 | public $ldap_port = '389'; |
||
161 | public $ldap_version = '3'; |
||
162 | public $ldap_base_dn; |
||
163 | public $ldap_loginname_asdn; |
||
164 | public $ldap_loginldap_attr; |
||
165 | public $ldap_mail_attr; |
||
166 | public $ldap_name_attr; |
||
167 | public $ldap_surname_attr; |
||
168 | public $ldap_givenname_attr; |
||
169 | public $ldap_manager_dn; |
||
170 | public $ldap_manager_pass; |
||
171 | public $_ds; |
||
172 | |||
173 | /** |
||
174 | * Authentication Service constructor |
||
175 | * @param XoopsDatabase $dao |
||
176 | */ |
||
177 | public function __construct(XoopsDatabase $dao = null) |
||
178 | { |
||
179 | $this->_dao = $dao; |
||
180 | // The config handler object allows us to look at the configuration options that are stored in the database |
||
181 | /** @var XoopsConfigHandler $config_handler */ |
||
182 | $config_handler = xoops_getHandler('config'); |
||
183 | $config = $config_handler->getConfigsByCat(XOOPS_CONF_AUTH); |
||
184 | $confcount = count($config); |
||
0 ignored issues
–
show
Unused Code
introduced
by
Loading history...
|
|||
185 | foreach ($config as $key => $val) { |
||
186 | $this->$key = $val; |
||
187 | } |
||
188 | } |
||
189 | |||
190 | /** |
||
191 | * XoopsAuthLdap::cp1252_to_utf8() |
||
192 | * |
||
193 | * @param mixed $str |
||
194 | * |
||
195 | * @return string |
||
196 | */ |
||
197 | public function cp1252_to_utf8($str) |
||
198 | { |
||
199 | return strtr(xoops_utf8_encode($str), $this->cp1252_map); |
||
200 | } |
||
201 | |||
202 | /** |
||
203 | * Authenticate user again LDAP directory (Bind) |
||
204 | * 2 options : |
||
205 | * Authenticate directly with uname in the DN |
||
206 | * Authenticate with manager, search the dn |
||
207 | * |
||
208 | * @param string $uname Username |
||
209 | * @param string $pwd Password |
||
210 | * @return bool |
||
211 | */ |
||
212 | public function authenticate($uname, $pwd = null) |
||
213 | { |
||
214 | $authenticated = false; |
||
215 | if (!extension_loaded('ldap')) { |
||
216 | $this->setErrors(0, _AUTH_LDAP_EXTENSION_NOT_LOAD); |
||
217 | |||
218 | return $authenticated; |
||
219 | } |
||
220 | $this->_ds = ldap_connect($this->ldap_server, $this->ldap_port); |
||
221 | if ($this->_ds) { |
||
222 | ldap_set_option($this->_ds, LDAP_OPT_PROTOCOL_VERSION, $this->ldap_version); |
||
223 | if ($this->ldap_use_TLS) { // We use TLS secure connection |
||
224 | if (!ldap_start_tls($this->_ds)) { |
||
225 | $this->setErrors(0, _AUTH_LDAP_START_TLS_FAILED); |
||
226 | } |
||
227 | } |
||
228 | // If the uid is not in the DN we proceed to a search |
||
229 | // The uid is not always in the dn |
||
230 | $userDN = $this->getUserDN($uname); |
||
231 | if (!$userDN) { |
||
232 | return false; |
||
233 | } |
||
234 | // We bind as user to test the credentials |
||
235 | $authenticated = ldap_bind($this->_ds, $userDN, stripslashes($pwd)); |
||
236 | if ($authenticated) { |
||
237 | // We load the Xoops User database |
||
238 | return $this->loadXoopsUser($userDN, $uname, $pwd); |
||
239 | } else { |
||
240 | $this->setErrors(ldap_errno($this->_ds), ldap_err2str(ldap_errno($this->_ds)) . '(' . $userDN . ')'); |
||
241 | } |
||
242 | } else { |
||
243 | $this->setErrors(0, _AUTH_LDAP_SERVER_NOT_FOUND); |
||
244 | } |
||
245 | @ldap_close($this->_ds); |
||
246 | |||
247 | return $authenticated; |
||
248 | } |
||
249 | |||
250 | /** |
||
251 | * Compose the user DN with the configuration. |
||
252 | * |
||
253 | * @param $uname |
||
254 | * @return userDN or false |
||
255 | */ |
||
256 | public function getUserDN($uname) |
||
257 | { |
||
258 | $userDN = false; |
||
259 | if (!$this->ldap_loginname_asdn) { |
||
260 | // Bind with the manager |
||
261 | if (!ldap_bind($this->_ds, $this->ldap_manager_dn, stripslashes($this->ldap_manager_pass))) { |
||
262 | $this->setErrors(ldap_errno($this->_ds), ldap_err2str(ldap_errno($this->_ds)) . '(' . $this->ldap_manager_dn . ')'); |
||
263 | |||
264 | return false; |
||
265 | } |
||
266 | $filter = $this->getFilter($uname); |
||
267 | $sr = ldap_search($this->_ds, $this->ldap_base_dn, $filter); |
||
268 | $info = ldap_get_entries($this->_ds, $sr); |
||
269 | if ($info['count'] > 0) { |
||
270 | $userDN = $info[0]['dn']; |
||
271 | } else { |
||
272 | $this->setErrors(0, sprintf(_AUTH_LDAP_USER_NOT_FOUND, $uname, $filter, $this->ldap_base_dn)); |
||
273 | } |
||
274 | } else { |
||
275 | $userDN = $this->ldap_loginldap_attr . '=' . $uname . ',' . $this->ldap_base_dn; |
||
276 | } |
||
277 | |||
278 | return $userDN; |
||
279 | } |
||
280 | |||
281 | /** |
||
282 | * Load user from XOOPS Database |
||
283 | * |
||
284 | * @param $uname |
||
285 | * @return XoopsUser object |
||
286 | */ |
||
287 | public function getFilter($uname) |
||
288 | { |
||
289 | $filter = ''; |
||
290 | if ($this->ldap_filter_person != '') { |
||
291 | $filter = str_replace('@@loginname@@', $uname, $this->ldap_filter_person); |
||
292 | } else { |
||
293 | $filter = $this->ldap_loginldap_attr . '=' . $uname; |
||
294 | } |
||
295 | |||
296 | return $filter; |
||
297 | } |
||
298 | |||
299 | /** |
||
300 | * XoopsAuthLdap::loadXoopsUser() |
||
301 | * |
||
302 | * @param mixed $userdn |
||
303 | * @param mixed $uname |
||
304 | * @param mixed $pwd |
||
305 | * @return bool |
||
306 | */ |
||
307 | public function loadXoopsUser($userdn, $uname, $pwd = null) |
||
308 | { |
||
309 | $provisHandler = XoopsAuthProvisionning::getInstance($this); |
||
310 | $sr = ldap_read($this->_ds, $userdn, '(objectclass=*)'); |
||
311 | $entries = ldap_get_entries($this->_ds, $sr); |
||
312 | if ($entries['count'] > 0) { |
||
313 | $xoopsUser = $provisHandler->sync($entries[0], $uname, $pwd); |
||
314 | } else { |
||
315 | $this->setErrors(0, sprintf('loadXoopsUser - ' . _AUTH_LDAP_CANT_READ_ENTRY, $userdn)); |
||
316 | } |
||
317 | |||
318 | return $xoopsUser; |
||
319 | } |
||
320 | } // end class |
||
321 | |||
322 |