* @author Joseph Engo * @author Ralf Becker * @copyright © 1998-2000 NetUSE AG Boris Erdmann, Kristian Koehntopp
© 2003 FreeSoftware Foundation * @license LGPL * @version $Id$ */ define('EGW_SESSION_VAR','egw_session'); // where to store our session-data $_SESSION[EGW_SESSION_VAR] /** * Session Management via php sessions * * @package api * @subpackage sessions */ class sessions extends sessions_ { var $save_session_vars_start; function sessions($domain_names=null) { $this->save_session_vars_start = $_SESSION; // store already set session vars $this->sessions_($domain_names); //controls the time out for php4 sessions - skwashd 18-May-2003 ini_set('session.gc_maxlifetime', $GLOBALS['egw_info']['server']['sessions_timeout']); session_name('sessionid'); } /** * commit the sessiondata to the filesystem * * @return bool */ function commit_session() { session_write_close(); return true; } function read_session() { if (!$this->sessionid) { return False; } session_id($this->sessionid); session_start(); return $_SESSION[EGW_SESSION_VAR]; } /** * Set paramaters for cookies - only implemented in PHP4 sessions * * @param string $domain domain name to use in cookie * @param string $path='/' path to use in cookie */ function set_cookie_params($domain,$path='/') { session_set_cookie_params(0,$path,$domain); } /** * Create a new session id, called by session::create() * * Reimplemented to use php session-id * * @return string a new session id */ function new_session_id() { session_start(); return session_id(); } function register_session($login,$user_ip,$now,$session_flags) { // restore session vars set before session was started if ($this->save_session_vars_start && is_array($this->save_session_vars_start)) { foreach($this->save_session_vars_start as $name => &$value) { //error_log(__METHOD__."() added $name=".array2string($value)); $_SESSION[$name] =& $value; } unset($this->save_session_vars_start); } $_SESSION[EGW_SESSION_VAR]['session_id'] = $this->sessionid; $_SESSION[EGW_SESSION_VAR]['session_lid'] = $login; $_SESSION[EGW_SESSION_VAR]['session_ip'] = $user_ip; $_SESSION[EGW_SESSION_VAR]['session_logintime'] = $now; $_SESSION[EGW_SESSION_VAR]['session_dla'] = $now; $_SESSION[EGW_SESSION_VAR]['session_action'] = $_SERVER['PHP_SELF']; $_SESSION[EGW_SESSION_VAR]['session_flags'] = $session_flags; // we need the install-id to differ between serveral installs shareing one tmp-dir $_SESSION[EGW_SESSION_VAR]['session_install_id'] = $GLOBALS['egw_info']['server']['install_id']; } // This will update the DateLastActive column, so the login does not expire function update_dla() { if (@isset($_GET['menuaction'])) { $action = $_GET['menuaction']; } else { $action = $_SERVER['PHP_SELF']; } // This way XML-RPC users aren't always listed as // xmlrpc.php if ($this->xmlrpc_method_called) { $action = $this->xmlrpc_method_called; } $_SESSION[EGW_SESSION_VAR]['session_dla'] = time(); $_SESSION[EGW_SESSION_VAR]['session_action'] = $action; return True; } function destroy($sessionid, $kp3) { if (!$sessionid && $kp3) { return False; } $this->log_access($this->sessionid); // log logout-time // Only do the following, if where working with the current user if ($sessionid == $GLOBALS['egw_info']['user']['sessionid']) { session_unset(); //echo "

sessions_php4::destroy: session_destroy() returned ".(session_destroy() ? 'True' : 'False')."

\n"; @session_destroy(); if ($GLOBALS['egw_info']['server']['usecookies']) { $this->egw_setcookie(session_name()); } } else { $sessions = $this->list_sessions(0,'','',True); if (isset($sessions[$sessionid])) { //echo "

session_php4::destroy($session_id): unlink('".$sessions[$sessionid]['php_session_file']."')

