# Code Coverage for /Volumes/Rest/Dev/Sites/authLDAP/ldap.php

| Code Coverage
| Classes and Traits | Functions and Methods | Lines
Total | 0.00% covered (danger) | 0.00% | 0 / 2 | 0.00% covered (danger) | 0.00% | 0 / 12 | CRAP | 68.97% covered (warning) | 68.97% | 60 / 87
LDAP | 0.00% covered (danger) | 0.00% | 0 / 1 | 0.00% covered (danger) | 0.00% | 0 / 11 | 76.77 | 72.29% covered (warning) | 72.29% | 60 / 83
__construct | 0.00% covered (danger) | 0.00% | 0 / 1 | 11 | 96.15% covered (success) | 96.15% | 25 / 26
connect | 0.00% covered (danger) | 0.00% | 0 / 1 | 4.32 | 72.73% covered (warning) | 72.73% | 8 / 11
disconnect | 0.00% covered (danger) | 0.00% | 0 / 1 | 2.06 | 75.00% covered (warning) | 75.00% | 3 / 4
bind | 0.00% covered (danger) | 0.00% | 0 / 1 | 8.43 | 69.23% covered (warning) | 69.23% | 9 / 13
getErrorNumber | 0.00% covered (danger) | 0.00% | 0 / 1 | 2 | 0.00% covered (danger) | 0.00% | 0 / 1
getErrorText | 0.00% covered (danger) | 0.00% | 0 / 1 | 2 | 0.00% covered (danger) | 0.00% | 0 / 1
search | 0.00% covered (danger) | 0.00% | 0 / 1 | 4.59 | 66.67% covered (warning) | 66.67% | 6 / 9
debugOn | 0.00% covered (danger) | 0.00% | 0 / 1 | 2 | 0.00% covered (danger) | 0.00% | 0 / 2
debugOff | 0.00% covered (danger) | 0.00% | 0 / 1 | 2 | 0.00% covered (danger) | 0.00% | 0 / 2
authenticate | 0.00% covered (danger) | 0.00% | 0 / 1 | 7.05 | 90.00% covered (success) | 90.00% | 9 / 10
logError | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 | 0.00% covered (danger) | 0.00% | 0 / 4
AuthLDAP_Exception | 0.00% covered (danger) | 0.00% | 0 / 1 | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 | 0.00% covered (danger) | 0.00% | 0 / 4
__construct | 0.00% covered (danger) | 0.00% | 0 / 1 | 6 | 0.00% covered (danger) | 0.00% | 0 / 4

