X-Git-Url: https://git.sur5r.net/?a=blobdiff_plain;f=functions.php;h=671fca402a873b55017460f1544669b31bdb898b;hb=e37e9f402048983cda6227130186cd5b2d64a488;hp=e8ac472488987ad535af3cbd5278081979d0d50e;hpb=aa36c490d2218814cb6faa20e31c10b5599d4483;p=contagged diff --git a/functions.php b/functions.php index e8ac472..671fca4 100644 --- a/functions.php +++ b/functions.php @@ -1,11 +1,11 @@ -assign('USER',$_SESSION[ldapab][username]); + $smarty->assign('USER',$_SESSION['ldapab']['username']); } /** @@ -13,18 +13,31 @@ function smarty_std(){ * If it fails it redirects to login.php */ function ldap_login(){ - if(!empty($_SESSION[ldapab][username])){ - //existing session! Check if valid - if($_COOKIE[ldapabconid] != $_SESSION[ldapab][conid]){ + 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; + 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 (!empty($_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])){ + if(empty($_SESSION['ldapab']) || + !do_ldap_bind($_SESSION['ldapab']['username'], + $_SESSION['ldapab']['password'], + $_SESSION['ldapab']['binddn'])){ header('Location: login.php?username='); exit; } @@ -36,21 +49,28 @@ function ldap_login(){ function do_ldap_bind($user,$pass,$dn=""){ global $conf; global $LDAP_CON; - - //create global connection to LDAP if nessessary + + //create global connection to LDAP if necessary if(!$LDAP_CON){ - $LDAP_CON = ldap_connect($conf[ldapserver]); + if (!empty($conf['ldapurl'])){ + $LDAP_CON = ldap_connect($conf['ldapurl']); + }else{ + $LDAP_CON = ldap_connect($conf['ldapserver'],$conf['ldapport']); + } if(!$LDAP_CON){ die("couldn't connect to LDAP server"); } } + if($conf['ldapv3']) ldap_set_option($LDAP_CON, LDAP_OPT_PROTOCOL_VERSION, 3); + if(empty($dn)){ //anonymous bind to lookup users - if(!ldap_bind($LDAP_CON)){ - die("can not bind anonymously"); + //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('','',''); @@ -58,8 +78,8 @@ function do_ldap_bind($user,$pass,$dn=""){ } //get dn for given user - $filter = str_replace('%u',$user,$conf[userfilter]); - $sr = ldap_search($LDAP_CON, $conf[usertree], $filter);; + $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('','',''); @@ -80,15 +100,70 @@ function do_ldap_bind($user,$pass,$dn=""){ } /** - * saves user data to Session + * 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 = ''; + if (empty($_SERVER['HTTP_USER_AGENT'])) { $_SERVER['HTTP_USER_AGENT']='USER_AGENT'; } + if (empty($_SERVER['HTTP_ACCEPT_ENCODING'])) { $_SERVER['HTTP_ACCEPT_ENCODING']='ACCEPT_ENCODING'; } + if (empty($_SERVER['HTTP_ACCEPT_LANGUAGE'])) { $_SERVER['HTTP_ACCEPT_LANGUAGE']='ACCEPT_LANGUAGE'; } + if (empty($_SERVER['HTTP_ACCEPT_CHARSET'])) { $_SERVER['HTTP_ACCEPT_CHARSET']='ACCEPT_CHARSET'; } + $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][conid] =$rand; - setcookie('ldapabconid',$rand,time()+60*60*24); + $_SESSION['ldapab']['username'] = $user; + $_SESSION['ldapab']['binddn'] = $dn; + $_SESSION['ldapab']['password'] = $pass; + $_SESSION['ldapab']['browserid'] = auth_browseruid(); + + // (re)set the persistent auth cookie + if($user == ''){ + setcookie('ldapabauth','',time()+60*60*24*365); + }elseif(!empty($_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 persistent 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); } /** @@ -121,43 +196,13 @@ function ldap_get_binentries($conn,$srchRslt){ 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($flip){ - $entries = array_reverse($entries); - $entries = array_flip($entries); - } - return $entries; + trigger_error('deprecated namedentries called',E_USER_WARNING); } /** @@ -165,33 +210,37 @@ function namedentries($flip=false){ */ 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]; + global $FIELDS; + global $OCLASSES; + + //check dateformats + if(!preg_match('/\d\d\d\d-\d\d-\d\d/',$in['anniversary'])) $in['anniversary']=''; + if(!preg_match('/\d\d\d\d-\d\d-\d\d/',$in['birthday'])) $in['birthday']=''; + + // we map all internal names to the configured LDAP attributes here + foreach($in as $key => $value){ + if($FIELDS[$key]){ + // normal mapped field + $out[$FIELDS[$key]][] = $value; + }elseif($FIELDS["_$key"]){ + // mapped multi field + if(is_array($value)){ + $out[$FIELDS["_$key"]] = $value; + }else{ + $out[$FIELDS["_$key"]][] = $value; //shouldn't happen, but to be sure + } }else{ - $out[$keyname][] = $in[$key]; + // no mapping found - assume it to be a LDAP attribute (shouldn't happen) + if(is_array($value)){ + $out[$key] = $value; + }else{ + $out[$key][] = $value; + } } } - //standard Objectclass - $out[objectclass][] = 'inetOrgPerson'; - if($conf[extended]){ - $out[objectclass][] = 'contactPerson'; - } - - utf8_encode_array($out); + // add the Objectclasses + $out['objectclass'] = $OCLASSES; return clear_array($out); } @@ -254,16 +303,17 @@ function get_users(){ global $conf; global $LDAP_CON; - $sr = ldap_list($LDAP_CON,$conf[usertree],"ObjectClass=inetOrgPerson"); + $sr = ldap_list($LDAP_CON,$conf['usertree'],"ObjectClass=inetOrgPerson"); $result = ldap_get_binentries($LDAP_CON, $sr); + $users = array(); if(count($result)){ foreach ($result as $entry){ - if(!empty($entry[sn][0])){ - $users[$entry[dn]] = $entry[givenName][0]." ".$entry[sn][0]; + if(!empty($entry['sn'][0])){ + $users[$entry['dn']] = $entry['givenName'][0]." ".$entry['sn'][0]; } } } - return $users; + return $users; } /** @@ -285,9 +335,9 @@ function ldap_store_objectclasses($dn,$classes){ $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; + $set = $result[0]['objectClass']; + $set = array_unique_renumber(array_merge((array)$set,(array)$classes)); + $add['objectClass'] = $set; $r = @ldap_mod_replace($LDAP_CON,$dn,$add); tpl_ldaperror(); @@ -297,6 +347,52 @@ function ldap_store_objectclasses($dn,$classes){ 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((array)$result1,(array)$result2); +} + /** * Makes array unique and renumbers the entries * @@ -312,10 +408,44 @@ function array_unique_renumber($somearray){ 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