assign('USER',$_SESSION[ldapab][username]); } /** * Uses Username and Password from Session to initialize the LDAP handle * If it fails it redirects to login.php */ function ldap_login(){ global $conf; if(!empty($_SESSION['ldapab']['username'])){ // existing session! Check if valid if($_SESSION['ldapab']['browserid'] != auth_browseruid()){ //session hijacking detected header('Location: login.php?username='); exit; } } elseif ($conf['httpd_auth'] && !empty($_SERVER['PHP_AUTH_USER'])) { // use HTTP auth if wanted and possible $_SESSION['ldapab']['username'] = $_SERVER['PHP_AUTH_USER']; $_SESSION['ldapab']['password'] = $_SERVER['PHP_AUTH_PW']; } elseif ($_COOKIE['ldapabauth']) { // check persistent cookie $cookie = base64_decode($_COOKIE['ldapabauth']); $cookie = x_Decrypt($cookie,get_cookie_secret()); list($u,$p) = unserialize($cookie); $_SESSION['ldapab']['username'] = $u; $_SESSION['ldapab']['password'] = $p; } if(!do_ldap_bind($_SESSION['ldapab']['username'], $_SESSION['ldapab']['password'], $_SESSION['ldapab']['binddn'])){ header('Location: login.php?username='); exit; } } /** * Creates a global LDAP connection handle called $LDAP_CON */ function do_ldap_bind($user,$pass,$dn=""){ global $conf; global $LDAP_CON; //create global connection to LDAP if nessessary if(!$LDAP_CON){ $LDAP_CON = ldap_connect($conf[ldapserver],$conf[ldapport]); if(!$LDAP_CON){ die("couldn't connect to LDAP server"); } } if(empty($dn)){ //anonymous bind to lookup users //blank binddn or blank bindpw will result in anonymous bind if(!ldap_bind($LDAP_CON,$conf[anonbinddn],$conf[anonbindpw])){ die("can not bind for user lookup"); } //when no user was given stay connected anonymous if(empty($user)){ set_session('','',''); return true; } //get dn for given user $filter = str_replace('%u',$user,$conf[userfilter]); $sr = ldap_search($LDAP_CON, $conf[usertree], $filter);; $result = ldap_get_entries($LDAP_CON, $sr); if($result['count'] != 1){ set_session('','',''); return false; } $dn = $result[0]['dn']; } //bind with dn if(ldap_bind($LDAP_CON,$dn,$pass)){ //bind successful -> set up session set_session($user,$pass,$dn); return true; } //bind failed -> remove session set_session('','',''); return false; } /** * Builds a pseudo UID from browser and IP data * * This is neither unique nor unfakable - still it adds some * security. Using the first part of the IP makes sure * proxy farms like AOLs are stil okay. * * @author Andreas Gohr * * @return string a MD5 sum of various browser headers */ function auth_browseruid(){ $uid = ''; $uid .= $_SERVER['HTTP_USER_AGENT']; $uid .= $_SERVER['HTTP_ACCEPT_ENCODING']; $uid .= $_SERVER['HTTP_ACCEPT_LANGUAGE']; $uid .= $_SERVER['HTTP_ACCEPT_CHARSET']; $uid .= substr($_SERVER['REMOTE_ADDR'],0,strpos($_SERVER['REMOTE_ADDR'],'.')); return md5($uid); } /** * saves user data to Session and cookies */ function set_session($user,$pass,$dn){ global $conf; $rand = rand(); $_SESSION[ldapab][username] = $user; $_SESSION[ldapab][binddn] = $dn; $_SESSION[ldapab][password] = $pass; $_SESSION[ldapab][browserid] = auth_browseruid(); // (re)set the persistant auth cookie if($user == ''){ setcookie('ldapabauth','',time()+60*60*24*365); }elseif($_REQUEST['remember']){ $cookie = serialize(array($user,$pass)); $cookie = x_Encrypt($cookie,get_cookie_secret()); $cookie = base64_encode($cookie); setcookie('ldapabauth',$cookie,time()+60*60*24*365); } } /** * Creates a random string to encrypt persistant auth * cookies the string is stored inside the cache dir */ function get_cookie_secret(){ $file = dirname(__FILE__).'/cache/.htcookiesecret.php'; if(@file_exists($file)){ return md5(trim(file($file))); } $secret = ''; if(!$fh = fopen($file,'w')) die("Couldn't write to $file"); if(fwrite($fh, $secret) === FALSE) die("Couldn't write to $file"); fclose($fh); return md5($secret); } /** * binary safe function to get all search result data. * It will use ldap_get_values_len() instead and build the array * note: it's similar with the array returned by ldap_get_entries() * except it has no "count" elements * * @author: Original code by Ovidiu Geaboc */ function ldap_get_binentries($conn,$srchRslt){ if(!@ldap_count_entries($conn,$srchRslt)){ return null; } $entry = ldap_first_entry($conn, $srchRslt); $i=0; do { $dn = ldap_get_dn($conn,$entry); $attrs = ldap_get_attributes($conn, $entry); for($j=0; $j<$attrs['count']; $j++) { $vals = ldap_get_values_len($conn, $entry,$attrs[$j]); for($k=0; $k<$vals['count']; $k++){ $data[$i][$attrs[$j]][$k]=$vals[$k]; } } $data[$i]['dn']=$dn; $i++; }while ($entry = ldap_next_entry($conn, $entry)); return $data; } /** * loads ldap names and their cleartext meanings from * entries.conf file and returns it as hash */ function namedentries($flip=false){ global $conf; $entries[dn] = 'dn'; $entries[sn] = 'name'; $entries[givenName] = 'givenname'; $entries[title] = 'title'; $entries[o] = 'organization'; $entries[physicalDeliveryOfficeName] = 'office'; $entries[postalAddress] = 'street'; $entries[postalCode] = 'zip'; $entries[l] = 'location'; $entries[telephoneNumber] = 'phone'; $entries[facsimileTelephoneNumber] = 'fax'; $entries[mobile] = 'mobile'; $entries[pager] = 'pager'; $entries[homePhone] = 'homephone'; $entries[homePostalAddress] = 'homestreet'; $entries[jpegPhoto] = 'photo'; $entries[labeledURI] = 'url'; $entries[description] = 'note'; $entries[manager] = 'manager'; $entries[cn] = 'displayname'; if($conf[extended]){ $entries[anniversary] = 'anniversary'; } if($conf[openxchange]){ $entries[mailDomain] = 'domain'; $entries[userCountry] = 'country'; $entries[birthDay] = 'birthday'; $entries[IPPhone] = 'ipphone'; $entries[OXUserCategories] = 'categories'; $entries[OXUserInstantMessenger] = 'instantmessenger'; $entries[OXTimeZone] = 'timezone'; $entries[OXUserPosition] = 'position'; $entries[relClientCert] = 'certificate'; } if($flip){ $entries = array_reverse($entries); $entries = array_flip($entries); } return $entries; } /** * Creates an array for submission to ldap from websitedata */ function prepare_ldap_entry($in){ global $conf; //check dateformat if(!preg_match('/\d\d\d\d-\d\d-\d\d/',$in[anniversary])){ $in[anniversary]=''; } $entries = namedentries(true); foreach(array_keys($in) as $key){ if(empty($entries[$key])){ $keyname=$key; }else{ $keyname=$entries[$key]; } if(is_array($in[$key])){ $out[$keyname] = $in[$key]; }else{ $out[$keyname][] = $in[$key]; } } //standard Objectclass $out[objectclass][] = 'inetOrgPerson'; if($conf[extended]){ $out[objectclass][] = 'contactPerson'; } if($conf[openxchange]){ $out[objectclass][] = 'OXUserObject'; } return clear_array($out); } /** * remove empty element from arrays recursively * * @author Original by */ function clear_array ( $a ) { if ($a !== array()) { $b = array(); foreach ( $a as $key => $value ) { if (is_array($value)) { if (clear_array($value) !== false) { $b[$key] = clear_array ( $value ); } } elseif ($value !== '') { $b[$key] = $value; } } if ($b !== array()) { return $b; } else { return false; } } else { return false; } } /** * deletes an entryfrom ldap - optional with recursion * * @author Original by */ function ldap_full_delete($ds,$dn,$recursive=false){ if($recursive == false){ return(ldap_delete($ds,$dn)); }else{ //searching for sub entries $sr=ldap_list($ds,$dn,"ObjectClass=*",array("")); $info = ldap_get_entries($ds, $sr); for($i=0;$i<$info['count'];$i++){ //deleting recursively sub entries $result=myldap_delete($ds,$info[$i]['dn'],$recursive); if(!$result){ //return result code, if delete fails return($result); } } return(ldap_delete($ds,$dn)); } } /** * Returns all User Accounts as assoziative array */ function get_users(){ global $conf; global $LDAP_CON; $sr = ldap_list($LDAP_CON,$conf[usertree],"ObjectClass=inetOrgPerson"); $result = ldap_get_binentries($LDAP_CON, $sr); if(count($result)){ foreach ($result as $entry){ if(!empty($entry[sn][0])){ $users[$entry[dn]] = $entry[givenName][0]." ".$entry[sn][0]; } } } return $users; } /** * makes sure the given DN contains exactly one space * after each , */ function normalize_dn($dn){ $dn = preg_replace('/,/',', ',$dn); $dn = preg_replace('/,\s+/',', ',$dn); return $dn; } /** * Merges the given classes with the existing ones */ function ldap_store_objectclasses($dn,$classes){ global $conf; global $LDAP_CON; $sr = ldap_search($LDAP_CON,$dn,"objectClass=*",array('objectClass')); $result = ldap_get_binentries($LDAP_CON, $sr); $set = $result[0][objectClass]; $set = array_unique_renumber(array_merge($set,$classes)); $add[objectClass] = $set; $r = @ldap_mod_replace($LDAP_CON,$dn,$add); tpl_ldaperror(); /* print '
';
  print_r($set);
  print '
';*/ } /** * escape parenthesises in given string */ function ldap_filterescape($string){ return strtr($string,array('('=>'\(', ')'=>'\)')); } /** * Queries public and private addressbooks, combining the * results * * @todo This function should be used where ever possible, replacing * lots of duplicate code */ function ldap_queryabooks($filter,$types){ global $conf; global $LDAP_CON; // make sure $types is an array if(!is_array($types)){ $types = explode(',',$types); $types = array_map('trim',$types); } $results = array(); $result1 = array(); $result2 = array(); // public addressbook $sr = ldap_list($LDAP_CON,$conf['publicbook'], $filter,$types); $result1 = ldap_get_binentries($LDAP_CON, $sr); ldap_free_result($sr); // private addressbook if(!empty($_SESSION['ldapab']['binddn'])){ $sr = @ldap_list($LDAP_CON,$conf['privatebook']. ','.$_SESSION['ldapab']['binddn'], $filter,$types); $result2 = ldap_get_binentries($LDAP_CON, $sr); } // return merged results return array_merge($result1,$result2); } /** * Makes array unique and renumbers the entries * * @author */ function array_unique_renumber($somearray){ $tmparr = array_unique($somearray); $i=0; foreach ($tmparr as $v) { $newarr[$i] = $v; $i++; } return $newarr; } /** * Simple XOR encryption * * @author Dustin Schneider * @link http://www.phpbuilder.com/tips/item.php?id=68 */ function x_Encrypt($string, $key){ for($i=0; $i