1 | <?php
2 | /**
3 | * $Id: ldap.php 381646 2011-05-06 09:37:31Z heiglandreas $
4 | *
5 | * authLdap - Authenticate Wordpress against an LDAP-Backend.
6 | * Copyright (c) 2008 Andreas Heigl<andreas@heigl.org>
7 | *
8 | * This program is free software; you can redistribute it and/or
9 | * modify it under the terms of the GNU General Public License
10 | * as published by the Free Software Foundation; either version 2
11 | * of the License, or (at your option) any later version.
12 | *
13 | * This program is distributed in the hope that it will be useful,
14 | * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 | * GNU General Public License for more details.
17 | *
18 | * You should have received a copy of the GNU General Public License
19 | * along with this program; if not, write to the Free Software
20 | * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
21 | *
22 | * This file handles the basic LDAP-Tasks
23 | *
24 | * @author Andreas Heigl<andreas@heigl.org>
25 | * @package authLdap
26 | * @category authLdap
27 | * @since 2008
28 | */
29 | class LDAP
30 | {
31 | private $_server = '';
32 |
33 | private $_scheme = 'ldap';
34 |
35 | private $_port = 389;
36 |
37 | private $_baseDn = '';
38 |
39 | private $_debug = false;
40 | /**
41 | * This property contains the connection handle to the ldap-server
42 | *
43 | * @var Ressource
44 | */
45 | private $_ch = null;
46 |
47 | private $_username = '';
48 |
49 | private $_password = '';
50 |
51 | public function __construct($URI, $debug = false)
52 | {
53 | $this->_debug=$debug;
54 | $url = parse_url($URI);
55 | if (false === $url) {
56 | throw new Exception($URI . ' is an invalid URL');
57 | }
58 | if (! isset ( $url['scheme'] )) {
59 | throw new Exception($URI . ' does not provide a scheme');
60 | }
61 | if (0 !== strpos($url['scheme'], 'ldap')) {
62 | throw new Exception($URI . ' is an invalid LDAP-URI');
63 | }
64 | if (! isset ( $url['host'] )) {
65 | throw new Exception($URI . ' does not provide a server');
66 | }
67 | if (! isset ( $url['path'] )) {
68 | throw new Exception($URI . ' does not provide a search-base');
69 | }
70 | if (1 == strlen($url['path'])) {
71 | throw new Exception($URI . ' does not provide a valid search-base');
72 | }
73 | $this -> _server = $url['host'];
74 | $this -> _scheme = $url['scheme'];
75 | $this -> _baseDn = substr($url['path'], 1);
76 | if (isset ( $url['user'] )) {
77 | $this -> _username = $url['user'];
78 | }
79 | if ('' == trim($this -> _username)) {
80 | $this -> _username = 'anonymous';
81 | }
82 | if (isset ( $url['pass'] )) {
83 | $this -> _password = $url['pass'];
84 | }
85 | if (isset ( $url['port'] )) {
86 | $this -> _port = $url['port'];
87 | }
88 | }
89 |
90 | /**
91 | * Connect to the given LDAP-Server
92 | *
93 | * @return LDAP
94 | * @throws AuthLdap_Exception
95 | */
96 | public function connect()
97 | {
98 | $this -> disconnect();
99 | if ('ldaps' == $this->_scheme) {
100 | $this->_ch = @ldap_connect($this->_server, $this->_port);
101 | } else {
102 | if (389 == $this -> _port) {
103 | $this -> _port = 636;
104 | }
105 | // when URL is used, port is ignored, see http://php.net/manual/en/function.ldap-connect.php
106 | $this->_ch = @ldap_connect($this->_scheme . '://' . $this->_server . ':' . $this -> _port);
107 | }
108 | if (! $this->_ch) {
109 | throw new AuthLDAP_Exception('Could not connect to the server');
110 | }
111 | ldap_set_option($this->_ch, LDAP_OPT_PROTOCOL_VERSION, 3);
112 | ldap_set_option($this->_ch, LDAP_OPT_REFERRALS, 0);
113 |
114 | return $this;
115 | }
116 |
117 | /**
118 | * Disconnect from a resource if one is available
119 | *
120 | * @return LDAP
121 | */
122 | public function disconnect()
123 | {
124 | if (is_resource($this->_ch)) {
125 | @ldap_unbind($this->_ch);
126 | }
127 | $this->_ch = null;
128 | return $this;
129 | }
130 |
131 | /**
132 | * Bind to an LDAP-Server with the given credentials
133 | *
134 | * @return LDAP
135 | * @throw AuthLdap_Exception
136 | */
137 | public function bind()
138 | {
139 | if (! $this->_ch) {
140 | $this->connect();
141 | }
142 | if (! is_resource($this->_ch)) {
143 | throw new AuthLDAP_Exception('No Resource-handle given');
144 | }
145 | $bind = false;
146 | if (( ( $this->_username )
147 | && ( $this->_username != 'anonymous') )
148 | && ( $this->_password != '' ) ) {
149 | $bind = @ldap_bind($this->_ch, $this->_username, $this->_password);
150 | } else {
151 | $bind = @ldap_bind($this->_ch);
152 | }
153 | if (! $bind) {
154 | throw new AuthLDAP_Exception('bind was not successfull: ' . ldap_error($this->_ch));
155 | }
156 | return $this;
157 | }
158 |
159 | public function getErrorNumber()
160 | {
161 | return @ldap_errno($this->_ch);
162 | }
163 |
164 | public function getErrorText()
165 | {
166 | return @ldap_error($this->_ch);
167 | }
168 |
169 | /**
170 | * This method does the actual ldap-serch.
171 | *
172 | * This is using the filter <var>$filter</var> for retrieving the attributes
173 | * <var>$attributes</var>
174 | *
175 | *
176 | * @param string $filter
177 | * @param array $attributes
178 | * @return array
179 | */
180 | public function search($filter, $attributes = array('uid'))
181 | {
182 | if (! is_Resource($this->_ch)) {
183 | throw new AuthLDAP_Exception('No resource handle avbailable');
184 | }
185 | $result = @ldap_search($this->_ch, $this->_baseDn, $filter, $attributes);
186 | if ($result === false) {
187 | throw new AuthLDAP_Exception('no result found');
188 | }
189 | $this->_info = @ldap_get_entries($this->_ch, $result);
190 | if ($this->_info === false) {
191 | throw new AuthLDAP_Exception('invalid results found');
192 | }
193 | return $this -> _info;
194 | }
195 |
196 | /**
197 | * This method sets debugging to ON
198 | */
199 | public function debugOn()
200 | {
201 | $this->_debug = true;
202 | return $this;
203 | }
204 |
205 | /**
206 | * This method sets debugging to OFF
207 | */
208 | public function debugOff()
209 | {
210 | $this->_debug = false;
211 | return $this;
212 | }
213 |
214 | /**
215 | * This method authenticates the user <var>$username</var> using the
216 | * password <var>$password</var>
217 | *
218 | * @param string $username
219 | * @param string $password
220 | * @param string $filter OPTIONAL This parameter defines the Filter to be used
221 | * when searchin for the username. This MUST contain the string '%s' which
222 | * will be replaced by the vaue given in <var>$username</var>
223 | * @return boolean true or false depending on successfull authentication or not
224 | */
225 | public function authenticate($username, $password, $filter = '(uid=%s)')
226 | {
227 | //return true;
228 | $this->connect();
229 | $this->bind();
230 | $res = $this->search(sprintf($filter, $username));
231 | if (! $res || ! is_array($res) || ( $res ['count'] != 1 )) {
232 | return false;
233 | }
234 | $dn = $res[0]['dn'];
235 | if ($username && $password) {
236 | if (@ldap_bind($this->_ch, $dn, $password)) {
237 | return true;
238 | }
239 | }
240 | return false;
241 | }
242 | /**
243 | * $this method loggs errors if debugging is set to ON
244 | */
245 | public function logError()
246 | {
247 | if ($this->_debug) {
248 | $_v = debug_backtrace();
249 | throw new AuthLDAP_Exception('[LDAP_ERROR]' . ldap_errno($this->_ch) . ':' . ldap_error($this->_ch), $_v[0]['line']);
250 | }
251 | }
252 | }
253 |
254 | class AuthLDAP_Exception extends Exception
255 | {
256 | public function __construct($message, $line = null)
257 | {
258 | parent :: __construct($message);
259 | if ($line) {
260 | $this -> line = $line;
261 | }
262 | }
263 | }