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); |
||||
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); |
||||
0 ignored issues
–
show
Bug
introduced
by
Loading history...
|
|||||
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 |
||||
0 ignored issues
–
show
|
|||||
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)); |
||||
0 ignored issues
–
show
It seems like
$pwd can also be of type null ; however, parameter $string of stripslashes() does only seem to accept string , maybe add an additional type check?
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
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 |
||||
0 ignored issues
–
show
The type
userDN was not found. Maybe you did not declare it correctly or list all dependencies?
The issue could also be caused by a filter entry in the build configuration.
If the path has been excluded in your configuration, e.g. filter:
dependency_paths: ["lib/*"]
For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths
Loading history...
|
|||||
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; |
||||
0 ignored issues
–
show
|
|||||
265 | } |
||||
266 | $filter = $this->getFilter($uname); |
||||
267 | $sr = ldap_search($this->_ds, $this->ldap_base_dn, $filter); |
||||
0 ignored issues
–
show
$filter of type XoopsUser is incompatible with the type array|string expected by parameter $filter of ldap_search() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
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)); |
||||
0 ignored issues
–
show
$filter of type XoopsUser is incompatible with the type double|integer|string expected by parameter $values of sprintf() .
(
Ignorable by Annotation
)
If this is a false-positive, you can also ignore this issue in your code via the
Loading history...
|
|||||
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 != '') { |
||||
0 ignored issues
–
show
|
|||||
291 | $filter = str_replace('@@loginname@@', $uname, $this->ldap_filter_person); |
||||
292 | } else { |
||||
293 | $filter = $this->ldap_loginldap_attr . '=' . $uname; |
||||
294 | } |
||||
295 | |||||
296 | return $filter; |
||||
0 ignored issues
–
show
|
|||||
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 |