]> git.sur5r.net Git - contagged/blob - functions.php
style fixes and doubleclick edit
[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 nessessary
53   if(!$LDAP_CON){
54     $LDAP_CON = ldap_connect($conf[ldapserver],$conf[ldapport]);
55     if(!$LDAP_CON){
56       die("couldn't connect to LDAP server");
57     }
58   }
59
60   if(empty($dn)){
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");
65     }
66   
67     //when no user was given stay connected anonymous
68     if(empty($user)){
69       set_session('','','');
70       return true;
71     }
72
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('','','');
79       return false;
80     }
81     $dn = $result[0]['dn'];
82   }
83
84   //bind with dn
85   if(ldap_bind($LDAP_CON,$dn,$pass)){
86     //bind successful -> set up session
87     set_session($user,$pass,$dn);
88     return true;
89   }
90   //bind failed -> remove session
91   set_session('','','');
92   return false;
93 }
94
95 /**
96  * Builds a pseudo UID from browser and IP data
97  *
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.
101  *
102  * @author  Andreas Gohr <andi@splitbrain.org>
103  *
104  * @return  string  a MD5 sum of various browser headers
105  */
106 function auth_browseruid(){
107   $uid  = '';
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'],'.'));
113   return md5($uid);
114 }
115
116
117 /**
118  * saves user data to Session and cookies
119  */
120 function set_session($user,$pass,$dn){
121   global $conf;
122
123   $rand = rand();
124   $_SESSION[ldapab][username]  = $user;
125   $_SESSION[ldapab][binddn]    = $dn;
126   $_SESSION[ldapab][password]  = $pass;
127   $_SESSION[ldapab][browserid] = auth_browseruid();
128
129   // (re)set the persistant auth cookie
130   if($user == ''){
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);
137   }
138 }
139
140 /**
141  * Creates a random string to encrypt persistant auth
142  * cookies the string is stored inside the cache dir
143  */
144 function get_cookie_secret(){
145   $file = dirname(__FILE__).'/cache/.htcookiesecret.php';
146   if(@file_exists($file)){
147     return md5(trim(file($file)));
148   }
149
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");
153   fclose($fh);
154
155   return md5($secret);
156 }
157
158 /**
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
163  *
164  * @author: Original code by Ovidiu Geaboc <ogeaboc@rdanet.com>
165  */
166 function ldap_get_binentries($conn,$srchRslt){
167   if(!@ldap_count_entries($conn,$srchRslt)){
168     return null;
169   }
170   $entry = ldap_first_entry($conn, $srchRslt);
171   $i=0;
172   do {
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];
179       }
180     }
181     $data[$i]['dn']=$dn;
182     $i++;
183   }while ($entry = ldap_next_entry($conn, $entry));
184
185   return $data;
186 }
187
188 /**
189  * loads ldap names and their cleartext meanings from
190  * entries.conf file and returns it as hash
191  */
192 function namedentries($flip=false){
193   global $conf;
194
195   $entries[dn]                         = 'dn';
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';
215
216   if($conf[extended]){
217     $entries[anniversary]              = 'anniversary';
218   }
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';
229   }
230
231   if($flip){
232     $entries = array_reverse($entries);
233     $entries = array_flip($entries);
234   }
235   return $entries;
236 }
237
238 /**
239  * Creates an array for submission to ldap from websitedata
240  */
241 function prepare_ldap_entry($in){
242   global $conf;
243
244   //check dateformat
245   if(!preg_match('/\d\d\d\d-\d\d-\d\d/',$in[anniversary])){
246     $in[anniversary]='';
247   }
248
249   $entries = namedentries(true);
250   foreach(array_keys($in) as $key){
251     if(empty($entries[$key])){
252       $keyname=$key;
253     }else{
254       $keyname=$entries[$key];
255     }
256     if(is_array($in[$key])){
257       $out[$keyname] = $in[$key];
258     }else{
259       $out[$keyname][] = $in[$key];
260     }
261   }
262
263   //standard Objectclass
264   $out[objectclass][] = 'inetOrgPerson';
265   if($conf[extended]){
266     $out[objectclass][] = 'contactPerson';
267   }
268   if($conf[openxchange]){
269     $out[objectclass][] = 'OXUserObject';
270   }
271
272   return clear_array($out);
273 }
274
275 /**
276  * remove empty element from arrays recursively
277  *
278  * @author Original by <xntx@msn.com>
279  */
280 function clear_array ( $a ) {
281   if ($a !== array()) {
282     $b = array();
283     foreach ( $a as $key => $value ) {
284         if (is_array($value)) {
285           if (clear_array($value) !== false) {
286             $b[$key] = clear_array ( $value );
287           }
288         } elseif ($value !== '') {
289           $b[$key] = $value;
290         }
291     }
292     if ($b !== array()) {
293         return $b;
294     } else {
295         return false;
296     }
297   } else {
298     return false;
299   }
300 }
301
302 /**
303  * deletes an entryfrom ldap - optional with recursion
304  *
305  * @author Original by <gabriel@hrz.uni-marburg.de>
306  */
307 function ldap_full_delete($ds,$dn,$recursive=false){
308   if($recursive == false){
309     return(ldap_delete($ds,$dn));
310   }else{
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);
317       if(!$result){
318         //return result code, if delete fails
319         return($result);
320       }
321     }
322     return(ldap_delete($ds,$dn));
323   }
324 }
325
326 /**
327  * Returns all User Accounts as assoziative array
328  */
329 function get_users(){
330   global $conf;
331   global $LDAP_CON;
332
333   $sr = ldap_list($LDAP_CON,$conf[usertree],"ObjectClass=inetOrgPerson");
334   $result = ldap_get_binentries($LDAP_CON, $sr);
335   if(count($result)){
336     foreach ($result as $entry){
337       if(!empty($entry[sn][0])){
338         $users[$entry[dn]] = $entry[givenName][0]." ".$entry[sn][0];
339       }
340     }
341   }
342   return $users; 
343 }
344
345 /**
346  * makes sure the given DN contains exactly one space
347  * after each ,
348  */
349 function normalize_dn($dn){
350   $dn = preg_replace('/,/',', ',$dn);
351   $dn = preg_replace('/,\s+/',', ',$dn);
352   return $dn;
353 }
354
355 /**
356  * Merges the given classes with the existing ones
357  */
358 function ldap_store_objectclasses($dn,$classes){
359   global $conf;
360   global $LDAP_CON;
361
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;
367
368   $r = @ldap_mod_replace($LDAP_CON,$dn,$add);
369   tpl_ldaperror();
370
371 /*  print '<pre>';
372   print_r($set);
373   print '</pre>';*/
374 }
375
376 /**
377  * escape parenthesises in given string
378  */
379 function ldap_filterescape($string){
380   return strtr($string,array('('=>'\(', ')'=>'\)'));
381 }
382
383 /**
384  * Queries public and private addressbooks, combining the
385  * results
386  *
387  * @todo This function should be used where ever possible, replacing
388  *       lots of duplicate code
389  */
390 function ldap_queryabooks($filter,$types){
391   global $conf;
392   global $LDAP_CON;
393
394   // make sure $types is an array
395   if(!is_array($types)){
396     $types = explode(',',$types);
397     $types = array_map('trim',$types);
398   }
399
400   $results = array();
401   $result1 = array();
402   $result2 = array();
403
404   // public addressbook
405   $sr      = ldap_list($LDAP_CON,$conf['publicbook'],
406                        $filter,$types);
407   $result1 = ldap_get_binentries($LDAP_CON, $sr);
408   ldap_free_result($sr);
409
410   // private addressbook
411   if(!empty($_SESSION['ldapab']['binddn'])){
412     $sr      = @ldap_list($LDAP_CON,$conf['privatebook'].
413                           ','.$_SESSION['ldapab']['binddn'],
414                           $filter,$types);
415     $result2 = ldap_get_binentries($LDAP_CON, $sr);
416   }
417
418   // return merged results
419   return array_merge($result1,$result2);
420 }
421
422 /**
423  * Makes array unique and renumbers the entries
424  *
425  * @author <kay_rules@yahoo.com>
426  */
427 function array_unique_renumber($somearray){
428    $tmparr = array_unique($somearray);
429    $i=0;
430    foreach ($tmparr as $v) {
431        $newarr[$i] = $v;
432        $i++;
433    }
434    return $newarr;
435 }
436
437 /**
438  * Simple XOR encryption
439  *
440  * @author Dustin Schneider
441  * @link http://www.phpbuilder.com/tips/item.php?id=68
442  */
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];
447         }
448     }
449     return $string;
450 }
451
452 /**
453  * Simple XOR decryption
454  *
455  * @author Dustin Schneider
456  * @link http://www.phpbuilder.com/tips/item.php?id=68
457  */
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];
462         }
463     }
464     return $string;
465 }
466
467 /**
468  * Decodes UTF8 recursivly for the given array
469  *
470  * @deprecated
471  */
472 function utf8_decode_array(&$array) {
473   trigger_error('deprecated utf8_decode_array called',E_USER_WARNING);
474
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]);
480     }else {
481       $array[$key] = utf8_decode($array[$key]);
482     }
483   }
484 }
485
486 /**
487  * Encodes the given array to UTF8 recursively
488  *
489  * @deprecated
490  */
491 function utf8_encode_array(&$array) {
492   trigger_error('deprecated utf8_encode_array called',E_USER_WARNING);
493
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]);
499     }else {
500       $array[$key] = utf8_encode($array[$key]);
501     }
502   }
503 }
504
505
506 ?>