2 if ( empty ( $PHP_SELF ) && ! empty ( $_SERVER ) &&
3 ! empty ( $_SERVER['PHP_SELF'] ) ) {
4 $PHP_SELF = $_SERVER['PHP_SELF'];
6 if ( ! empty ( $PHP_SELF ) && preg_match ( "/\/includes\//", $PHP_SELF ) ) {
7 die ( "You can't access this file directly!" );
10 // LDAP user functions.
11 // This file is intended to be used instead of the standard user.php
12 // file. I have not tested this yet (I do not have an LDAP server
13 // running yet), so please provide feedback.
15 // This file contains all the functions for getting information
16 // about users. So, if you want to use an authentication scheme
17 // other than the webcal_user table, you can just create a new
18 // version of each function found below.
20 // Note: this application assumes that usernames (logins) are unique.
22 // Note #2: If you are using HTTP-based authentication, then you still
23 // need these functions and you will still need to add users to
27 /***************************** Config *******************************/
28 // Set some global config variables about your system.
29 // Next three are NOT yet implemented for LDAP
30 $user_can_update_password = false;
31 $admin_can_add_user = false;
32 $admin_can_delete_user = false;
35 //------ LDAP General Server Settings ------//
37 // Name or address of the LDAP server
38 // For SSL/TLS use 'ldaps://localhost'
39 $ldap_server = 'localhost';
41 // Port LDAP listens on (default 389)
44 // Use TLS for the connection (not the same as ldaps://)
45 $ldap_start_tls = false;
47 // If you need to set LDAP_OPT_PROTOCOL_VERSION
48 $set_ldap_version = false;
49 $ldap_version = '3'; // (usually 3)
51 // base DN to search for users
52 $ldap_base_dn = 'ou=people,dc=company,dc=com';
54 // The ldap attribute used to find a user (login).
55 // E.g., if you use cn, your login might be "Jane Smith"
56 // if you use uid, your login might be "jsmith"
57 $ldap_login_attr = 'uid';
59 // Account used to bind to the server and search for information.
60 // This user must have the correct rights to perform search.
61 // If left empty the search will be made in anonymous.
63 // *** We do NOT recommend storing the root LDAP account info here ***
64 $ldap_admin_dn = ''; // user DN
65 $ldap_admin_pwd = ''; // user password
68 //------ Admin Group Settings ------//
70 // A group name (complete DN) to find users with admin rights
71 $ldap_admin_group_name = 'cn=webcal_admin,ou=group,dc=company,dc=com';
73 // What type of group do we want (posixgroup, groupofnames, groupofuniquenames)
74 $ldap_admin_group_type = 'posixgroup';
76 // The LDAP attribute used to store member of a group
77 $ldap_admin_group_attr = 'memberuid';
80 //------ LDAP Search Settings ------//
82 // LDAP filter to find a user list.
83 $ldap_user_filter = '(objectclass=person)';
85 // Attributes to fetch from LDAP and corresponding user variables in the
86 // application. Do change according to your LDAP Schema
87 $ldap_user_attr = array(
88 // LDAP attribute //WebCalendar variable
91 'givenname', //firstname
96 /*************************** End Config *****************************/
99 // Convert group name to lower case to prevent problems
100 $ldap_admin_group_attr = strtolower($ldap_admin_group_attr);
101 $ldap_admin_group_type = strtolower($ldap_admin_group_type);
103 // Function to search the dn of a given user the error message will
104 // be placed in $error.
106 // $login - user login
107 // $dn - complete dn for the user (must be given by ref )
109 // TRUE if the user is found, FALSE in other case
110 function user_search_dn ( $login ,$dn ) {
111 global $error, $ds, $ldap_base_dn, $ldap_login_attr, $ldap_user_attr;
114 if ($r = connect_and_bind()) {
115 $sr = @ldap_search ( $ds, $ldap_base_dn, "($ldap_login_attr=$login)", $ldap_user_attr );
117 $error = 'Error searching LDAP server: ' . ldap_error();
119 $info = @ldap_get_entries ( $ds, $sr );
120 if ( $info['count'] != 1 ) {
121 $error = 'Invalid login';
124 $dn = $info[0]['dn'];
126 @ldap_free_result ( $sr );
134 // Check to see if a given login/password is valid. If invalid,
135 // the error message will be placed in $error.
137 // $login - user login
138 // $password - user password
139 // returns: true or false
140 function user_valid_login ( $login, $password ) {
141 global $error, $ldap_server, $ldap_port, $ldap_base_dn, $ldap_login_attr;
142 global $ldap_admin_dn, $ldap_admin_pwd, $ldap_start_tls, $set_ldap_version, $ldap_version;
145 $ds = @ldap_connect ( $ldap_server, $ldap_port );
147 if ($set_ldap_version || $ldap_start_tls)
148 ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, $ldap_version);
150 if ($ldap_start_tls) {
151 if (!ldap_start_tls($ds)) {
152 $error = 'Could not start TLS for LDAP connection';
157 if ( user_search_dn ( $login, &$dn) ) {
158 $r = @ldap_bind ( $ds, $dn, $password );
160 $error = 'Invalid login';
161 //$error .= ': incorrect password'; // uncomment for debugging
166 $error = 'Invalid login';
167 //$error .= ': no such user'; // uncomment for debugging
171 $error = 'Error connecting to LDAP server';
176 // TODO: implement this function properly for LDAP.
177 // Check to see if a given login/crypted password is valid. If invalid,
178 // the error message will be placed in $error.
180 // $login - user login
181 // $crypt_password - crypted user password
182 // returns: true or false
183 function user_valid_crypt ( $login, $crypt_password ) {
187 // Load info about a user (first name, last name, admin) and set globally.
189 // $user - user login
190 // $prefix - variable prefix to use
191 function user_load_variables ( $login, $prefix ) {
192 global $error, $ds, $ldap_base_dn, $ldap_login_attr, $ldap_user_attr;
193 global $PUBLIC_ACCESS_FULLNAME, $NONUSER_PREFIX;
195 if ($NONUSER_PREFIX && substr($login, 0, strlen($NONUSER_PREFIX) ) == $NONUSER_PREFIX ) {
196 nonuser_load_variables ( $login, $prefix );
200 if ( $login == '__public__' ) {
201 $GLOBALS[$prefix . 'login'] = $login;
202 $GLOBALS[$prefix . 'firstname'] = '';
203 $GLOBALS[$prefix . 'lastname'] = '';
204 $GLOBALS[$prefix . 'is_admin'] = 'N';
205 $GLOBALS[$prefix . 'email'] = '';
206 $GLOBALS[$prefix . 'fullname'] = $PUBLIC_ACCESS_FULLNAME;
207 $GLOBALS[$prefix . 'password'] = '';
212 if ($r = connect_and_bind()) {
213 $sr = @ldap_search ( $ds, $ldap_base_dn, "($ldap_login_attr=$login)", $ldap_user_attr );
215 $error = 'Error searching LDAP server: ' . ldap_error();
217 $info = @ldap_get_entries ( $ds, $sr );
218 if ( $info['count'] != 1 ) {
219 $error = 'Invalid login';
221 $GLOBALS[$prefix . 'login'] = $login;
222 $GLOBALS[$prefix . 'firstname'] = $info[0][$ldap_user_attr[2]][0];
223 $GLOBALS[$prefix . 'lastname'] = $info[0][$ldap_user_attr[1]][0];
224 $GLOBALS[$prefix . 'email'] = $info[0][$ldap_user_attr[4]][0];
225 $GLOBALS[$prefix . 'fullname'] = $info[0][$ldap_user_attr[3]][0];
226 $GLOBALS[$prefix . 'is_admin'] = user_is_admin($login,get_admins());
229 @ldap_free_result ( $sr );
238 // $user - user login
239 // $password - user password
240 // $firstname - first name
241 // $lastname - last name
242 // $email - email address
243 // $admin - is admin? ("Y" or "N")
244 function user_add_user ( $user, $password, $firstname, $lastname, $email, $admin ) {
247 $error = 'Not yet supported.';
253 // $user - user login
254 // $firstname - first name
255 // $lastname - last name
256 // $email - email address
257 // $admin - is admin?
258 function user_update_user ( $user, $firstname, $lastname, $email, $admin ) {
261 $error = 'Not yet supported.';
265 // Update user password
267 // $user - user login
268 // $password - last name
269 function user_update_user_password ( $user, $password ) {
272 $error = 'Not yet supported';
276 // Delete a user from the system.
277 // Once this does get implemented, be sure to delete the user from
278 // various WebCalendar tables (see user.php user_delete_user function).
280 // $user - user to delete
281 function user_delete_user ( $user ) {
282 $error = 'Not yet supported';
287 // Get a list of users and return info in an array.
288 // returns: array of users
289 function user_get_users () {
290 global $error, $ds, $ldap_base_dn, $ldap_user_attr, $ldap_user_filter;
291 global $public_access, $PUBLIC_ACCESS_FULLNAME;
293 $Admins = get_admins();
296 if ( $public_access == 'Y' )
297 $ret[$count++] = array (
298 'cal_login' => '__public__',
299 'cal_lastname' => '',
300 'cal_firstname' => '',
301 'cal_is_admin' => 'N',
303 'cal_password' => '',
304 'cal_fullname' => $PUBLIC_ACCESS_FULLNAME );
306 if ($r = connect_and_bind()) {
307 $sr = @ldap_search ( $ds, $ldap_base_dn, $ldap_user_filter, $ldap_user_attr );
309 $error = 'Error searching LDAP server: ' . ldap_error();
311 if ( (float)substr(PHP_VERSION,0,3) >= 4.2 ) ldap_sort ( $ds, $sr, $ldap_user_attr[3]);
312 $info = @ldap_get_entries( $ds, $sr );
313 for ( $i = 0; $i < $info['count']; $i++ ) {
314 $ret[$count++] = array (
315 'cal_login' => $info[$i][$ldap_user_attr[0]][0],
316 'cal_lastname' => $info[$i][$ldap_user_attr[1]][0],
317 'cal_firstname' => $info[$i][$ldap_user_attr[2]][0],
318 'cal_email' => $info[$i][$ldap_user_attr[4]][0],
319 'cal_is_admin' => user_is_admin($info[$i][$ldap_user_attr[0]][0],$Admins),
320 'cal_fullname' => $info[$i][$ldap_user_attr[3]][0]
323 @ldap_free_result($sr);
330 // Test if a user is an admin, that is: if the user is a member of a special
331 // group in the LDAP Server
333 // $values - the login name
334 // returns: Y if user is admin, N if not
335 function user_is_admin($values,$Admins) {
338 } else if (in_array ($values, $Admins)) {
345 // Searches $ldap_admin_group_name and returns an array of the group members.
346 // Do this search only once per request.
347 // returns: array of admins
348 function get_admins() {
349 global $error, $ds, $cached_admins;
350 global $ldap_admin_group_name,$ldap_admin_group_attr,$ldap_admin_group_type;
352 if ( ! empty ( $cached_admins ) ) return $cached_admins;
353 $cached_admins = array ();
355 if ($r = connect_and_bind()) {
356 $search_filter = "($ldap_admin_group_attr=*)";
357 $sr = @ldap_search ( $ds, $ldap_admin_group_name, $search_filter, array($ldap_admin_group_attr) );
359 $error = 'Error searching LDAP server: ' . ldap_error();
361 $admins = ldap_get_entries( $ds, $sr );
362 for( $x = 0; $x <= $admins[0][$ldap_admin_group_attr]['count']; $x ++ ) {
363 if ($ldap_admin_group_type != 'posixgroup') {
364 $cached_admins[] = stripdn($admins[0][$ldap_admin_group_attr][$x]);
366 $cached_admins[] = $admins[0][$ldap_admin_group_attr][$x];
369 @ldap_free_result($sr);
373 return $cached_admins;
376 // Strip everything but the username (uid) from a dn.
378 // $dn - the dn you want to strip the uid from.
379 // returns: string - userid
381 // ex: stripdn(uid=jeffh,ou=people,dc=example,dc=com) returns jeffh
382 function stripdn($dn){
383 list ($uid,$trash) = split (',', $dn, 2);
384 list ($trash,$user) = split ('=', $uid);
388 // Connects and binds to the LDAP server
389 // Tries to connect as $ldap_admin_dn if we set it.
390 // returns: bind result or false
391 function connect_and_bind() {
392 global $ds, $error, $ldap_server, $ldap_port, $ldap_version;
393 global $ldap_admin_dn, $ldap_admin_pwd, $ldap_start_tls, $set_ldap_version;
396 $ds = @ldap_connect ( $ldap_server, $ldap_port );
398 if ($set_ldap_version || $ldap_start_tls)
399 ldap_set_option($ds, LDAP_OPT_PROTOCOL_VERSION, $ldap_version);
401 if ($ldap_start_tls) {
402 if (!ldap_start_tls($ds)) {
403 $error = 'Could not start TLS for LDAP connection';
408 if ( $ldap_admin_dn != '') {
409 $r = @ldap_bind ( $ds, $ldap_admin_dn, $ldap_admin_pwd );
411 $r = @ldap_bind ( $ds );
415 $error = 'Invalid Admin login for LDAP Server';
420 $error = 'Error connecting to LDAP server';