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