\n"; @unlink($sessions[$sessionid]['php_session_file']); } } return True; } /*************************************************************************\ * Functions for appsession data and session cache * \*************************************************************************/ function delete_cache($accountid='') { $account_id = get_account_id($accountid,$this->account_id); $_SESSION[EGW_SESSION_VAR]['app_sessions']['phpgwapi']['phpgw_info_cache'] = ''; } function appsession($location = 'default', $appname = '', $data = '##NOTHING##') { if (! $appname) { $appname = $GLOBALS['egw_info']['flags']['currentapp']; } /* This allows the user to put '' as the value. */ if ($data === '##NOTHING##') { /* do not decrypt and return if no data (decrypt returning garbage) */ if($_SESSION[EGW_SESSION_VAR]['app_sessions'][$appname][$location]) { return $GLOBALS['egw']->crypto->decrypt($_SESSION[EGW_SESSION_VAR]['app_sessions'][$appname][$location]); } return false; } $_SESSION[EGW_SESSION_VAR]['app_sessions'][$appname][$location] = $GLOBALS['egw']->crypto->encrypt($data); return $data; } function session_sort($a,$b) { $sign = strcasecmp($GLOBALS['egw']->session->sort_order,'ASC') ? 1 : -1; return strcasecmp( $a[$GLOBALS['egw']->session->sort_by], $b[$GLOBALS['egw']->session->sort_by] ) * $sign; } /** * get list of normal / non-anonymous sessions (works only for session.handler = files!, but that's the default) * * The data from the session-files get cached in the app_session phpgwapi/php4_session_cache * * @author RalfBecker-AT-outdoor-training.de */ function list_sessions($start,$order,$sort,$all_no_sort = False) { //echo "

session_php4::list_sessions($start,'$order','$sort',$all)

\n"; $session_cache = $this->appsession('php4_session_cache','phpgwapi'); $values = array(); $maxmatchs = $GLOBALS['egw_info']['user']['preferences']['common']['maxmatchs']; $dir = @opendir($path = ini_get('session.save_path')); if (!$dir || !@file_exists($path.'/.')) // eg. openbasedir restrictions, or dir not listable { return $values; } if (!($max_session_size = ini_get('memory_limit'))) $max_session_size = '16M'; switch(strtoupper(substr($max_session_size,-1))) { case 'M': $max_session_size *= 1024*1024; break; case 'K': $max_session_size *= 1024; break; } $max_session_size /= 4; // use at max 1/4 of the memory_limit to read sessions, the others get ignored while (($file = readdir($dir))) { if ($file{0} == '.' || filesize($path.'/'.$file) >= $max_session_size) continue; if (substr($file,0,5) != 'sess_' || $session_cache[$file] === false) { continue; } if (isset($session_cache[$file]) && !$session_cache[$file]) // session is marked as not to list (not ours or anonymous) { continue; } if (isset($session_cache[$file])) // use copy from cache { $session = $session_cache[$file]; if (!$all_no_sort || // we need the up-to-date data --> unset and reread it $session['session_dla'] <= (time() - $GLOBALS['egw_info']['server']['sessions_timeout'])) // cached dla is timeout { unset($session_cache[$file]); } } if (!isset($session_cache[$file])) // not in cache, read and cache it { if (!is_readable($path. '/' . $file)) { $session_cache[$file] = false; // dont try reading it again continue; // happens if webserver runs multiple user-ids } $session = ''; if (($fd = fopen ($path . '/' . $file,'r'))) { $session = ($size = filesize ($path . '/' . $file)) ? fread ($fd, $size) : 0; fclose ($fd); } if (substr($session,0,1+strlen(EGW_SESSION_VAR)) != EGW_SESSION_VAR.'|') { $session_cache[$file] = false; // dont try reading it again continue; } $session = unserialize(substr($session,1+strlen(EGW_SESSION_VAR))); unset($session['app_sessions']); // not needed, saves memory $session['php_session_file'] = $path . '/' . $file; $session_cache[$file] = $session; if($session['session_flags'] == 'A' || !$session['session_id'] || $session['session_install_id'] != $GLOBALS['egw_info']['server']['install_id']) { $session_cache[$file] = false; // dont try reading it again continue; // no anonymous sessions or other domains or installations } // check for and terminate sessions which are timed out ==> destroy them // this should be not necessary if php is configured right, but I'm sick of the questions on the list if ($session['session_dla'] <= (time() - $GLOBALS['egw_info']['server']['sessions_timeout'])) { //echo "session $session[session_id] is timed out !!!
\n"; @unlink($path . '/' . $file); $session_cache[$file] = false; continue; } } // ignore (empty) login sessions created by IE and konqueror, when clicking on [login] (double submission of the form) if ($session['session_action'] == $GLOBALS['egw_info']['server']['webserver_url'].'/login.php') continue; //echo "file='$file'=
"; print_r($session); echo "
"; $values[$session['session_id']] = $session; } closedir($dir); if(!$all_no_sort) { $GLOBALS['egw']->session->sort_by = $sort; $GLOBALS['egw']->session->sort_order = $order; uasort($values,array('sessions','session_sort')); $i = 0; $start = (int)$start; foreach($values as $id => $data) { if($i < $start || $i > $start+$maxmatchs) { unset($values[$id]); } ++$i; } reset($values); } $this->appsession('php4_session_cache','phpgwapi',$session_cache); return $values; } /** * get number of normal / non-anonymous sessions * * @author RalfBecker-AT-outdoor-training.de */ function total() { return count($this->list_sessions(0,'','',True)); } }