]> git.sur5r.net Git - contagged/blob - functions.php
PHP5 compatibility and code cleanup
[contagged] / functions.php
1 <?
2
3 /**
4  * assigns some standard variables to smarty templates
5  */
6 function smarty_std(){
7   global $smarty;
8   $smarty->assign('USER',$_SESSION['ldapab']['username']);
9 }
10
11 /**
12  * Uses Username and Password from Session to initialize the LDAP handle
13  * If it fails it redirects to login.php
14  */
15 function ldap_login(){
16   global $conf;
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=');
22       exit;
23     }
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;
35   }
36
37   if(!do_ldap_bind($_SESSION['ldapab']['username'],
38                    $_SESSION['ldapab']['password'],
39                    $_SESSION['ldapab']['binddn'])){
40     header('Location: login.php?username=');
41     exit;
42   }
43 }
44
45 /**
46  * Creates a global LDAP connection handle called $LDAP_CON
47  */
48 function do_ldap_bind($user,$pass,$dn=""){
49   global $conf;
50   global $LDAP_CON;
51   
52   //create global connection to LDAP if necessary
53   if(!$LDAP_CON){
54     if (!empty($conf['ldapurl'])){
55       $LDAP_CON = ldap_connect($conf['ldapurl']);
56     }else{
57       $LDAP_CON = ldap_connect($conf['ldapserver'],$conf['ldapport']);
58     }
59     if(!$LDAP_CON){
60       die("couldn't connect to LDAP server");
61     }
62   }
63
64   if(empty($dn)){
65     //anonymous bind to lookup users
66     //blank binddn or blank bindpw will result in anonymous bind
67     if(!ldap_bind($LDAP_CON,$conf['anonbinddn'],$conf['anonbindpw'])){
68       die("can not bind for user lookup");
69     }
70   
71     //when no user was given stay connected anonymous
72     if(empty($user)){
73       set_session('','','');
74       return true;
75     }
76
77     //get dn for given user
78     $filter = str_replace('%u',$user,$conf['userfilter']);
79     $sr = ldap_search($LDAP_CON, $conf['usertree'], $filter);;
80     $result = ldap_get_entries($LDAP_CON, $sr);
81     if($result['count'] != 1){
82       set_session('','','');
83       return false;
84     }
85     $dn = $result[0]['dn'];
86   }
87
88   //bind with dn
89   if(ldap_bind($LDAP_CON,$dn,$pass)){
90     //bind successful -> set up session
91     set_session($user,$pass,$dn);
92     return true;
93   }
94   //bind failed -> remove session
95   set_session('','','');
96   return false;
97 }
98
99 /**
100  * Builds a pseudo UID from browser and IP data
101  *
102  * This is neither unique nor unfakable - still it adds some
103  * security. Using the first part of the IP makes sure
104  * proxy farms like AOLs are stil okay.
105  *
106  * @author  Andreas Gohr <andi@splitbrain.org>
107  *
108  * @return  string  a MD5 sum of various browser headers
109  */
110 function auth_browseruid(){
111   $uid  = '';
112   $uid .= $_SERVER['HTTP_USER_AGENT'];
113   $uid .= $_SERVER['HTTP_ACCEPT_ENCODING'];
114   $uid .= $_SERVER['HTTP_ACCEPT_LANGUAGE'];
115   $uid .= $_SERVER['HTTP_ACCEPT_CHARSET'];
116   $uid .= substr($_SERVER['REMOTE_ADDR'],0,strpos($_SERVER['REMOTE_ADDR'],'.'));
117   return md5($uid);
118 }
119
120
121 /**
122  * saves user data to Session and cookies
123  */
124 function set_session($user,$pass,$dn){
125   global $conf;
126
127   $rand = rand();
128   $_SESSION['ldapab']['username']  = $user;
129   $_SESSION['ldapab']['binddn']    = $dn;
130   $_SESSION['ldapab']['password']  = $pass;
131   $_SESSION['ldapab']['browserid'] = auth_browseruid();
132
133   // (re)set the persistant auth cookie
134   if($user == ''){
135     setcookie('ldapabauth','',time()+60*60*24*365);
136   }elseif($_REQUEST['remember']){
137     $cookie = serialize(array($user,$pass));
138     $cookie = x_Encrypt($cookie,get_cookie_secret());
139     $cookie = base64_encode($cookie);
140     setcookie('ldapabauth',$cookie,time()+60*60*24*365);
141   }
142 }
143
144 /**
145  * Creates a random string to encrypt persistant auth
146  * cookies the string is stored inside the cache dir
147  */
148 function get_cookie_secret(){
149   $file = dirname(__FILE__).'/cache/.htcookiesecret.php';
150   if(@file_exists($file)){
151     return md5(trim(file($file)));
152   }
153
154   $secret = '<?php #'.(rand()*time()).'?>';
155   if(!$fh = fopen($file,'w')) die("Couldn't write to $file");
156   if(fwrite($fh, $secret) === FALSE) die("Couldn't write to $file");
157   fclose($fh);
158
159   return md5($secret);
160 }
161
162 /**
163  * binary safe function to get all search result data.
164  * It will use ldap_get_values_len() instead and build the array
165  * note: it's similar with the array returned by ldap_get_entries()
166  * except it has no "count" elements
167  *
168  * @author: Original code by Ovidiu Geaboc <ogeaboc@rdanet.com>
169  */
170 function ldap_get_binentries($conn,$srchRslt){
171   if(!@ldap_count_entries($conn,$srchRslt)){
172     return null;
173   }
174   $entry = ldap_first_entry($conn, $srchRslt);
175   $i=0;
176   do {
177     $dn = ldap_get_dn($conn,$entry);
178     $attrs = ldap_get_attributes($conn, $entry);
179     for($j=0; $j<$attrs['count']; $j++) {
180       $vals = ldap_get_values_len($conn, $entry,$attrs[$j]);
181       for($k=0; $k<$vals['count']; $k++){
182         $data[$i][$attrs[$j]][$k]=$vals[$k];
183       }
184     }
185     $data[$i]['dn']=$dn;
186     $i++;
187   }while ($entry = ldap_next_entry($conn, $entry));
188
189   return $data;
190 }
191
192 /**
193  * loads ldap names and their cleartext meanings from
194  * entries.conf file and returns it as hash
195  */
196 function namedentries($flip=false){
197   global $conf;
198
199   $entries['dn']                         = 'dn';
200   $entries['sn']                         = 'name';
201   $entries['givenName']                  = 'givenname';
202   $entries['title']                      = 'title';
203   $entries['o']                          = 'organization';
204   $entries['physicalDeliveryOfficeName'] = 'office';
205   $entries['postalAddress']              = 'street';
206   $entries['postalCode']                 = 'zip';
207   $entries['l']                          = 'location';
208   $entries['telephoneNumber']            = 'phone';
209   $entries['facsimileTelephoneNumber']   = 'fax';
210   $entries['mobile']                     = 'mobile';
211   $entries['pager']                      = 'pager';
212   $entries['homePhone']                  = 'homephone';
213   $entries['homePostalAddress']          = 'homestreet';
214   $entries['jpegPhoto']                  = 'photo';
215   $entries['labeledURI']                 = 'url';
216   $entries['description']                = 'note';
217   $entries['manager']                    = 'manager';
218   $entries['cn']                         = 'displayname';
219
220   if($conf['extended']){
221     $entries['anniversary']              = 'anniversary';
222   }
223   if($conf['openxchange']){
224     $entries['mailDomain']               = 'domain';
225     $entries['userCountry']              = 'country';
226     $entries['birthDay']                 = 'birthday';
227     $entries['IPPhone']                  = 'ipphone';
228     $entries['OXUserCategories']         = 'categories';
229     $entries['OXUserInstantMessenger']   = 'instantmessenger';
230     $entries['OXTimeZone']               = 'timezone';
231     $entries['OXUserPosition']           = 'position';
232     $entries['relClientCert']            = 'certificate';
233   }
234
235   if($flip){
236     $entries = array_reverse($entries);
237     $entries = array_flip($entries);
238   }
239   return $entries;
240 }
241
242 /**
243  * Creates an array for submission to ldap from websitedata
244  */
245 function prepare_ldap_entry($in){
246   global $conf;
247
248   //check dateformat
249   if(!preg_match('/\d\d\d\d-\d\d-\d\d/',$in['anniversary'])){
250     $in['anniversary']='';
251   }
252
253   $entries = namedentries(true);
254   foreach(array_keys($in) as $key){
255     if(empty($entries[$key])){
256       $keyname=$key;
257     }else{
258       $keyname=$entries[$key];
259     }
260     if(is_array($in[$key])){
261       $out[$keyname] = $in[$key];
262     }else{
263       $out[$keyname][] = $in[$key];
264     }
265   }
266
267   //standard Objectclass
268   $out['objectclass'][] = 'inetOrgPerson';
269   if($conf['extended']){
270     $out['objectclass'][] = 'contactPerson';
271   }
272   if($conf['openxchange']){
273     $out['objectclass'][] = 'OXUserObject';
274   }
275
276   return clear_array($out);
277 }
278
279 /**
280  * remove empty element from arrays recursively
281  *
282  * @author Original by <xntx@msn.com>
283  */
284 function clear_array ( $a ) {
285   if ($a !== array()) {
286     $b = array();
287     foreach ( $a as $key => $value ) {
288         if (is_array($value)) {
289           if (clear_array($value) !== false) {
290             $b[$key] = clear_array ( $value );
291           }
292         } elseif ($value !== '') {
293           $b[$key] = $value;
294         }
295     }
296     if ($b !== array()) {
297         return $b;
298     } else {
299         return false;
300     }
301   } else {
302     return false;
303   }
304 }
305
306 /**
307  * deletes an entryfrom ldap - optional with recursion
308  *
309  * @author Original by <gabriel@hrz.uni-marburg.de>
310  */
311 function ldap_full_delete($ds,$dn,$recursive=false){
312   if($recursive == false){
313     return(ldap_delete($ds,$dn));
314   }else{
315     //searching for sub entries
316     $sr=ldap_list($ds,$dn,"ObjectClass=*",array(""));
317     $info = ldap_get_entries($ds, $sr);
318     for($i=0;$i<$info['count'];$i++){
319       //deleting recursively sub entries
320       $result=myldap_delete($ds,$info[$i]['dn'],$recursive);
321       if(!$result){
322         //return result code, if delete fails
323         return($result);
324       }
325     }
326     return(ldap_delete($ds,$dn));
327   }
328 }
329
330 /**
331  * Returns all User Accounts as assoziative array
332  */
333 function get_users(){
334   global $conf;
335   global $LDAP_CON;
336
337   $sr = ldap_list($LDAP_CON,$conf['usertree'],"ObjectClass=inetOrgPerson");
338   $result = ldap_get_binentries($LDAP_CON, $sr);
339   if(count($result)){
340     foreach ($result as $entry){
341       if(!empty($entry['sn'][0])){
342         $users[$entry['dn']] = $entry['givenName'][0]." ".$entry['sn'][0];
343       }
344     }
345   }
346   return $users; 
347 }
348
349 /**
350  * makes sure the given DN contains exactly one space
351  * after each ,
352  */
353 function normalize_dn($dn){
354   $dn = preg_replace('/,/',', ',$dn);
355   $dn = preg_replace('/,\s+/',', ',$dn);
356   return $dn;
357 }
358
359 /**
360  * Merges the given classes with the existing ones
361  */
362 function ldap_store_objectclasses($dn,$classes){
363   global $conf;
364   global $LDAP_CON;
365
366   $sr     = ldap_search($LDAP_CON,$dn,"objectClass=*",array('objectClass'));
367   $result = ldap_get_binentries($LDAP_CON, $sr);
368   $set    = $result[0]['objectClass'];
369   $set    = array_unique_renumber(array_merge((array)$set,(array)$classes));
370   $add['objectClass'] = $set;
371
372   $r = @ldap_mod_replace($LDAP_CON,$dn,$add);
373   tpl_ldaperror();
374
375 /*  print '<pre>';
376   print_r($set);
377   print '</pre>';*/
378 }
379
380 /**
381  * escape parenthesises in given string
382  */
383 function ldap_filterescape($string){
384   return strtr($string,array('('=>'\(', ')'=>'\)'));
385 }
386
387 /**
388  * Queries public and private addressbooks, combining the
389  * results
390  *
391  * @todo This function should be used where ever possible, replacing
392  *       lots of duplicate code
393  */
394 function ldap_queryabooks($filter,$types){
395   global $conf;
396   global $LDAP_CON;
397
398   // make sure $types is an array
399   if(!is_array($types)){
400     $types = explode(',',$types);
401     $types = array_map('trim',$types);
402   }
403
404   $results = array();
405   $result1 = array();
406   $result2 = array();
407
408   // public addressbook
409   $sr      = ldap_list($LDAP_CON,$conf['publicbook'],
410                        $filter,$types);
411   $result1 = ldap_get_binentries($LDAP_CON, $sr);
412   ldap_free_result($sr);
413
414   // private addressbook
415   if(!empty($_SESSION['ldapab']['binddn'])){
416     $sr      = @ldap_list($LDAP_CON,$conf['privatebook'].
417                           ','.$_SESSION['ldapab']['binddn'],
418                           $filter,$types);
419     $result2 = ldap_get_binentries($LDAP_CON, $sr);
420   }
421
422   // return merged results
423   return array_merge((array)$result1,(array)$result2);
424 }
425
426 /**
427  * Makes array unique and renumbers the entries
428  *
429  * @author <kay_rules@yahoo.com>
430  */
431 function array_unique_renumber($somearray){
432    $tmparr = array_unique($somearray);
433    $i=0;
434    foreach ($tmparr as $v) {
435        $newarr[$i] = $v;
436        $i++;
437    }
438    return $newarr;
439 }
440
441 /**
442  * Simple XOR encryption
443  *
444  * @author Dustin Schneider
445  * @link http://www.phpbuilder.com/tips/item.php?id=68
446  */
447 function x_Encrypt($string, $key){
448     for($i=0; $i<strlen($string); $i++){
449         for($j=0; $j<strlen($key); $j++){
450             $string[$i] = $string[$i]^$key[$j];
451         }
452     }
453     return $string;
454 }
455
456 /**
457  * Simple XOR decryption
458  *
459  * @author Dustin Schneider
460  * @link http://www.phpbuilder.com/tips/item.php?id=68
461  */
462 function x_Decrypt($string, $key){
463     for($i=0; $i<strlen($string); $i++){
464         for($j=0; $j<strlen($key); $j++){
465             $string[$i] = $key[$j]^$string[$i];
466         }
467     }
468     return $string;
469 }
470
471 /**
472  * Decodes UTF8 recursivly for the given array
473  *
474  * @deprecated
475  */
476 function utf8_decode_array(&$array) {
477   trigger_error('deprecated utf8_decode_array called',E_USER_WARNING);
478
479   foreach (array_keys($array) as $key) {
480     if($key === 'dn') continue;
481     if($key === 'jpegPhoto') continue;
482     if (is_array($array[$key])) {
483       utf8_decode_array($array[$key]);
484     }else {
485       $array[$key] = utf8_decode($array[$key]);
486     }
487   }
488 }
489
490 /**
491  * Encodes the given array to UTF8 recursively
492  *
493  * @deprecated
494  */
495 function utf8_encode_array(&$array) {
496   trigger_error('deprecated utf8_encode_array called',E_USER_WARNING);
497
498   foreach (array_keys($array) as $key) {
499     if($key === 'dn') continue;
500     if($key === 'jpegPhoto') continue;
501     if (is_array($array[$key])) {
502       utf8_encode_array($array[$key]);
503     }else {
504       $array[$key] = utf8_encode($array[$key]);
505     }
506   }
507 }
508
509
510 ?>