Commit 0540bd75aee7915728beba66945feddf8add1204

Authored by Neil Blakey-Milner
1 parent 52ad2632

Remove unused class.AuthLdap.php


git-svn-id: https://kt-dms.svn.sourceforge.net/svnroot/kt-dms/trunk@5032 c91229c3-7414-0410-bfa2-8a42b809f60b
lib/authentication/class.AuthLdap.php deleted
1 -<?php  
2 -/**  
3 - * class.AuthLdap.php , version 0.1  
4 - * Mark Round, December 2002 - http://www.markround.com/unix  
5 - * Provides LDAP authentication and user functions.  
6 - *  
7 - * Not intended as a full-blown LDAP access class - but it does provide  
8 - * several useful functions for dealing with users.  
9 - * Note - this works out of the box on Sun's iPlanet Directory Server - but  
10 - * an ACL has to be defined giving all users the ability to change their  
11 - * password (userPassword attribute).  
12 - * See the README file for more information and examples.  
13 - *  
14 - * This program is free software; you can redistribute it and/or modify  
15 - * it under the terms of the GNU General Public License as published by  
16 - * the Free Software Foundation; using version 2 of the License.  
17 - *  
18 - *  
19 - * This program is distributed in the hope that it will be useful,  
20 - * but WITHOUT ANY WARRANTY; without even the implied warranty of  
21 - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the  
22 - * GNU General Public License for more details.  
23 - *  
24 - * You should have received a copy of the GNU General Public License  
25 - * along with this program; if not, write to the Free Software  
26 - * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA  
27 - *  
28 - * ChangeLog  
29 - * ---------  
30 - * version 0.2, 11.04.2003, Michael Joseph <michael@jamwarehouse.com>  
31 - * - Added switches and workarounds for Active Directory integration  
32 - * - Change documentation to phpdoc style (http://phpdocu.sourceforge.net)  
33 - * - Added a constructor  
34 - * - Added an attribute array parameter to the getUsers method  
35 - * 20040909, Daniel Patrick <daniel@geekmobile.biz>  
36 - * - Added server type OpenLDAP2  
37 - * - Added support for OpenLDAP2 servers that deny Anonymous Bind  
38 - * - Added support for OpenLDAP2 servers that deny LDAPv2 protocol  
39 - */  
40 -  
41 -class AuthLdap {  
42 -  
43 - // 1.1 Public properties -----------------------------------------------------  
44 - /**  
45 - * Array of server IP address or hostnames  
46 - */  
47 - var $server;  
48 - /**  
49 - * The base DN (e.g. "dc=foo,dc=com")  
50 - */  
51 - var $dn;  
52 - /**  
53 - * the directory server, currently supports iPlanet and Active Directory  
54 - */  
55 - var $serverType;  
56 - /**  
57 - * Active Directory authenticates using user@domain  
58 - */  
59 - var $domain;  
60 - /**  
61 - * The user to authenticate with when searching  
62 - * Active Directory doesn't support anonymous access  
63 - */  
64 - var $searchUser;  
65 - /**  
66 - * The password to authenticate with when searching  
67 - * Active Directory doesn't support anonymous access  
68 - */  
69 - var $searchPassword;  
70 - /**  
71 - * Where the user records are kept  
72 - */  
73 - var $people;  
74 - /**  
75 - * Where the group definitions are kept  
76 - */  
77 - var $groups;  
78 - /**  
79 - * The last error code returned by the LDAP server  
80 - */  
81 - var $ldapErrorCode;  
82 - /**  
83 - * Text of the error message  
84 - */  
85 - var $ldapErrorText;  
86 -  
87 - // 1.2 Private properties ----------------------------------------------------  
88 - /**  
89 - * The internal LDAP connection handle  
90 - */  
91 - var $connection;  
92 - /**  
93 - * Result of any connections etc.  
94 - */  
95 - var $result;  
96 -  
97 - /**  
98 - * Constructor- creates a new instance of the authentication class  
99 - *  
100 - * @param string the ldap server to connect to  
101 - * @param string the base dn  
102 - * @param string the server type- current supports iPlanet and ActiveDirectory  
103 - * @param string the domain to use when authenticating against Active Directory  
104 - * @param string the username to authenticate with when searching if anonymous binding is not supported  
105 - * @param string the password to authenticate with when searching if anonymous binding is not supported  
106 - */  
107 - function AuthLdap ($aLdapServers, $sBaseDN, $sServerType, $sDomain = "", $searchUser = "", $searchPassword = "") {  
108 - if (is_string($aLdapServers)) {  
109 - $this->server = array($aLdapServers);  
110 - } elseif (is_array($aLdapServers)) {  
111 - $this->server = $aLdapServers;  
112 - }  
113 - $this->dn = $sBaseDN;  
114 - $this->serverType = $sServerType;  
115 - $this->domain = $sDomain;  
116 - $this->searchUser = $searchUser;  
117 - $this->searchPassword = $searchPassword;  
118 - }  
119 -  
120 - // 2.1 Connection handling methods -------------------------------------------  
121 -  
122 - /**  
123 - * 2.1.1 : Connects to the server. Just creates a connection which is used  
124 - * in all later access to the LDAP server. If it can't connect and bind  
125 - * anonymously, it creates an error code of -1. Returns true if connected,  
126 - * false if failed. Takes an array of possible servers - if one doesn't work,  
127 - * it tries the next and so on.  
128 - */  
129 - function connect() {  
130 - foreach ($this->server as $key => $host) {  
131 - $this->connection = ldap_connect( $host);  
132 - if ( $this->serverType == "OpenLDAP2" ) {  
133 - ldap_set_option($this->connection, LDAP_OPT_PROTOCOL_VERSION, 3);  
134 - }  
135 - if ( $this->connection) {  
136 - if (($this->serverType == "ActiveDirectory") ||  
137 - (($this->serverType == "OpenLDAP2") &&  
138 - (!$this->searchUser == "") &&  
139 - (!$this->searchPassword == ""))) {  
140 - return true;  
141 - } else {  
142 - // Connected, now try binding anonymously  
143 - $this->result=@ldap_bind( $this->connection);  
144 - }  
145 - return true;  
146 - }  
147 - }  
148 -  
149 - $this->ldapErrorCode = -1;  
150 - $this->ldapErrorText = "Unable to connect to any server";  
151 - return false;  
152 - }  
153 -  
154 - /**  
155 - * 2.1.2 : Simply closes the connection set up earlier.  
156 - * Returns true if OK, false if there was an error.  
157 - */  
158 - function close() {  
159 - if ( !@ldap_close( $this->connection)) {  
160 - $this->ldapErrorCode = ldap_errno( $this->connection);  
161 - $this->ldapErrorText = ldap_error( $this->connection);  
162 - return false;  
163 - } else {  
164 - return true;  
165 - }  
166 - }  
167 -  
168 - /**  
169 - * 2.1.3 : Anonymously binds to the connection. After this is done,  
170 - * queries and searches can be done - but read-only.  
171 - */  
172 - function bind() {  
173 - if ( !$this->result=@ldap_bind( $this->connection)) {  
174 - $this->ldapErrorCode = ldap_errno( $this->connection);  
175 - $this->ldapErrorText = ldap_error( $this->connection);  
176 - return false;  
177 - } else {  
178 - return true;  
179 - }  
180 - }  
181 -  
182 -  
183 -  
184 - /**  
185 - * 2.1.4 : Binds as an authenticated user, which usually allows for write  
186 - * access. The FULL dn must be passed. For a directory manager, this is  
187 - * "cn=Directory Manager" under iPlanet. For a user, it will be something  
188 - * like "uid=jbloggs,ou=People,dc=foo,dc=com".  
189 - */  
190 - function authBind( $bindDn,$pass) {  
191 - if ( !$this->result = @ldap_bind( $this->connection,$bindDn,$pass)) {  
192 - $this->ldapErrorCode = ldap_errno( $this->connection);  
193 - $this->ldapErrorText = ldap_error( $this->connection);  
194 - return false;  
195 - } else {  
196 - return true;  
197 - }  
198 - }  
199 -  
200 - // 2.2 Password methods ------------------------------------------------------  
201 -  
202 - /**  
203 - * 2.2.1 : Checks a username and password - does this by logging on to the  
204 - * server as a user - specified in the DN. There are several reasons why  
205 - * this login could fail - these are listed below.  
206 - */  
207 - function checkPass( $uname,$pass) {  
208 - /* Construct the full DN, eg:-  
209 - ** "uid=username, ou=People, dc=orgname,dc=com"  
210 - */  
211 - if ($this->serverType == "ActiveDirectory") {  
212 - $checkDn = "$uname@$this->domain";  
213 - } else {  
214 - $checkDn = $this->getUserIdentifier() . "=$uname, " . $this->setDn(true);  
215 - }  
216 - // Try and connect...  
217 - $this->result = @ldap_bind( $this->connection,$checkDn,$pass);  
218 - if ( $this->result) {  
219 - // Connected OK - login credentials are fine!  
220 - return true;  
221 - } else {  
222 - /* Login failed. Return false, together with the error code and text from  
223 - ** the LDAP server. The common error codes and reasons are listed below :  
224 - ** (for iPlanet, other servers may differ)  
225 - ** 19 - Account locked out (too many invalid login attempts)  
226 - ** 32 - User does not exist  
227 - ** 49 - Wrong password  
228 - ** 53 - Account inactive (manually locked out by administrator)  
229 - */  
230 - $this->ldapErrorCode = ldap_errno( $this->connection);  
231 - $this->ldapErrorText = ldap_error( $this->connection);  
232 - return false;  
233 - }  
234 - }  
235 -  
236 -  
237 - /**  
238 - * 2.2.2 : Allows a password to be changed. Note that on most LDAP servers,  
239 - * a new ACL must be defined giving users the ability to modify their  
240 - * password attribute (userPassword). Otherwise this will fail.  
241 - */  
242 - function changePass( $uname,$oldPass,$newPass) {  
243 - // builds the appropriate dn, based on whether $this->people and/or $this->group is set  
244 - if ($this->serverType == "ActiveDirectory") {  
245 - $checkDn = "$uname@$this->domain";  
246 - } else {  
247 - $checkDn = $this->getUserIdentifier() . "=$uname, " . $this->setDn(true);  
248 - }  
249 - $this->result = @ldap_bind( $this->connection,$checkDn,$oldPass);  
250 -  
251 - if ( $this->result) {  
252 - // Connected OK - Now modify the password...  
253 - $info["userPassword"] = $newPass;  
254 - $this->result = @ldap_modify( $this->connection, $checkDn, $info);  
255 - if ( $this->result) {  
256 - // Change went OK  
257 - return true;  
258 - } else {  
259 - // Couldn't change password...  
260 - $this->ldapErrorCode = ldap_errno( $this->connection);  
261 - $this->ldapErrorText = ldap_error( $this->connection);  
262 - return false;  
263 - }  
264 - } else {  
265 - // Login failed - see checkPass method for common error codes  
266 - $this->ldapErrorCode = ldap_errno( $this->connection);  
267 - $this->ldapErrorText = ldap_error( $this->connection);  
268 - return false;  
269 - }  
270 - }  
271 -  
272 -  
273 - /**  
274 - * 2.2.3 : Returns days until the password will expire.  
275 - * We have to explicitly state this is what we want returned from the  
276 - * LDAP server - by default, it will only send back the "basic"  
277 - * attributes.  
278 - */  
279 - function checkPassAge ( $uname) {  
280 -  
281 - $results[0] = "passwordexpirationtime";  
282 - // builds the appropriate dn, based on whether $this->people and/or $this->group is set  
283 - $checkDn = $this->setDn(true);  
284 - $this->result = @ldap_search( $this->connection,$checkDn,$this->getUserIdentifier()."=$uname",$results);  
285 -  
286 - if ( !$info=@ldap_get_entries( $this->connection, $this->result)) {  
287 - $this->ldapErrorCode = ldap_errno( $this->connection);  
288 - $this->ldapErrorText = ldap_error( $this->connection);  
289 - return false;  
290 - } else {  
291 - /* Now work out how many days remaining....  
292 - ** Yes, it's very verbose code but I left it like this so it can easily  
293 - ** be modified for your needs.  
294 - */  
295 - $date = $info[0]["passwordexpirationtime"][0];  
296 - $year = substr( $date,0,4);  
297 - $month = substr( $date,4,2);  
298 - $day = substr( $date,6,2);  
299 - $hour = substr( $date,8,2);  
300 - $min = substr( $date,10,2);  
301 - $sec = substr( $date,12,2);  
302 -  
303 - $timestamp = mktime( $hour,$min,$sec,$month,$day,$year);  
304 - $today = mktime();  
305 - $diff = $timestamp-$today;  
306 - return round( ( ( ( $diff/60)/60)/24));  
307 - }  
308 - }  
309 -  
310 - // 2.3 Group methods ---------------------------------------------------------  
311 -  
312 - /**  
313 - * 2.3.1 : Checks to see if a user is in a given group. If so, it returns  
314 - * true, and returns false if the user isn't in the group, or any other  
315 - * error occurs (eg:- no such user, no group by that name etc.)  
316 - */  
317 - function checkGroup ( $uname,$group) {  
318 - // builds the appropriate dn, based on whether $this->people and/or $this->group is set  
319 - $checkDn = $this->setDn(false);  
320 -  
321 - // We need to search for the group in order to get it's entry.  
322 - $this->result = @ldap_search( $this->connection, $checkDn, "cn=" .$group);  
323 - $info = @ldap_get_entries( $this->connection, $this->result);  
324 -  
325 - // Only one entry should be returned(no groups will have the same name)  
326 - $entry = ldap_first_entry( $this->connection,$this->result);  
327 -  
328 - if ( !$entry) {  
329 - $this->ldapErrorCode = ldap_errno( $this->connection);  
330 - $this->ldapErrorText = ldap_error( $this->connection);  
331 - return false; // Couldn't find the group...  
332 - }  
333 - // Get all the member DNs  
334 - if ( !$values = @ldap_get_values( $this->connection, $entry, "uniqueMember")) {  
335 - $this->ldapErrorCode = ldap_errno( $this->connection);  
336 - $this->ldapErrorText = ldap_error( $this->connection);  
337 - return false; // No users in the group  
338 - }  
339 -  
340 - foreach ( $values as $key => $value) {  
341 - /* Loop through all members - see if the uname is there...  
342 - ** Also check for sub-groups - this allows us to define a group as  
343 - ** having membership of another group.  
344 - ** FIXME:- This is pretty ugly code and unoptimised. It takes ages  
345 - ** to search if you have sub-groups.  
346 - */  
347 - list( $cn,$ou) = explode( ",",$value);  
348 - list( $ou_l,$ou_r) = explode( "=",$ou);  
349 -  
350 - if ( $this->groups==$ou_r) {  
351 - list( $cn_l,$cn_r) = explode( "=",$cn);  
352 - // OK, So we now check the sub-group...  
353 - if ( $this->checkGroup ( $uname,$cn_r)) {  
354 - return true;  
355 - }  
356 - }  
357 -  
358 - if ( preg_match( "/$uname/i",$value)) {  
359 - return true;  
360 - }  
361 - }  
362 - }  
363 -  
364 - // 2.4 Attribute methods -----------------------------------------------------  
365 - /**  
366 - * 2.4.1 : Returns an array containing a set of attribute values.  
367 - * For most searches, this will just be one row, but sometimes multiple  
368 - * results are returned (eg:- multiple email addresses)  
369 - */  
370 - function getAttribute ( $uname,$attribute) {  
371 - // builds the appropriate dn, based on whether $this->people and/or $this->group is set  
372 - $checkDn = $this->setDn( true);  
373 - $results[0] = $attribute;  
374 -  
375 - // We need to search for this user in order to get their entry.  
376 - $this->result = @ldap_search( $this->connection,$checkDn,$this->getUserIdentifier()."=$uname",$results);  
377 - $info = ldap_get_entries( $this->connection, $this->result);  
378 -  
379 - // Only one entry should ever be returned (no user will have the same uid)  
380 - $entry = ldap_first_entry( $this->connection, $this->result);  
381 -  
382 - if ( !$entry) {  
383 - $this->ldapErrorCode = -1;  
384 - $this->ldapErrorText = "Couldn't find user";  
385 - return false; // Couldn't find the user...  
386 - }  
387 -  
388 - // Get all the member DNs  
389 - if ( !$values = @ldap_get_values( $this->connection, $entry, $attribute)) {  
390 - $this->ldapErrorCode = ldap_errno( $this->connection);  
391 - $this->ldapErrorText = ldap_error( $this->connection);  
392 - return false; // No matching attributes  
393 - }  
394 -  
395 - // Return an array containing the attributes.  
396 - return $values;  
397 - }  
398 -  
399 - /**  
400 - * 2.4.2 : Allows an attribute value to be set.  
401 - * This can only usually be done after an authenticated bind as a  
402 - * directory manager - otherwise, read/write access will not be granted.  
403 - */  
404 - function setAttribute( $uname, $attribute, $value) {  
405 - // Construct a full DN...  
406 - // builds the appropriate dn, based on whether $this->people and/or $this->group is set  
407 - $attrib_dn = $this->getUserIdentifier()."=$uname," . $this->setDn(true);  
408 -  
409 - $info[$attribute] = $value;  
410 - // Change attribute  
411 - $this->result = ldap_modify( $this->connection, $attrib_dn, $info);  
412 - if ( $this->result) {  
413 - // Change went OK  
414 - return true;  
415 - } else {  
416 - // Couldn't change password...  
417 - $this->ldapErrorCode = ldap_errno( $this->connection);  
418 - $this->ldapErrorText = ldap_error( $this->connection);  
419 - return false;  
420 - }  
421 - }  
422 -  
423 - // 2.5 User methods ----------------------------------------------------------  
424 - /**  
425 - * 2.5.1 : Returns an array containing a details of users, sorted by  
426 - * username. The search criteria is a standard LDAP query - * returns all  
427 - * users. The $attributeArray variable contains the required user detail field names  
428 - */  
429 - function getUsers( $search, $attributeArray) {  
430 - // builds the appropriate dn, based on whether $this->people and/or $this->group is set  
431 - $checkDn = $this->setDn( true);  
432 -  
433 - // Perform the search and get the entry handles  
434 -  
435 - // if the directory is AD, then bind first with the search user first  
436 - if (($this->serverType == "ActiveDirectory") ||  
437 - (($this->serverType == "OpenLDAP2") &&  
438 - (!$this->searchUser == "") &&  
439 - (!$this->searchPassword == ""))) {  
440 - $this->authBind($this->searchUser, $this->searchPassword);  
441 - }  
442 - $this->result = ldap_search( $this->connection, $checkDn, $this->getUserIdentifier() . "=$search");  
443 -  
444 - $info = ldap_get_entries( $this->connection, $this->result);  
445 - for( $i = 0; $i < $info["count"]; $i++) {  
446 - // Get the username, and create an array indexed by it...  
447 - // Modify these as you see fit.  
448 - $uname = $info[$i][$this->getUserIdentifier()][0];  
449 - // add to the array for each attribute in my list  
450 - for ( $j = 0; $j < count( $attributeArray); $j++) {  
451 - if (strtolower($attributeArray[$j]) == "dn") {  
452 - $userslist["$uname"]["$attributeArray[$j]"] = $info[$i][strtolower($attributeArray[$j])];  
453 - } else {  
454 - $userslist["$uname"]["$attributeArray[$j]"] = $info[$i][strtolower($attributeArray[$j])][0];  
455 - }  
456 - }  
457 - }  
458 -  
459 - if ( !@asort( $userslist)) {  
460 - /* Sort into alphabetical order. If this fails, it's because there  
461 - ** were no results returned (array is empty) - so just return false.  
462 - */  
463 - $this->ldapErrorCode = -1;  
464 - $this->ldapErrorText = "No users found matching search criteria ".$search;  
465 - return false;  
466 - }  
467 - return $userslist;  
468 - }  
469 -  
470 - // 2.6 helper methods  
471 -  
472 - /**  
473 - * Sets and returns the appropriate dn, based on whether there  
474 - * are values in $this->people and $this->groups.  
475 - *  
476 - * @param boolean specifies whether to build a groups dn or a people dn  
477 - * @return string if true ou=$this->people,$this->dn, else ou=$this->groups,$this->dn  
478 - */  
479 - function setDn($peopleOrGroups) {  
480 -  
481 - if ($peopleOrGroups) {  
482 - if ( isset($this->people) && (strlen($this->people) > 0) ) {  
483 - $checkDn = "ou=" .$this->people. ", " .$this->dn;  
484 - }  
485 - } else {  
486 - if ( isset($this->groups) && (strlen($this->groups) > 0) ) {  
487 - $checkDn = "ou=" .$this->groups. ", " .$this->dn;  
488 - }  
489 - }  
490 -  
491 - if ( !isset($checkDn) ) {  
492 - $checkDn = $this->dn;  
493 - }  
494 - return $checkDn;  
495 - }  
496 -  
497 - /**  
498 - * Returns the correct user identifier to use, based on the ldap server type  
499 - */  
500 - function getUserIdentifier() {  
501 - if ($this->serverType == "ActiveDirectory") {  
502 - return "samaccountname";  
503 - } else {  
504 - return "uid";  
505 - }  
506 - }  
507 -} // End of class  
508 -?>