| [ Index ] |
|
Code source de eGroupWare 1.2.106-2 |
1 <?php 2 /**************************************************************************\ 3 * eGroupWare API - Session management * 4 * This file written by Dan Kuykendall <seek3r@phpgroupware.org> * 5 * and Joseph Engo <jengo@phpgroupware.org> * 6 * and Ralf Becker <ralfbecker@outdoor-training.de> * 7 * Copyright (C) 2000, 2001 Dan Kuykendall * 8 * Parts Copyright (C) 2003 Free Software Foundation Inc * 9 * -------------------------------------------------------------------------* 10 * This library is part of the eGroupWare API * 11 * http://www.egroupware.org/api * 12 * ------------------------------------------------------------------------ * 13 * This library is free software; you can redistribute it and/or modify it * 14 * under the terms of the GNU Lesser General Public License as published by * 15 * the Free Software Foundation; either version 2.1 of the License, * 16 * or any later version. * 17 * This library is distributed in the hope that it will be useful, but * 18 * WITHOUT ANY WARRANTY; without even the implied warranty of * 19 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. * 20 * See the GNU Lesser General Public License for more details. * 21 * You should have received a copy of the GNU Lesser General Public License * 22 * along with this library; if not, write to the Free Software Foundation, * 23 * Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA * 24 \**************************************************************************/ 25 26 /* $Id: class.sessions.inc.php 21940 2006-06-23 19:14:55Z lkneschke $ */ 27 28 /** 29 * Session Management Libabray 30 * 31 * This allows eGroupWare to use php4 or database sessions 32 * 33 * @package api 34 * @subpackage sessions 35 * @author NetUSE AG Boris Erdmann, Kristian Koehntopp <br> hacked on by phpGW 36 * @copyright © 1998-2000 NetUSE AG Boris Erdmann, Kristian Koehntopp <br> © 2003 FreeSoftware Foundation 37 * @license LGPL 38 * @link http://www.sanisoft.com/phplib/manual/DB_sql.php 39 */ 40 41 class sessions_ 42 { 43 /** 44 * @var string current user login 45 */ 46 var $login; 47 48 /** 49 * @var string current user password 50 */ 51 var $passwd; 52 53 /** 54 * @var int current user db/ldap account id 55 */ 56 var $account_id; 57 58 /** 59 * @var string current user account login id - ie user@domain 60 */ 61 var $account_lid; 62 63 /** 64 * @var string previous page call id - repost prevention 65 */ 66 var $history_id; 67 68 /** 69 * @var string domain for current user 70 */ 71 var $account_domain; 72 73 /** 74 * @var session type flag, A - anonymous session, N - None, normal session 75 */ 76 var $session_flags; 77 78 /** 79 * @var string current user session id 80 */ 81 var $sessionid; 82 83 /** 84 * @var string not sure what this does, but it is important :) 85 */ 86 var $kp3; 87 88 /** 89 * @var string encryption key? 90 */ 91 var $key; 92 93 /** 94 * @var string iv == ivegotnoidea ;) (skwashd) 95 */ 96 var $iv; 97 98 /** 99 * @var session data 100 */ 101 var $data; 102 103 /** 104 * @var object holder for the database object 105 */ 106 var $db; 107 108 /** 109 * @var $access_table name of access-log table 110 */ 111 var $access_table = 'egw_access_log'; 112 113 /** 114 * @var array publicly available methods 115 */ 116 var $public_functions = array( 117 'list_methods' => True, 118 'update_dla' => True, 119 'list' => True, 120 'total' => True 121 ); 122 123 /** 124 * @var string domain for cookies 125 */ 126 var $cookie_domain; 127 128 /** 129 * @var name of XML-RPC/SOAP method called 130 */ 131 var $xmlrpc_method_called; 132 133 /** 134 * @var Array with the name of the system domains 135 */ 136 var $phpgw_domains; 137 138 /** 139 * Constructor just loads up some defaults from cookies 140 */ 141 function sessions_($domain_names=null) 142 { 143 $this->db = clone($GLOBALS['egw']->db); 144 $this->db->set_app('phpgwapi'); 145 $this->sessionid = get_var('sessionid',array('GET','COOKIE')); 146 $this->kp3 = get_var('kp3',array('GET','COOKIE')); 147 148 $this->phpgw_domains = $domain_names; 149 150 /* Create the crypto object */ 151 $GLOBALS['egw']->crypto =& CreateObject('phpgwapi.crypto'); 152 if ($GLOBALS['egw_info']['server']['usecookies']) 153 { 154 $this->phpgw_set_cookiedomain(); 155 } 156 // verfiy and if necessary create and save our config settings 157 // 158 $save_rep = False; 159 if (!isset($GLOBALS['egw_info']['server']['max_access_log_age'])) 160 { 161 $GLOBALS['egw_info']['server']['max_access_log_age'] = 90; // default 90 days 162 $save_rep = True; 163 } 164 if (!isset($GLOBALS['egw_info']['server']['block_time'])) 165 { 166 $GLOBALS['egw_info']['server']['block_time'] = 30; // default 30min 167 $save_rep = True; 168 } 169 if (!isset($GLOBALS['egw_info']['server']['num_unsuccessful_id'])) 170 { 171 $GLOBALS['egw_info']['server']['num_unsuccessful_id'] = 3; // default 3 trys per id 172 $save_rep = True; 173 } 174 if (!isset($GLOBALS['egw_info']['server']['num_unsuccessful_ip'])) 175 { 176 $GLOBALS['egw_info']['server']['num_unsuccessful_ip'] = $GLOBALS['egw_info']['server']['num_unsuccessful_id']; // default same as for id 177 $save_rep = True; 178 } 179 if (!isset($GLOBALS['egw_info']['server']['install_id'])) 180 { 181 $GLOBALS['egw_info']['server']['install_id'] = md5($GLOBALS['egw']->common->randomstring(15)); 182 $save_rep = True; 183 } 184 if (!isset($GLOBALS['egw_info']['server']['sessions_timeout'])) 185 { 186 $GLOBALS['egw_info']['server']['sessions_timeout'] = 14400; 187 $save_rep = True; 188 } 189 if (!isset($GLOBALS['egw_info']['server']['sessions_app_timeout'])) 190 { 191 $GLOBALS['egw_info']['server']['sessions_app_timeout'] = 86400; 192 $save_rep = True; 193 } 194 if (!isset($GLOBALS['egw_info']['server']['max_history'])) 195 { 196 $GLOBALS['egw_info']['server']['max_history'] = 20; 197 $save_rep = True; 198 } 199 if ($save_rep) 200 { 201 $config = CreateObject('phpgwapi.config','phpgwapi'); 202 $config->read_repository(); 203 $config->value('max_access_log_age',$GLOBALS['egw_info']['server']['max_access_log_age']); 204 $config->value('block_time',$GLOBALS['egw_info']['server']['block_time']); 205 $config->value('num_unsuccessful_id',$GLOBALS['egw_info']['server']['num_unsuccessful_id']); 206 $config->value('num_unsuccessful_ip',$GLOBALS['egw_info']['server']['num_unsuccessful_ip']); 207 $config->value('install_id',$GLOBALS['egw_info']['server']['install_id']); 208 $config->value('sessions_timeout',$GLOBALS['egw_info']['server']['sessions_timeout']); 209 $config->value('sessions_app_timeout',$GLOBALS['egw_info']['server']['sessions_app_timeout']); 210 $config->save_repository(); 211 unset($config); 212 } 213 } 214 215 /** 216 * commit the sessiondata to storage (needs to be reimplemented for the subclasses) 217 * 218 * @return bool 219 */ 220 function commit_session() { 221 return true; 222 } 223 224 function split_login_domain($both,&$login,&$domain) 225 { 226 $parts = explode('@',$both); 227 228 // var_dump(debug_backtrace()); 229 //conference - for strings like vinicius@thyamad.com@default , 230 //allows that user have a login that is his e-mail. (viniciuscb) 231 if (count($parts) > 1) 232 { 233 $probable_domain = array_pop($parts); 234 //Last part of login string, when separated by @, is a domain name 235 if (in_array($probable_domain,$this->phpgw_domains)) 236 { 237 $got_login = true; 238 $domain = $probable_domain; 239 $login = implode('@',$parts); 240 } 241 } 242 243 if (!$got_login) 244 { 245 $domain = $GLOBALS['egw_info']['server']['default_domain']; 246 $login = $both; 247 } 248 } 249 250 /** 251 * Check to see if a session is still current and valid 252 * 253 * @param string $sessionid session id to be verfied 254 * @param string $kp3 ?? to be verified 255 * @return bool is the session valid? 256 */ 257 function verify($sessionid='',$kp3='') 258 { 259 $fill_egw_info_and_repositories = !$GLOBALS['egw_info']['flags']['restored_from_session']; 260 261 if(empty($sessionid) || !$sessionid) 262 { 263 $sessionid = get_var('sessionid',array('GET','COOKIE')); 264 $kp3 = get_var('kp3',array('GET','COOKIE')); 265 } 266 267 $this->sessionid = $sessionid; 268 $this->kp3 = $kp3; 269 270 $session = $this->read_session(); 271 //echo "<pre>session::verify(id='$sessionid'): \n".print_r($session,True)."</pre>\n"; 272 /* 273 $fp = fopen('/tmp/session_verify','a+'); 274 fwrite($fp,"session::verify(id='$sessionid'): \n".print_r($session,True)."\n\n"); 275 fclose($fp); 276 */ 277 if ($session['session_dla'] <= (time() - $GLOBALS['egw_info']['server']['sessions_timeout'])) 278 { 279 $this->destroy($sessionid,$kp3); 280 return False; 281 } 282 283 $this->session_flags = $session['session_flags']; 284 285 $this->split_login_domain($session['session_lid'],$this->account_lid,$this->account_domain); 286 287 /* This is to ensure that we authenticate to the correct domain (might not be default) */ 288 if($this->account_domain != $GLOBALS['egw_info']['user']['domain']) 289 { 290 $GLOBALS['egw']->ADOdb = null; 291 $GLOBALS['egw_info']['user']['domain'] = $this->account_domain; 292 // reset the db 293 $GLOBALS['egw_info']['server']['db_host'] = $GLOBALS['egw_domain'][$this->account_domain]['db_host']; 294 $GLOBALS['egw_info']['server']['db_port'] = $GLOBALS['egw_domain'][$this->account_domain]['db_port']; 295 $GLOBALS['egw_info']['server']['db_name'] = $GLOBALS['egw_domain'][$this->account_domain]['db_name']; 296 $GLOBALS['egw_info']['server']['db_user'] = $GLOBALS['egw_domain'][$this->account_domain]['db_user']; 297 $GLOBALS['egw_info']['server']['db_pass'] = $GLOBALS['egw_domain'][$this->account_domain]['db_pass']; 298 $GLOBALS['egw_info']['server']['db_type'] = $GLOBALS['egw_domain'][$this->account_domain]['db_type']; 299 $GLOBALS['egw']->setup('',False); 300 } 301 $GLOBALS['egw_info']['user']['kp3'] = $this->kp3; 302 303 $this->update_dla(); 304 $this->account_id = $GLOBALS['egw']->accounts->name2id($this->account_lid); 305 if (!$this->account_id) 306 { 307 return False; 308 } 309 310 $GLOBALS['egw_info']['user']['account_id'] = $this->account_id; 311 312 /* init the crypto object before appsession call below */ 313 $this->key = md5($this->kp3 . $this->sessionid . @$GLOBALS['egw_info']['server']['encryptkey']); 314 $this->iv = $GLOBALS['egw_info']['server']['mcrypt_iv']; 315 $GLOBALS['egw']->crypto->init(array($this->key,$this->iv)); 316 317 if ($fill_egw_info_and_repositories) 318 { 319 $this->read_repositories(@$GLOBALS['egw_info']['server']['cache_phpgw_info']); 320 } 321 322 if ($this->user['expires'] != -1 && $this->user['expires'] < time()) 323 { 324 if(is_object($GLOBALS['egw']->log)) 325 { 326 $GLOBALS['egw']->log->message(array( 327 'text' => 'W-VerifySession, account loginid %1 is expired', 328 'p1' => $this->account_lid, 329 'line' => __LINE__, 330 'file' => __FILE__ 331 )); 332 $GLOBALS['egw']->log->commit(); 333 } 334 return False; 335 } 336 if ($fill_egw_info_and_repositories) 337 { 338 $GLOBALS['egw_info']['user'] = $this->user; 339 $GLOBALS['egw_info']['hooks'] = $this->hooks; 340 341 $GLOBALS['egw_info']['user']['session_ip'] = $session['session_ip']; 342 $GLOBALS['egw_info']['user']['passwd'] = base64_decode($this->appsession('password','phpgwapi')); 343 } 344 if ($this->account_domain != $GLOBALS['egw_info']['user']['domain']) 345 { 346 if(is_object($GLOBALS['egw']->log)) 347 { 348 $GLOBALS['egw']->log->message(array( 349 'text' => 'W-VerifySession, the domains %1 and %2 don\'t match', 350 'p1' => $userid_array[1], 351 'p2' => $GLOBALS['egw_info']['user']['domain'], 352 'line' => __LINE__, 353 'file' => __FILE__ 354 )); 355 $GLOBALS['egw']->log->commit(); 356 } 357 return False; 358 } 359 360 if (@$GLOBALS['egw_info']['server']['sessions_checkip']) 361 { 362 if((PHP_OS != 'Windows') && (PHP_OS != 'WINNT') && 363 (!$GLOBALS['egw_info']['user']['session_ip'] || $GLOBALS['egw_info']['user']['session_ip'] != $this->getuser_ip()) 364 ) 365 { 366 if(is_object($GLOBALS['egw']->log)) 367 { 368 // This needs some better wording 369 $GLOBALS['egw']->log->message(array( 370 'text' => 'W-VerifySession, IP %1 doesn\'t match IP %2 in session table', 371 'p1' => $this->getuser_ip(), 372 'p2' => $GLOBALS['egw_info']['user']['session_ip'], 373 'line' => __LINE__, 374 'file' => __FILE__ 375 )); 376 $GLOBALS['egw']->log->commit(); 377 } 378 return False; 379 } 380 } 381 382 if ($fill_egw_info_and_repositories) 383 { 384 $GLOBALS['egw']->acl->acl($this->account_id); 385 $GLOBALS['egw']->accounts->accounts($this->account_id); 386 $GLOBALS['egw']->preferences->preferences($this->account_id); 387 $GLOBALS['egw']->applications->applications($this->account_id); 388 } 389 if (! $this->account_lid) 390 { 391 if(is_object($GLOBALS['egw']->log)) 392 { 393 // This needs some better wording 394 $GLOBALS['egw']->log->message(array( 395 'text' => 'W-VerifySession, account_id is empty', 396 'line' => __LINE__, 397 'file' => __FILE__ 398 )); 399 $GLOBALS['egw']->log->commit(); 400 } 401 //echo 'DEBUG: Sessions: account_id is empty!<br>'."\n"; 402 return False; 403 } 404 return True; 405 } 406 407 /** 408 * Functions for creating and verifying the session 409 */ 410 411 /** 412 * Get the ip address of current users 413 * 414 * @return string ip address 415 */ 416 function getuser_ip() 417 { 418 return (isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR']); 419 } 420 421 /** 422 * Set the domain used for cookies 423 * 424 * @return string domain 425 */ 426 function phpgw_set_cookiedomain() 427 { 428 // Use HTTP_X_FORWARDED_HOST if set, which is the case behind a none-transparent proxy 429 $this->cookie_domain = isset($_SERVER['HTTP_X_FORWARDED_HOST']) ? $_SERVER['HTTP_X_FORWARDED_HOST'] : $_SERVER['HTTP_HOST']; 430 431 // remove port from HTTP_HOST 432 if (preg_match("/^(.*):(.*)$/",$this->cookie_domain,$arr)) 433 { 434 $this->cookie_domain = $arr[1]; 435 } 436 if (count(explode('.',$this->cookie_domain)) <= 1) 437 { 438 // setcookie dont likes domains without dots, leaving it empty, gets setcookie to fill the domain in 439 $this->cookie_domain = ''; 440 } 441 print_debug('COOKIE_DOMAIN',$this->cookie_domain,'api'); 442 443 $this->set_cookie_params($this->cookie_domain); // for php4 sessions necessary 444 } 445 446 /** 447 * Set a cookie 448 * 449 * @param string $cookiename name of cookie to be set 450 * @param string $cookievalue value to be used, if unset cookie is cleared (optional) 451 * @param int $cookietime when cookie should expire, 0 for session only (optional) 452 */ 453 function phpgw_setcookie($cookiename,$cookievalue='',$cookietime=0) 454 { 455 if (!$this->cookie_domain) 456 { 457 $this->phpgw_set_cookiedomain(); 458 } 459 setcookie($cookiename,$cookievalue,$cookietime,'/',$this->cookie_domain); 460 } 461 462 /** 463 * Create a new session 464 * 465 * @param string $login user login 466 * @param string $passwd user password 467 * @param string $passwd_type type of password being used, ie plaintext, md5, sha1 468 * @return string session id 469 */ 470 function create($login,$passwd = '',$passwd_type = '') 471 { 472 if (is_array($login)) 473 { 474 $this->login = $login['login']; 475 $this->passwd = $login['passwd']; 476 $this->passwd_type = $login['passwd_type']; 477 $login = $this->login; 478 } 479 else 480 { 481 $this->login = $login; 482 $this->passwd = $passwd; 483 $this->passwd_type = $passwd_type; 484 } 485 486 $this->clean_sessions(); 487 $this->split_login_domain($login,$this->account_lid,$this->account_domain); 488 // add domain to the login, if not already there 489 if (substr($this->login,-strlen($this->account_domain)-1) != '@'.$this->account_domain) 490 { 491 $this->login .= '@'.$this->account_domain; 492 } 493 $now = time(); 494 495 /* This is to ensure that we authenticate to the correct domain (might not be default) */ 496 if($this->account_domain != $GLOBALS['egw_info']['user']['domain']) 497 { 498 $GLOBALS['egw']->ADOdb = null; 499 $GLOBALS['egw_info']['user']['domain'] = $this->account_domain; 500 // reset the db 501 $GLOBALS['egw_info']['server']['db_host'] = $GLOBALS['egw_domain'][$this->account_domain]['db_host']; 502 $GLOBALS['egw_info']['server']['db_port'] = $GLOBALS['egw_domain'][$this->account_domain]['db_port']; 503 $GLOBALS['egw_info']['server']['db_name'] = $GLOBALS['egw_domain'][$this->account_domain]['db_name']; 504 $GLOBALS['egw_info']['server']['db_user'] = $GLOBALS['egw_domain'][$this->account_domain]['db_user']; 505 $GLOBALS['egw_info']['server']['db_pass'] = $GLOBALS['egw_domain'][$this->account_domain]['db_pass']; 506 $GLOBALS['egw_info']['server']['db_type'] = $GLOBALS['egw_domain'][$this->account_domain]['db_type']; 507 $GLOBALS['egw']->setup('',False); 508 } 509 510 //echo "<p>session::create(login='$login'): lid='$this->account_lid', domain='$this->account_domain'</p>\n"; 511 $user_ip = $this->getuser_ip(); 512 513 $this->account_id = $GLOBALS['egw']->accounts->name2id($this->account_lid); 514 515 if (($blocked = $this->login_blocked($login,$user_ip)) || // too many unsuccessful attempts 516 $GLOBALS['egw_info']['server']['global_denied_users'][$this->account_lid] || 517 !$GLOBALS['egw']->auth->authenticate($this->account_lid, $this->passwd, $this->passwd_type) || 518 $this->account_id && $GLOBALS['egw']->accounts->get_type($this->account_id) == 'g') 519 { 520 $this->reason = $blocked ? 'blocked, too many attempts' : 'bad login or password'; 521 $this->cd_reason = $blocked ? 99 : 5; 522 523 $this->log_access($this->reason,$login,$user_ip,0); // log unsuccessfull login 524 return False; 525 } 526 527 if (!$this->account_id && $GLOBALS['egw_info']['server']['auto_create_acct']) 528 { 529 if ($GLOBALS['egw_info']['server']['auto_create_acct'] == 'lowercase') 530 { 531 $this->account_lid = strtolower($this->account_lid); 532 } 533 $this->account_id = $GLOBALS['egw']->accounts->auto_add($this->account_lid, $passwd); 534 } 535 536 $GLOBALS['egw_info']['user']['account_id'] = $this->account_id; 537 $GLOBALS['egw']->accounts->accounts($this->account_id); 538 $this->sessionid = $this->new_session_id(); 539 $this->kp3 = md5($GLOBALS['egw']->common->randomstring(15)); 540 541 if ($GLOBALS['egw_info']['server']['usecookies']) 542 { 543 $this->phpgw_setcookie('sessionid',$this->sessionid); 544 $this->phpgw_setcookie('kp3',$this->kp3); 545 $this->phpgw_setcookie('domain',$this->account_domain); 546 } 547 if ($GLOBALS['egw_info']['server']['usecookies'] || isset($_COOKIE['last_loginid'])) 548 { 549 $this->phpgw_setcookie('last_loginid', $this->account_lid ,$now+1209600); /* For 2 weeks */ 550 $this->phpgw_setcookie('last_domain',$this->account_domain,$now+1209600); 551 } 552 unset($GLOBALS['egw_info']['server']['default_domain']); /* we kill this for security reasons */ 553 554 /* init the crypto object */ 555 $this->key = md5($this->kp3 . $this->sessionid . $GLOBALS['egw_info']['server']['encryptkey']); 556 $this->iv = $GLOBALS['egw_info']['server']['mcrypt_iv']; 557 $GLOBALS['egw']->crypto->init(array($this->key,$this->iv)); 558 559 $this->read_repositories(False); 560 if ($this->user['expires'] != -1 && $this->user['expires'] < time()) 561 { 562 if(is_object($GLOBALS['egw']->log)) 563 { 564 $GLOBALS['egw']->log->message(array( 565 'text' => 'W-LoginFailure, account loginid %1 is expired', 566 'p1' => $this->account_lid, 567 'line' => __LINE__, 568 'file' => __FILE__ 569 )); 570 $GLOBALS['egw']->log->commit(); 571 } 572 $this->reason = 'account is expired'; 573 $this->cd_reason = 98; 574 575 return False; 576 } 577 578 $GLOBALS['egw_info']['user'] = $this->user; 579 $GLOBALS['egw_info']['hooks'] = $this->hooks; 580 581 $this->appsession('password','phpgwapi',base64_encode($this->passwd)); 582 if ($GLOBALS['egw']->acl->check('anonymous',1,'phpgwapi')) 583 { 584 $session_flags = 'A'; 585 } 586 else 587 { 588 $session_flags = 'N'; 589 } 590 591 $GLOBALS['egw']->db->transaction_begin(); 592 $this->register_session($this->login,$user_ip,$now,$session_flags); 593 if ($session_flags != 'A') // dont log anonymous sessions 594 { 595 $this->log_access($this->sessionid,$login,$user_ip,$this->account_id); 596 } 597 $this->appsession('account_previous_login','phpgwapi',$GLOBALS['egw']->auth->previous_login); 598 $GLOBALS['egw']->accounts->update_lastlogin($this->account_id,$user_ip); 599 $GLOBALS['egw']->db->transaction_commit(); 600 601 //if (!$this->sessionid) echo "<p>session::create(login='$login') = '$this->sessionid': lid='$this->account_lid', domain='$this->account_domain'</p>\n"; 602 603 return $this->sessionid; 604 } 605 606 /** 607 * Write or update (for logout) the access_log 608 * 609 * @param string $sessionid id of session or 0 for unsuccessful logins 610 * @param string $login account_lid (evtl. with domain) or '' for settion the logout-time 611 * @param string $user_ip ip to log 612 * @param int $account_id numerical account_id 613 */ 614 function log_access($sessionid,$login='',$user_ip='',$account_id='') 615 { 616 $now = time(); 617 618 if ($login) 619 { 620 if (strlen($login) > 30) 621 { 622 $login = substr($login,0,30); 623 } 624 $GLOBALS['egw']->db->insert($this->access_table,array( 625 'sessionid' => $sessionid, 626 'loginid' => $login, 627 'ip' => $user_ip, 628 'li' => $now, 629 'lo' => 0, 630 'account_id'=> $account_id, 631 ),false,__LINE__,__FILE__); 632 } 633 else 634 { 635 $GLOBALS['egw']->db->update($this->access_table,array('lo' => $now),array('sessionid' => $sessionid),__LINE__,__FILE__); 636 } 637 if ($GLOBALS['egw_info']['server']['max_access_log_age']) 638 { 639 $max_age = $now - $GLOBALS['egw_info']['server']['max_access_log_age'] * 24 * 60 * 60; 640 641 $GLOBALS['egw']->db->delete($this->access_table,"li < $max_age",__LINE__,__FILE__); 642 } 643 } 644 645 /** 646 * Protect against brute force attacks, block login if too many unsuccessful login attmepts 647 * 648 * @param string $login account_lid (evtl. with domain) 649 * @param string $ip ip of the user 650 * @returns bool login blocked? 651 */ 652 function login_blocked($login,$ip) 653 { 654 $blocked = False; 655 $block_time = time() - $GLOBALS['egw_info']['server']['block_time'] * 60; 656 657 $this->db->select($this->access_table,'COUNT(*)',array( 658 'account_id = 0', 659 'ip' => $ip, 660 "li > $block_time", 661 ),__LINE__,__FILE__); 662 $this->db->next_record(); 663 if (($false_ip = $this->db->f(0)) > $GLOBALS['egw_info']['server']['num_unsuccessful_ip']) 664 { 665 //echo "<p>login_blocked: ip='$ip' ".$this->db->f(0)." trys (".$GLOBALS['egw_info']['server']['num_unsuccessful_ip']." max.) since ".date('Y/m/d H:i',$block_time)."</p>\n"; 666 $blocked = True; 667 } 668 $this->db->select($this->access_table,'COUNT(*)',array( 669 'account_id = 0', 670 '(loginid = '.$this->db->quote($login).' OR loginid LIKE '.$this->db->quote($login.'@%').')', 671 "li > $block_time", 672 ),__LINE__,__FILE__); 673 $this->db->next_record(); 674 if (($false_id = $this->db->f(0)) > $GLOBALS['egw_info']['server']['num_unsuccessful_id']) 675 { 676 //echo "<p>login_blocked: login='$login' ".$this->db->f(0)." trys (".$GLOBALS['egw_info']['server']['num_unsuccessful_id']." max.) since ".date('Y/m/d H:i',$block_time)."</p>\n"; 677 $blocked = True; 678 } 679 if ($blocked && $GLOBALS['egw_info']['server']['admin_mails'] && 680 // max. one mail each 5mins 681 $GLOBALS['egw_info']['server']['login_blocked_mail_time'] < time()-5*60) 682 { 683 // notify admin(s) via email 684 $from = 'eGroupWare@'.$GLOBALS['egw_info']['server']['mail_suffix']; 685 $subject = lang("eGroupWare: login blocked for user '%1', IP %2",$login,$ip); 686 $body = lang("Too many unsucessful attempts to login: %1 for the user '%2', %3 for the IP %4",$false_id,$login,$false_ip,$ip); 687 688 if(!is_object($GLOBALS['egw']->send)) 689 { 690 $GLOBALS['egw']->send = CreateObject('phpgwapi.send'); 691 } 692 $subject = $GLOBALS['egw']->send->encode_subject($subject); 693 $admin_mails = explode(',',$GLOBALS['egw_info']['server']['admin_mails']); 694 foreach($admin_mails as $to) 695 { 696 $GLOBALS['egw']->send->msg('email',$to,$subject,$body,'','','',$from,$from); 697 } 698 // save time of mail, to not send to many mails 699 $config = CreateObject('phpgwapi.config','phpgwapi'); 700 $config->read_repository(); 701 $config->value('login_blocked_mail_time',time()); 702 $config->save_repository(); 703 } 704 return $blocked; 705 } 706 707 /** 708 * Verfy a peer server access request 709 * 710 * @param string $sessionid session id to verfiy 711 * @param string $kp3 ?? 712 * @return bool verfied? 713 */ 714 function verify_server($sessionid, $kp3) 715 { 716 $GLOBALS['egw']->interserver = CreateObject('phpgwapi.interserver'); 717 $this->sessionid = $sessionid; 718 $this->kp3 = $kp3; 719 720 $session = $this->read_session(); 721 $this->session_flags = $session['session_flags']; 722 723 list($this->account_lid,$this->account_domain) = explode('@', $session['session_lid']); 724 725 if ($this->account_domain == '') 726 { 727 $this->account_domain = $GLOBALS['egw_info']['server']['default_domain']; 728 } 729 730 $GLOBALS['egw_info']['user']['kp3'] = $this->kp3; 731 $phpgw_info_flags = $GLOBALS['egw_info']['flags']; 732 733 $GLOBALS['egw_info']['flags'] = $phpgw_info_flags; 734 735 $this->update_dla(); 736 $this->account_id = $GLOBALS['egw']->interserver->name2id($this->account_lid); 737 738 if (!$this->account_id) 739 { 740 return False; 741 } 742 743 $GLOBALS['egw_info']['user']['account_id'] = $this->account_id; 744 745 $this->read_repositories(@$GLOBALS['egw_info']['server']['cache_phpgw_info']); 746 747 /* init the crypto object before appsession call below */ 748 $this->key = md5($this->kp3 . $this->sessionid . $GLOBALS['egw_info']['server']['encryptkey']); 749 $this->iv = $GLOBALS['egw_info']['server']['mcrypt_iv']; 750 $GLOBALS['egw']->crypto->init(array($this->key,$this->iv)); 751 752 $GLOBALS['egw_info']['user'] = $this->user; 753 $GLOBALS['egw_info']['hooks'] = $this->hooks; 754 755 $GLOBALS['egw_info']['user']['session_ip'] = $session['session_ip']; 756 $GLOBALS['egw_info']['user']['passwd'] = base64_decode($this->appsession('password','phpgwapi')); 757 758 if ($userid_array[1] != $GLOBALS['egw_info']['user']['domain']) 759 { 760 if(is_object($GLOBALS['egw']->log)) 761 { 762 $GLOBALS['egw']->log->message(array( 763 'text' => 'W-VerifySession, the domains %1 and %2 don\t match', 764 'p1' => $userid_array[1], 765 'p2' => $GLOBALS['egw_info']['user']['domain'], 766 'line' => __LINE__, 767 'file' => __FILE__ 768 )); 769 $GLOBALS['egw']->log->commit(); 770 } 771 772 if(is_object($GLOBALS['egw']->crypto)) 773 { 774 $GLOBALS['egw']->crypto->cleanup(); 775 unset($GLOBALS['egw']->crypto); 776 } 777 return False; 778 } 779 780 if(@$GLOBALS['egw_info']['server']['sessions_checkip']) 781 { 782 if((PHP_OS != 'Windows') && (PHP_OS != 'WINNT') && 783 (!$GLOBALS['egw_info']['user']['session_ip'] || $GLOBALS['egw_info']['user']['session_ip'] != $this->getuser_ip()) 784 ) 785 { 786 if(is_object($GLOBALS['egw']->log)) 787 { 788 // This needs some better wording 789 $GLOBALS['egw']->log->message(array( 790 'text' => 'W-VerifySession, IP %1 doesn\'t match IP %2 in session table', 791 'p1' => $this->getuser_ip(), 792 'p2' => $GLOBALS['egw_info']['user']['session_ip'], 793 'line' => __LINE__, 794 'file' => __FILE__ 795 )); 796 $GLOBALS['egw']->log->commit(); 797 } 798 799 if(is_object($GLOBALS['egw']->crypto)) 800 { 801 $GLOBALS['egw']->crypto->cleanup(); 802 unset($GLOBALS['egw']->crypto); 803 } 804 return False; 805 } 806 } 807 808 $GLOBALS['egw']->acl->acl($this->account_id); 809 $GLOBALS['egw']->accounts->accounts($this->account_id); 810 $GLOBALS['egw']->preferences->preferences($this->account_id); 811 $GLOBALS['egw']->applications->applications($this->account_id); 812 813 if (! $this->account_lid) 814 { 815 if(is_object($GLOBALS['egw']->log)) 816 { 817 // This needs some better wording 818 $GLOBALS['egw']->log->message(array( 819 'text' => 'W-VerifySession, account_id is empty', 820 'line' => __LINE__, 821 'file' => __FILE__ 822 )); 823 $GLOBALS['egw']->log->commit(); 824 } 825 826 if(is_object($GLOBALS['egw']->crypto)) 827 { 828 $GLOBALS['egw']->crypto->cleanup(); 829 unset($GLOBALS['egw']->crypto); 830 } 831 return False; 832 } 833 else 834 { 835 return True; 836 } 837 } 838 839 /** 840 * Validate a peer server login request 841 * 842 * @param string $login login name 843 * @param string $password password 844 * @return bool login ok? 845 */ 846 function create_server($login,$passwd) 847 { 848 $GLOBALS['egw']->interserver = CreateObject('phpgwapi.interserver'); 849 // $this->login = $login; 850 $this->passwd = $passwd; 851 $this->clean_sessions(); 852 $login_array = explode('@', $login); 853 // $this->account_lid = $login_array[0]; 854 $now = time(); 855 856 $this->split_login_domain($login,$this->account_lid,$this->account_domain); 857 $this->login = $this->account_lid . '@' . $this->account_domain; 858 859 $serverdata = array( 860 'server_name' => $this->account_domain, 861 'username' => $this->account_lid, 862 'password' => $passwd 863 ); 864 if (!$GLOBALS['egw']->interserver->auth($serverdata)) 865 { 866 return False; 867 exit; 868 } 869 870 if (!$GLOBALS['egw']->interserver->exists($this->account_lid)) 871 { 872 $this->account_id = $GLOBALS['egw']->interserver->name2id($this->account_lid); 873 } 874 $GLOBALS['egw_info']['user']['account_id'] = $this->account_id; 875 $GLOBALS['egw']->interserver->serverid = $this->account_id; 876 877 $this->sessionid = md5($GLOBALS['egw']->common->randomstring(10)); 878 $this->kp3 = md5($GLOBALS['egw']->common->randomstring(15)); 879 880 /* re-init the crypto object */ 881 $this->key = md5($this->kp3 . $this->sessionid . $GLOBALS['egw_info']['server']['encryptkey']); 882 $this->iv = $GLOBALS['egw_info']['server']['mcrypt_iv']; 883 $GLOBALS['egw']->crypto->init(array($this->key,$this->iv)); 884 885 //$this->read_repositories(False); 886 887 $GLOBALS['egw_info']['user'] = $this->user; 888 $GLOBALS['egw_info']['hooks'] = $this->hooks; 889 890 $this->appsession('password','phpgwapi',base64_encode($this->passwd)); 891 $session_flags = 'S'; 892 893 $user_ip = $this->getuser_ip(); 894 895 $GLOBALS['egw']->db->transaction_begin(); 896 $this->register_session($login,$user_ip,$now,$session_flags); 897 898 $this->log_access($this->sessionid,$login,$user_ip,$this->account_id); 899 900 $this->appsession('account_previous_login','phpgwapi',$GLOBALS['egw']->auth->previous_login); 901 $GLOBALS['egw']->accounts->update_lastlogin($this->account_id,$user_ip); 902 $GLOBALS['egw']->db->transaction_commit(); 903 904 return array($this->sessionid,$this->kp3); 905 } 906 907 /** 908 * Functions for appsession data and session cache 909 */ 910 911 /** 912 * Is this also useless?? (skwashd) 913 */ 914 function read_repositories($cached='',$write_cache=True) 915 { 916 $GLOBALS['egw']->acl->acl($this->account_id); 917 $GLOBALS['egw']->accounts->accounts($this->account_id); 918 $GLOBALS['egw']->preferences->preferences($this->account_id); 919 $GLOBALS['egw']->applications->applications($this->account_id); 920 921 if(@$cached) 922 { 923 $this->user = $this->appsession('phpgw_info_cache','phpgwapi'); 924 if(!empty($this->user)) 925 { 926 $GLOBALS['egw']->preferences->data = $this->user['preferences']; 927 if (!isset($GLOBALS['egw_info']['apps']) || !is_array($GLOBALS['egw_info']['apps'])) 928 { 929 $GLOBALS['egw']->applications->read_installed_apps(); 930 } 931 } 932 else 933 { 934 $this->setup_cache($write_cache); 935 } 936 } 937 else 938 { 939 $this->setup_cache($write_cache); 940 } 941 $this->hooks = $GLOBALS['egw']->hooks->read(); 942 } 943 944 /** 945 * Is this also useless?? (skwashd) 946 */ 947 function setup_cache($write_cache=True) 948 { 949 $this->user = $GLOBALS['egw']->accounts->read_repository(); 950 $this->user['acl'] = $GLOBALS['egw']->acl->read_repository(); 951 $this->user['preferences'] = $GLOBALS['egw']->preferences->read_repository(); 952 if (is_object($GLOBALS['egw']->datetime)) 953 { 954 $GLOBALS['egw']->datetime->datetime(); // to set tz_offset from the now read prefs 955 } 956 $this->user['apps'] = $GLOBALS['egw']->applications->read_repository(); 957 //@reset($this->data['user']['apps']); 958 959 $this->user['domain'] = $this->account_domain; 960 $this->user['sessionid'] = $this->sessionid; 961 $this->user['kp3'] = $this->kp3; 962 $this->user['session_ip'] = $this->getuser_ip(); 963 $this->user['session_lid'] = $this->account_lid.'@'.$this->account_domain; 964 $this->user['account_id'] = $this->account_id; 965 $this->user['account_lid'] = $this->account_lid; 966 $this->user['userid'] = $this->account_lid; 967 $this->user['passwd'] = @$this->passwd; 968 if(@$GLOBALS['egw_info']['server']['cache_phpgw_info'] && $write_cache) 969 { 970 $this->delete_cache(); 971 $this->appsession('phpgw_info_cache','phpgwapi',$this->user); 972 } 973 } 974 975 /** 976 * This looks to be useless 977 * This will capture everything in the $GLOBALS['egw_info'] including server info, 978 * and store it in appsessions. This is really incompatible with any type of restoring 979 * from appsession as the saved user info is really in ['user'] rather than the root of 980 * the structure, which is what this class likes. 981 */ 982 function save_repositories() 983 { 984 $phpgw_info_temp = $GLOBALS['egw_info']; 985 $phpgw_info_temp['user']['kp3'] = ''; 986 $phpgw_info_temp['flags'] = array(); 987 988 if ($GLOBALS['egw_info']['server']['cache_phpgw_info']) 989 { 990 $this->appsession('phpgw_info_cache','phpgwapi',$phpgw_info_temp); 991 } 992 } 993 994 function restore() 995 { 996 $sessionData = $this->appsession('sessiondata'); 997 998 if (!empty($sessionData) && is_array($sessionData)) 999 { 1000 foreach($sessionData as $key => $value) 1001 { 1002 global $$key; 1003 $$key = $value; 1004 $this->variableNames[$key] = 'registered'; 1005 // echo 'restored: '.$key.', ' . $value . '<br>'; 1006 } 1007 } 1008 } 1009 1010 /** 1011 * Save the current values of all registered variables 1012 */ 1013 function save() 1014 { 1015 if (is_array($this->variableNames)) 1016 { 1017 reset($this->variableNames); 1018 while(list($key, $value) = each($this->variableNames)) 1019 { 1020 if ($value == 'registered') 1021 { 1022 global $$key; 1023 $sessionData[$key] = $$key; 1024 } 1025 } 1026 $this->appsession('sessiondata','',$sessionData); 1027 } 1028 } 1029 1030 /** 1031 * Create a list a variable names, which data needs to be restored 1032 * 1033 * @param string $_variableName name of variable to be registered 1034 */ 1035 function register($_variableName) 1036 { 1037 $this->variableNames[$_variableName]='registered'; 1038 #print 'registered '.$_variableName.'<br>'; 1039 } 1040 1041 /** 1042 * Mark variable as unregistered 1043 * 1044 * @param string $_variableName name of variable to deregister 1045 */ 1046 function unregister($_variableName) 1047 { 1048 $this->variableNames[$_variableName]='unregistered'; 1049 #print 'unregistered '.$_variableName.'<br>'; 1050 } 1051 1052 /** 1053 * Check if we have a variable registred already 1054 * 1055 * @param string $_variableName name of variable to check 1056 * @return bool was the variable found? 1057 */ 1058 function is_registered($_variableName) 1059 { 1060 if ($this->variableNames[$_variableName] == 'registered') 1061 { 1062 return True; 1063 } 1064 else 1065 { 1066 return False; 1067 } 1068 } 1069 /** 1070 * Additional tracking of user actions - prevents reposts/use of back button 1071 * 1072 * @deprecated not used in eGroupWare 1073 * @author skwashd 1074 * @return string current history id 1075 */ 1076 function generate_click_history() 1077 { 1078 if(!isset($this->history_id)) 1079 { 1080 $this->history_id = md5($this->login . time()); 1081 $history = $this->appsession($location = 'history', $appname = 'phpgwapi'); 1082 1083 if(count($history) >= $GLOBALS['egw_info']['server']['max_history']) 1084 { 1085 array_shift($history); 1086 $this->appsession($location = 'history', $appname = 'phpgwapi', $history); 1087 } 1088 } 1089 return $this->history_id; 1090 } 1091 1092 /** 1093 * Detects if the page has already been called before - good for forms 1094 * 1095 * @deprecated not used in eGroupWare 1096 * @author skwashd 1097 * @param bool $diplay_error when implemented will use the generic error handling code 1098 * @return True if called previously, else False - call ok 1099 */ 1100 function is_repost($display_error = False) 1101 { 1102 $history = $this->appsession($location = 'history', $appname = 'phpgwapi'); 1103 if(isset($history[$_GET['click_history']])) 1104 { 1105 if($display_error) 1106 { 1107 $GLOBALS['egw']->redirect_link('/error.php', 'type=repost');//more on this later :) 1108 } 1109 else 1110 { 1111 return True; //handled by the app 1112 } 1113 } 1114 else 1115 { 1116 $history[$_GET['click_history']] = True; 1117 $this->appsession($location = 'history', $appname = 'phpgwapi', $history); 1118 return False; 1119 } 1120 } 1121 1122 /** 1123 * Generate a url which supports url or cookies based sessions 1124 * 1125 * Please note, the values of the query get url encoded! 1126 * 1127 * @param string $url a url relative to the egroupware install root, it can contain a query too 1128 * @param array/string $extravars query string arguements as string or array (prefered) 1129 * @return string generated url 1130 */ 1131 function link($url, $extravars = '') 1132 { 1133 //echo "<p>session::link(url='$url',extravars='".print_r($extravars,True)."')"; 1134 1135 if ($url{0} != '/') 1136 { 1137 $app = $GLOBALS['egw_info']['flags']['currentapp']; 1138 if ($app != 'login' && $app != 'logout') 1139 { 1140 $url = $app.'/'.$url; 1141 } 1142 } 1143 1144 // append the url to the webserver url, but avoid more then one slash between the parts of the url 1145 if ($url{0} != '/' || $GLOBALS['egw_info']['server']['webserver_url'] != '/') 1146 { 1147 if($url{0} != '/' && substr($GLOBALS['egw_info']['server']['webserver_url'],-1) != '/') 1148 { 1149 $url = $GLOBALS['egw_info']['server']['webserver_url'] .'/'. $url; 1150 } 1151 else 1152 { 1153 $url = $GLOBALS['egw_info']['server']['webserver_url'] . $url; 1154 } 1155 } 1156 1157 if(@isset($GLOBALS['egw_info']['server']['enforce_ssl']) && $GLOBALS['egw_info']['server']['enforce_ssl']) // && !$_SERVER['HTTPS']) imho https should always be a full path - skwashd 1158 { 1159 if(substr($url ,0,4) != 'http') 1160 { 1161 $url = 'https://'.$GLOBALS['egw_info']['server']['hostname'].$url; 1162 } 1163 else 1164 { 1165 $url = str_replace ( 'http:', 'https:', $url); 1166 } 1167 } 1168 1169 // check if the url already contains a query and ensure that vars is an array and all strings are in extravars 1170 list($url,$othervars) = explode('?',$url); 1171 if ($extravars && is_array($extravars)) 1172 { 1173 $vars = $extravars; 1174 $extravars = $othervars; 1175 } 1176 else 1177 { 1178 $vars = array(); 1179 if ($othervars) $extravars .= '&'.$othervars; 1180 } 1181 1182 // parse extravars string into the vars array 1183 if ($extravars) 1184 { 1185 foreach(explode('&',$extravars) as $expr) 1186 { 1187 list($var,$val) = explode('=', $expr,2); 1188 if (substr($var,-2) == '[]') 1189 { 1190 $vars[substr($var,0,-2)][] = $val; 1191 } 1192 else 1193 { 1194 $vars[$var] = $val; 1195 } 1196 } 1197 } 1198 1199 // add session params if not using cookies 1200 if (!$GLOBALS['egw_info']['server']['usecookies']) 1201 { 1202 $vars['sessionid'] = $this->sessionid; 1203 $vars['kp3'] = $this->kp3; 1204 $vars['domain'] = $this->account_domain; 1205 } 1206 1207 // if there are vars, we add them urlencoded to the url 1208 if (count($vars)) 1209 { 1210 $query = array(); 1211 foreach($vars as $key => $value) 1212 { 1213 if (is_array($value)) 1214 { 1215 foreach($value as $val) 1216 { 1217 $query[] = $key.'[]='.urlencode($val); 1218 } 1219 } 1220 else 1221 { 1222 $query[] = $key.'='.urlencode($value); 1223 } 1224 } 1225 $url .= '?' . implode('&',$query); 1226 } 1227 //echo " = '$url'</p>\n"; 1228 return $url; 1229 } 1230 1231 /** 1232 * The remaining methods are abstract - as they are unique for each session handler 1233 */ 1234 1235 /** 1236 * Load user's session information 1237 * 1238 * The sessionid of the session to read is passed in the class-var $this->sessionid 1239 * 1240 * @return mixed the session data 1241 */ 1242 function read_session() 1243 {} 1244 1245 /** 1246 * Remove stale sessions out of the database 1247 */ 1248 function clean_sessions() 1249 {} 1250 1251 /** 1252 * Set paramaters for cookies - only implemented in PHP4 sessions 1253 * 1254 * @param string $domain domain name to use in cookie 1255 */ 1256 1257 function set_cookie_params($domain) 1258 {} 1259 1260 /** 1261 * Create a new session id 1262 * 1263 * @return string a new session id 1264 */ 1265 function new_session_id() 1266 {} 1267 1268 /** 1269 * Create a new session 1270 * 1271 * @param string $login user login 1272 * @param string $user_ip users ip address 1273 * @param int $now time now as a unix timestamp 1274 * @param string $session_flags A = Anonymous, N = Normal 1275 */ 1276 function register_session($login,$user_ip,$now,$session_flags) 1277 {} 1278 1279 /** 1280 * Update the date last active info for the session, so the login does not expire 1281 * 1282 * @return bool did it suceed? 1283 */ 1284 function update_dla() 1285 {} 1286 1287 /** 1288 * Terminate a session 1289 * 1290 * @param string $sessionid the id of the session to be terminated 1291 * @param string $kp3 - NOT SURE 1292 * @return bool did it suceed? 1293 */ 1294 function destroy($sessionid, $kp3) 1295 {} 1296 1297 /** 1298 * Functions for appsession data and session cache 1299 */ 1300 1301 /** 1302 * Delete all data from the session cache for a user 1303 * 1304 * @param int $accountid user account id, defaults to current user (optional) 1305 */ 1306 function delete_cache($accountid='') 1307 {} 1308 1309 /** 1310 * Stores or retrieves information from the sessions cache 1311 * 1312 * @param string $location identifier for data 1313 * @param string $appname name of app which is responsbile for the data 1314 * @param mixed $data data to be stored, if left blank data is retreived (optional) 1315 * @return mixed data from cache, only returned if $data arg is not used 1316 */ 1317 function appsession($location = 'default', $appname = '', $data = '##NOTHING##') 1318 {} 1319 1320 /** 1321 * Get list of normal / non-anonymous sessions 1322 * Note: The data from the session-files get cached in the app_session phpgwapi/php4_session_cache 1323 * 1324 * @author ralfbecker 1325 * @param int $start session to start at 1326 * @param string $order field to sort on 1327 * @param string $sort sort order 1328 * @param bool $all_no_sort list all with out sorting (optional) default False 1329 * @return array info for all current sessions 1330 */ 1331 function list_sessions($start,$order,$sort,$all_no_sort = False) 1332 {} 1333 1334 /** 1335 * Get the number of normal / non-anonymous sessions 1336 * 1337 * @author ralfbecker 1338 * @return int number of sessions 1339 */ 1340 function total() 1341 {} 1342 } 1343 1344 if(empty($GLOBALS['egw_info']['server']['sessions_type'])) 1345 { 1346 $GLOBALS['egw_info']['server']['sessions_type'] = 'php4'; // the more performant default 1347 } 1348 // for php4 sessions, check if the extension is loaded, try loading it and fallback to db sessions if not 1349 if (substr($GLOBALS['egw_info']['server']['sessions_type'],0,4) == 'php4' && !extension_loaded('session')) 1350 { 1351 // some constanst for pre php4.3 1352 if (!defined('PHP_SHLIB_SUFFIX')) 1353 { 1354 define('PHP_SHLIB_SUFFIX',strtoupper(substr(PHP_OS, 0,3)) == 'WIN' ? 'dll' : 'so'); 1355 } 1356 if (!defined('PHP_SHLIB_PREFIX')) 1357 { 1358 define('PHP_SHLIB_PREFIX',PHP_SHLIB_SUFFIX == 'dll' ? 'php_' : ''); 1359 } 1360 if (!function_exists('dl') || !@dl(PHP_SHLIB_PREFIX.'session'.'.'.PHP_SHLIB_SUFFIX)) 1361 { 1362 $GLOBALS['egw_info']['server']['sessions_type'] = 'db'; // fallback if we have no php sessions support 1363 } 1364 } 1365 include_once(EGW_API_INC.'/class.sessions_'.substr($GLOBALS['egw_info']['server']['sessions_type'],0,4).'.inc.php');
titre
Description
Corps
titre
Description
Corps
titre
Description
Corps
titre
Corps
| Généré le : Sun Feb 25 17:20:01 2007 | par Balluche grâce à PHPXref 0.7 |