4 * assigns some standard variables to smarty templates
8 $smarty->assign('USER',$_SESSION[ldapab][username]);
12 * Uses Username and Password from Session to initialize the LDAP handle
13 * If it fails it redirects to login.php
15 function ldap_login(){
17 if(!empty($_SESSION['ldapab']['username'])){
18 // existing session! Check if valid
19 if($_SESSION['ldapab']['browserid'] != auth_browseruid()){
20 //session hijacking detected
21 header('Location: login.php?username=');
24 } elseif ($conf['httpd_auth'] && !empty($_SERVER['PHP_AUTH_USER'])) {
25 // use HTTP auth if wanted and possible
26 $_SESSION['ldapab']['username'] = $_SERVER['PHP_AUTH_USER'];
27 $_SESSION['ldapab']['password'] = $_SERVER['PHP_AUTH_PW'];
28 } elseif ($_COOKIE['ldapabauth']) {
29 // check persistent cookie
30 $cookie = base64_decode($_COOKIE['ldapabauth']);
31 $cookie = x_Decrypt($cookie,get_cookie_secret());
32 list($u,$p) = unserialize($cookie);
33 $_SESSION['ldapab']['username'] = $u;
34 $_SESSION['ldapab']['password'] = $p;
37 if(!do_ldap_bind($_SESSION['ldapab']['username'],
38 $_SESSION['ldapab']['password'],
39 $_SESSION['ldapab']['binddn'])){
40 header('Location: login.php?username=');
46 * Creates a global LDAP connection handle called $LDAP_CON
48 function do_ldap_bind($user,$pass,$dn=""){
52 //create global connection to LDAP if nessessary
54 $LDAP_CON = ldap_connect($conf[ldapserver],$conf[ldapport]);
56 die("couldn't connect to LDAP server");
61 //anonymous bind to lookup users
62 //blank binddn or blank bindpw will result in anonymous bind
63 if(!ldap_bind($LDAP_CON,$conf[anonbinddn],$conf[anonbindpw])){
64 die("can not bind for user lookup");
67 //when no user was given stay connected anonymous
69 set_session('','','');
73 //get dn for given user
74 $filter = str_replace('%u',$user,$conf[userfilter]);
75 $sr = ldap_search($LDAP_CON, $conf[usertree], $filter);;
76 $result = ldap_get_entries($LDAP_CON, $sr);
77 if($result['count'] != 1){
78 set_session('','','');
81 $dn = $result[0]['dn'];
85 if(ldap_bind($LDAP_CON,$dn,$pass)){
86 //bind successful -> set up session
87 set_session($user,$pass,$dn);
90 //bind failed -> remove session
91 set_session('','','');
96 * Builds a pseudo UID from browser and IP data
98 * This is neither unique nor unfakable - still it adds some
99 * security. Using the first part of the IP makes sure
100 * proxy farms like AOLs are stil okay.
102 * @author Andreas Gohr <andi@splitbrain.org>
104 * @return string a MD5 sum of various browser headers
106 function auth_browseruid(){
108 $uid .= $_SERVER['HTTP_USER_AGENT'];
109 $uid .= $_SERVER['HTTP_ACCEPT_ENCODING'];
110 $uid .= $_SERVER['HTTP_ACCEPT_LANGUAGE'];
111 $uid .= $_SERVER['HTTP_ACCEPT_CHARSET'];
112 $uid .= substr($_SERVER['REMOTE_ADDR'],0,strpos($_SERVER['REMOTE_ADDR'],'.'));
118 * saves user data to Session and cookies
120 function set_session($user,$pass,$dn){
124 $_SESSION[ldapab][username] = $user;
125 $_SESSION[ldapab][binddn] = $dn;
126 $_SESSION[ldapab][password] = $pass;
127 $_SESSION[ldapab][browserid] = auth_browseruid();
129 // (re)set the persistant auth cookie
131 setcookie('ldapabauth','',time()+60*60*24*365);
132 }elseif($_REQUEST['remember']){
133 $cookie = serialize(array($user,$pass));
134 $cookie = x_Encrypt($cookie,get_cookie_secret());
135 $cookie = base64_encode($cookie);
136 setcookie('ldapabauth',$cookie,time()+60*60*24*365);
141 * Creates a random string to encrypt persistant auth
142 * cookies the string is stored inside the cache dir
144 function get_cookie_secret(){
145 $file = dirname(__FILE__).'/cache/.htcookiesecret.php';
146 if(@file_exists($file)){
147 return md5(trim(file($file)));
150 $secret = '<?php #'.(rand()*time()).'?>';
151 if(!$fh = fopen($file,'w')) die("Couldn't write to $file");
152 if(fwrite($fh, $secret) === FALSE) die("Couldn't write to $file");
159 * binary safe function to get all search result data.
160 * It will use ldap_get_values_len() instead and build the array
161 * note: it's similar with the array returned by ldap_get_entries()
162 * except it has no "count" elements
164 * @author: Original code by Ovidiu Geaboc <ogeaboc@rdanet.com>
166 function ldap_get_binentries($conn,$srchRslt){
167 if(!@ldap_count_entries($conn,$srchRslt)){
170 $entry = ldap_first_entry($conn, $srchRslt);
173 $dn = ldap_get_dn($conn,$entry);
174 $attrs = ldap_get_attributes($conn, $entry);
175 for($j=0; $j<$attrs['count']; $j++) {
176 $vals = ldap_get_values_len($conn, $entry,$attrs[$j]);
177 for($k=0; $k<$vals['count']; $k++){
178 $data[$i][$attrs[$j]][$k]=$vals[$k];
183 }while ($entry = ldap_next_entry($conn, $entry));
189 * loads ldap names and their cleartext meanings from
190 * entries.conf file and returns it as hash
192 function namedentries($flip=false){
196 $entries[sn] = 'name';
197 $entries[givenName] = 'givenname';
198 $entries[title] = 'title';
199 $entries[o] = 'organization';
200 $entries[physicalDeliveryOfficeName] = 'office';
201 $entries[postalAddress] = 'street';
202 $entries[postalCode] = 'zip';
203 $entries[l] = 'location';
204 $entries[telephoneNumber] = 'phone';
205 $entries[facsimileTelephoneNumber] = 'fax';
206 $entries[mobile] = 'mobile';
207 $entries[pager] = 'pager';
208 $entries[homePhone] = 'homephone';
209 $entries[homePostalAddress] = 'homestreet';
210 $entries[jpegPhoto] = 'photo';
211 $entries[labeledURI] = 'url';
212 $entries[description] = 'note';
213 $entries[manager] = 'manager';
214 $entries[cn] = 'displayname';
217 $entries[anniversary] = 'anniversary';
219 if($conf[openxchange]){
220 $entries[mailDomain] = 'domain';
221 $entries[userCountry] = 'country';
222 $entries[birthDay] = 'birthday';
223 $entries[IPPhone] = 'ipphone';
224 $entries[OXUserCategories] = 'categories';
225 $entries[OXUserInstantMessenger] = 'instantmessenger';
226 $entries[OXTimeZone] = 'timezone';
227 $entries[OXUserPosition] = 'position';
228 $entries[relClientCert] = 'certificate';
232 $entries = array_reverse($entries);
233 $entries = array_flip($entries);
239 * Creates an array for submission to ldap from websitedata
241 function prepare_ldap_entry($in){
245 if(!preg_match('/\d\d\d\d-\d\d-\d\d/',$in[anniversary])){
249 $entries = namedentries(true);
250 foreach(array_keys($in) as $key){
251 if(empty($entries[$key])){
254 $keyname=$entries[$key];
256 if(is_array($in[$key])){
257 $out[$keyname] = $in[$key];
259 $out[$keyname][] = $in[$key];
263 //standard Objectclass
264 $out[objectclass][] = 'inetOrgPerson';
266 $out[objectclass][] = 'contactPerson';
268 if($conf[openxchange]){
269 $out[objectclass][] = 'OXUserObject';
272 return clear_array($out);
276 * remove empty element from arrays recursively
278 * @author Original by <xntx@msn.com>
280 function clear_array ( $a ) {
281 if ($a !== array()) {
283 foreach ( $a as $key => $value ) {
284 if (is_array($value)) {
285 if (clear_array($value) !== false) {
286 $b[$key] = clear_array ( $value );
288 } elseif ($value !== '') {
292 if ($b !== array()) {
303 * deletes an entryfrom ldap - optional with recursion
305 * @author Original by <gabriel@hrz.uni-marburg.de>
307 function ldap_full_delete($ds,$dn,$recursive=false){
308 if($recursive == false){
309 return(ldap_delete($ds,$dn));
311 //searching for sub entries
312 $sr=ldap_list($ds,$dn,"ObjectClass=*",array(""));
313 $info = ldap_get_entries($ds, $sr);
314 for($i=0;$i<$info['count'];$i++){
315 //deleting recursively sub entries
316 $result=myldap_delete($ds,$info[$i]['dn'],$recursive);
318 //return result code, if delete fails
322 return(ldap_delete($ds,$dn));
327 * Returns all User Accounts as assoziative array
329 function get_users(){
333 $sr = ldap_list($LDAP_CON,$conf[usertree],"ObjectClass=inetOrgPerson");
334 $result = ldap_get_binentries($LDAP_CON, $sr);
336 foreach ($result as $entry){
337 if(!empty($entry[sn][0])){
338 $users[$entry[dn]] = $entry[givenName][0]." ".$entry[sn][0];
346 * makes sure the given DN contains exactly one space
349 function normalize_dn($dn){
350 $dn = preg_replace('/,/',', ',$dn);
351 $dn = preg_replace('/,\s+/',', ',$dn);
356 * Merges the given classes with the existing ones
358 function ldap_store_objectclasses($dn,$classes){
362 $sr = ldap_search($LDAP_CON,$dn,"objectClass=*",array('objectClass'));
363 $result = ldap_get_binentries($LDAP_CON, $sr);
364 $set = $result[0][objectClass];
365 $set = array_unique_renumber(array_merge($set,$classes));
366 $add[objectClass] = $set;
368 $r = @ldap_mod_replace($LDAP_CON,$dn,$add);
377 * escape parenthesises in given string
379 function ldap_filterescape($string){
380 return strtr($string,array('('=>'\(', ')'=>'\)'));
384 * Queries public and private addressbooks, combining the
387 * @todo This function should be used where ever possible, replacing
388 * lots of duplicate code
390 function ldap_queryabooks($filter,$types){
394 // make sure $types is an array
395 if(!is_array($types)){
396 $types = explode(',',$types);
397 $types = array_map('trim',$types);
404 // public addressbook
405 $sr = ldap_list($LDAP_CON,$conf['publicbook'],
407 $result1 = ldap_get_binentries($LDAP_CON, $sr);
408 ldap_free_result($sr);
410 // private addressbook
411 if(!empty($_SESSION['ldapab']['binddn'])){
412 $sr = @ldap_list($LDAP_CON,$conf['privatebook'].
413 ','.$_SESSION['ldapab']['binddn'],
415 $result2 = ldap_get_binentries($LDAP_CON, $sr);
418 // return merged results
419 return array_merge($result1,$result2);
423 * Makes array unique and renumbers the entries
425 * @author <kay_rules@yahoo.com>
427 function array_unique_renumber($somearray){
428 $tmparr = array_unique($somearray);
430 foreach ($tmparr as $v) {
438 * Simple XOR encryption
440 * @author Dustin Schneider
441 * @link http://www.phpbuilder.com/tips/item.php?id=68
443 function x_Encrypt($string, $key){
444 for($i=0; $i<strlen($string); $i++){
445 for($j=0; $j<strlen($key); $j++){
446 $string[$i] = $string[$i]^$key[$j];
453 * Simple XOR decryption
455 * @author Dustin Schneider
456 * @link http://www.phpbuilder.com/tips/item.php?id=68
458 function x_Decrypt($string, $key){
459 for($i=0; $i<strlen($string); $i++){
460 for($j=0; $j<strlen($key); $j++){
461 $string[$i] = $key[$j]^$string[$i];
468 * Decodes UTF8 recursivly for the given array
472 function utf8_decode_array(&$array) {
473 trigger_error('deprecated utf8_decode_array called',E_USER_WARNING);
475 foreach (array_keys($array) as $key) {
476 if($key === 'dn') continue;
477 if($key === 'jpegPhoto') continue;
478 if (is_array($array[$key])) {
479 utf8_decode_array($array[$key]);
481 $array[$key] = utf8_decode($array[$key]);
487 * Encodes the given array to UTF8 recursively
491 function utf8_encode_array(&$array) {
492 trigger_error('deprecated utf8_encode_array called',E_USER_WARNING);
494 foreach (array_keys($array) as $key) {
495 if($key === 'dn') continue;
496 if($key === 'jpegPhoto') continue;
497 if (is_array($array[$key])) {
498 utf8_encode_array($array[$key]);
500 $array[$key] = utf8_encode($array[$key]);