Commit ae61c83d398710db0eedeb6b67ddcee03a6ff580

Authored by Michael Joseph
1 parent 91a3f245

moved to lib/authentication


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