Main Page | Directories | File List | File Members

session.php

Go to the documentation of this file.
00001 <?php
00002 # This file is part of the Savane project
00003 # <http://gna.org/projects/savane/>
00004 #
00005 # $Id: session.php 5450 2006-02-19 18:00:27Z yeupou $
00006 #
00007 #  Copyright 1999-2000 (c) The SourceForge Crew
00008 #  Copyright 2000-2003 (c) Free Software Foundation
00009 #
00010 #  Copyright 2003-2005 (c) Mathieu Roy <yeupou--at--gnu.org>
00011 #                          Derek Feichtinger <derek.feichtinger--cern.ch>
00012 # 
00013 # The Savane project is free software; you can redistribute it and/or
00014 # modify it under the terms of the GNU General Public License
00015 # as published by the Free Software Foundation; either version 2
00016 # of the License, or (at your option) any later version.
00017 #
00018 # The Savane project is distributed in the hope that it will be useful,
00019 # but WITHOUT ANY WARRANTY; without even the implied warranty of
00020 # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00021 # GNU General Public License for more details.
00022 #
00023 # You should have received a copy of the GNU General Public License
00024 # along with the Savane project; if not, write to the Free Software
00025 # Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
00026 
00027 
00028 $G_SESSION=array();
00029 $G_USER=array();
00030 
00031 function session_login_valid($form_loginname,
00032                              $form_pw,
00033                              $allowpending=0,
00034                              $cookie_for_a_year=0,
00035                              $crypted_pw=0,
00036                              $stay_in_ssl=1)
00037 {
00038 
00039   # Password is crypted if we are coming from the brother site.
00040   # Normally, users should use this feature
00041   # if they never login at brother site.
00042   # FIXME: feel free to mess with PHP3 and crypt...
00043   global $session_hash;
00044   
00045   if (!$form_loginname || !$form_pw) 
00046     {
00047       fb(_('Missing Password Or User Name'), 1);
00048       return false;
00049     }
00050   
00051   $resq = db_query("SELECT user_id,user_pw,status FROM user WHERE "
00052                    . "user_name = '$form_loginname'");
00053   if (!$resq || db_numrows($resq) < 1) 
00054     {
00055       fb(_('Invalid User Name'), 1);
00056       return false;
00057     }
00058 
00059   $usr = db_fetch_array($resq);
00060 
00061   # Check status first:
00062   # if allowpending (for verify.php) then allow
00063   if ($allowpending && ($usr['status'] == 'P')) 
00064     {
00065       #1;
00066     } 
00067   else 
00068     {
00069       if ($usr['status'] == 'P') 
00070         { 
00071           #account pending
00072           fb(_('Account Pending'), 1);
00073           return false;
00074         } 
00075       if ($usr['status'] == 'D' || $usr['status'] == 'S')
00076         { 
00077           #account deleted
00078           fb(_('Account Deleted'), 1);
00079           return false;
00080         }
00081       if ($usr['status'] != 'A') 
00082         {
00083           #unacceptable account flag
00084           fb(_('Account Not Active'),1);
00085           return false;
00086         }
00087     }
00088 
00089 
00090 
00091   # TODO: Brother site login mechanism should be implemented later for
00092   #       all authentication methods:
00093   #
00094 
00095 
00096   #
00097   # authentication method: PAM based
00098   # this requires the 'pam_auth' php extension from
00099   # http:#www.math.ohio-state.edu/~ccunning/pam_auth.html
00100   #
00101   if($usr['user_pw'] == 'PAM') 
00102     {
00103       $pam_error='';
00104       if(! pam_auth($form_loginname, $form_pw, &$pam_error)) 
00105         {
00106           fb(_('Invalid Password (AFS)'), 1);
00107           return false;
00108         }
00109 
00110     } 
00111   else if ($usr['user_pw'] == '') 
00112     {
00113       #
00114       # authentication method: Kerberos
00115       # If both user_pw and unix_pw are empty the user might
00116       # be able to login if she/he has a Kerberos account.
00117       # Update unix_pw and user_pw.
00118       # TODO: THE KERBEROS PASSWORD SHOULD NOT BE STORED LOCALLY!!!!
00119       #
00120       if ($GLOBALS[sys_use_krb5])
00121         { $ret = krb5_login($form_loginname, $form_pw); }
00122 
00123       if($ret == KRB5_NOTOK) 
00124         {
00125           fb("phpkrb5 module failure", 1);
00126           return false;
00127         }
00128       if($ret == KRB5_BAD_USER) 
00129         {
00130           fb("user is not a kerberos principal", 1);
00131           return false;
00132         }
00133       if($ret == KRB5_BAD_PASSWORD) 
00134         {
00135           fb("user is a kerberos principal but passwords do not match", 1);
00136           return false;
00137         }
00138       $md5_pw = md5($form_pw);
00139       db_query("UPDATE user SET user_pw = '$md5_pw' WHERE user_id = ".$usr['user_id']);
00140     }
00141   else if($usr['user_pw'] == 'SSH') 
00142     {
00143       fb('This user is known but we have no way to authenticate her/him. Please ask for a password to site administrators', 1);
00144       return false;
00145       
00146     }
00147   else 
00148     {
00149       # Default authentication method:
00150       # MD5 encrypted password stored locally
00151 
00152       # For this authentication method we enable a brother site
00153       # login mechanism:
00154       # Password is crypted (crypt()) if we are coming from the brother site.
00155       # Normally, users shouldn't use this feature
00156       # unless they login at brother site one time.
00157       # FIXME: feel free to mess with PHP3 and crypt...
00158       if ($crypted_pw) 
00159         {
00160           if (crypt($usr['user_pw'],$form_pw) != $form_pw) 
00161             {
00162               #invalid password or user_name
00163               fb(_('Invalid Password'),1);
00164               return false;
00165             }
00166         } 
00167       else 
00168         {
00169           if ($usr['user_pw'] != md5($form_pw)) 
00170             {
00171               #invalid password or user_name
00172               fb(_('Invalid Password'),1);
00173               return false;
00174             }
00175         }
00176 
00177     }
00178 
00179 
00180  
00181   #create a new session
00182   session_set_new($usr['user_id'], $cookie_for_a_year, $stay_in_ssl);
00183 
00184   return true;
00185 }
00186 
00187 function session_checkip($oldip,$newip) 
00188 {
00189   $eoldip = explode(".",$oldip);
00190   $enewip = explode(".",$newip);
00191   
00192   # ## require same class b subnet
00193   if (($eoldip[0]!=$enewip[0])||($eoldip[1]!=$enewip[1])) 
00194     {
00195       return 0;
00196     } 
00197   else 
00198     {
00199       return 1;
00200     }
00201 }
00202 
00203 function session_issecure() 
00204 {
00205   return (getenv('HTTPS') == 'on');
00206 }
00207 
00208 
00209 function session_needsstayinssl()    
00210 {
00211   return db_result(db_query("SELECT stay_in_ssl FROM session WHERE session_hash='$GLOBALS[session_hash]'"), 0, 'stay_in_ssl');
00212 }
00213 
00214 function session_cookie($n,$v,$cookie_for_a_year=0) 
00215 {
00216   
00217   # yeupou--gnu.org 2004-09-21: this will pose problem on different servers
00218   # with the same domain; on the other hand, it's helpful for servers that
00219   # want multiple domains to be working.
00220   # In the meantime, shut it off.
00221   #
00222   # Define the domain name, only the last part of it like .domain.org
00223   # in order to permit any host of .domain.org to access it.
00224   #preg_match("/[^\.\/]+\.[^\.\/]+$/", $GLOBALS['sys_default_domain'], $domain);
00225   #$domain = ".".$domain[0];
00226   $domain = $GLOBALS['sys_default_domain'];
00227 
00228   if ($cookie_for_a_year=="1") 
00229     {
00230       # Set the cookie for a year.
00231       setcookie($n,$v, time() + 60*60*24*365 ,$GLOBALS['sys_home'],$domain,0);
00232     } 
00233   else 
00234     {
00235       setcookie($n,$v,0,$GLOBALS['sys_home'],$domain,0);
00236     }
00237 }
00238 
00239 # Removes a cookie. This is an alternative to setting it to an empty
00240 # or irrelevant value, and will just prevent the browser from sending
00241 # it again.
00242 function session_delete_cookie($n)
00243 {
00244   setcookie($n, '', 0, $GLOBALS['sys_home'], $GLOBALS['sys_default_domain'], 0);
00245 }
00246 
00247 function session_redirect($loc) 
00248 {
00249   header('Location: http' . (session_issecure()?'s':'') . '://' . (session_issecure()?$GLOBALS['sys_https_host']:$GLOBALS['sys_default_domain']).$loc);
00250   print("\n\n");
00251   exit;
00252 }
00253 
00254 function session_require_test($req) 
00255 {
00256   /* 
00257        Similiar tho session_require but only return 1 or 0
00258   */
00259   if (user_is_super_user()) 
00260     {
00261       return true;
00262     }
00263   if ($req['group']) 
00264     {
00265       $query = "SELECT user_id FROM user_group WHERE user_id=" . user_getid()
00266          . " AND group_id=$req[group]";
00267       if ($req['admin_flags']) 
00268         {
00269           $query .= " AND admin_flags = '$req[admin_flags]'";
00270         }
00271       if ((db_numrows(db_query($query)) < 1) || !$req['group']) 
00272         {
00273           return false;
00274         }
00275     
00276     }
00277   elseif ($req['user']) 
00278     {
00279       if (user_getid() != $req['user']) 
00280         {
00281           return false;
00282         }
00283     }
00284   elseif ($req['isloggedin']) 
00285     {
00286       if (!user_isloggedin()) 
00287         {
00288           return false;
00289         }
00290     } 
00291   else 
00292     {
00293       return false;
00294     }
00295   
00296 }
00297 
00298 function session_require($req) 
00299 {
00300   /*
00301                 SV admins always return true
00302   */
00303   if (user_is_super_user()) 
00304     {
00305       return true;
00306     }
00307   
00308   if ($req['group']) 
00309     {
00310       $query = "SELECT user_id FROM user_group WHERE user_id=" . user_getid()
00311          . " AND group_id=$req[group]";
00312       if ($req['admin_flags']) 
00313         {
00314           $query .= " AND admin_flags = '$req[admin_flags]'";   
00315         }
00316     
00317       if ((db_numrows(db_query($query)) < 1) || !$req['group']) 
00318         {
00319           exit_error("Insufficient Group Access","You do not have permission to "
00320                      . "view this page.");
00321         }
00322     }
00323   elseif ($req['user']) 
00324     {
00325       if (user_getid() != $req['user']) 
00326         {       
00327           exit_error("Insufficient User Access","You do not have permission to "
00328                      . "view this page.");
00329         }
00330     }
00331   elseif ($req['isloggedin']) 
00332     {
00333       if (!user_isloggedin()) 
00334         {
00335           exit_error("Required Login","In order to view this page, you must "
00336                      . "be logged in.");
00337         }
00338     } 
00339   else 
00340     {
00341       exit_error("Insufficient Access","Probably by mangling a URL, you have attempted "
00342                  . "to reach a part of the site for which you do not have access. This can "
00343                  . "probably be fixed by properly navigating through the site.");
00344     }
00345 }
00346 
00347 function session_setglobals($user_id) 
00348 {
00349   global $G_USER;
00350   
00351   #     unset($G_USER);
00352   
00353   if ($user_id > 0) 
00354     {
00355       $result=db_query("SELECT user_id,user_name FROM user WHERE user_id='$user_id'");
00356       if (!$result || db_numrows($result) < 1) 
00357         {
00358           #echo db_error();
00359           $G_USER = array();
00360         } 
00361       else 
00362         {
00363           $G_USER = db_fetch_array($result);
00364           #                     echo $G_USER['user_name'].'<BR>';
00365         }
00366     } 
00367   else 
00368     {
00369       $G_USER = array();
00370     }
00371 }
00372 
00373 function session_set_new($user_id, $cookie_for_a_year=0, $stay_in_ssl=1) 
00374 {
00375   global $G_SESSION;
00376   
00377   #     unset($G_SESSION);
00378   
00379   # concatinate current time, and random seed for MD5 hash
00380   # continue until unique hash is generated (SHOULD only be once)
00381   do {
00382     $pre_hash = time() . rand() . $GLOBALS['REMOTE_ADDR'] . microtime();
00383     $GLOBALS['session_hash'] = md5($pre_hash);
00384   } 
00385   while (db_numrows(db_query("SELECT session_hash FROM session WHERE session_hash='$GLOBALS[session_hash]'")) > 0);
00386   
00387   # set session cookies
00388   session_cookie("session_hash",$GLOBALS['session_hash'],$cookie_for_a_year);
00389   session_cookie("session_uid",$user_id,$cookie_for_a_year);
00390   
00391   # make new session entries into db
00392   db_query("INSERT INTO session (session_hash, ip_addr, time, user_id, stay_in_ssl) VALUES ('".addslashes($GLOBALS[session_hash])."','".addslashes($GLOBALS[REMOTE_ADDR])."'," . time() . ",'$user_id','$stay_in_ssl')");
00393   
00394   # set global
00395   $res=db_query("SELECT * FROM session WHERE session_hash='$GLOBALS[session_hash]'");
00396   if (db_numrows($res) > 1) 
00397     {
00398       db_query("DELETE FROM session WHERE session_hash='$GLOBALS[session_hash]'");
00399       exit_error("ERROR","ERROR - two people had the same hash - backarrow and re-login. It should never happen again");
00400     } 
00401   else 
00402     {
00403       $G_SESSION = db_fetch_array($res);
00404       session_setglobals($G_SESSION['user_id']);
00405     }
00406 
00407   # if the user specified he wants only one session to be opened at a time,
00408   # kill the others sessions
00409   if (user_get_preference("keep_only_one_session"))
00410     {
00411       db_query("DELETE FROM session WHERE session_hash<>'$GLOBALS[session_hash]' AND user_id='$user_id'");
00412     }
00413 }
00414 
00415 function session_set() 
00416 {
00417   global $G_SESSION,$G_USER;
00418   
00419   #     unset($G_SESSION);
00420   
00421   # assume bad session_hash and session. If all checks work, then allow
00422   # otherwise make new session
00423   $id_is_good = 0;
00424   
00425   # here also check for good hash, set if new session is needed
00426   $session_hash = sane_cookie("session_hash");
00427   $session_uid = sane_cookie("session_uid");
00428   if ($session_hash && $session_uid) 
00429     {
00430       $result=db_query("SELECT * FROM session WHERE session_hash='".$session_hash."' AND user_id='".$session_uid."'");
00431       $G_SESSION = db_fetch_array($result);
00432     
00433       # does hash exist?
00434       if ($G_SESSION['session_hash']) 
00435         {
00436           if (session_checkip($G_SESSION['ip_addr'],$GLOBALS['REMOTE_ADDR'])) 
00437             {
00438               $id_is_good = 1;
00439             } 
00440         } # else hash was not in database
00441     } # else (hash does not exist) or (session hash is bad)
00442   
00443   if ($id_is_good) 
00444     {
00445       session_setglobals($G_SESSION['user_id']);
00446     } 
00447   else 
00448     {
00449       unset($G_SESSION);
00450       unset($G_USER);
00451     }
00452 }
00453 
00454 function session_count ($uid) 
00455 {
00456   return db_numrows(db_query("SELECT ip_addr FROM session WHERE "
00457                              . "user_id = '".$uid."'"));
00458   
00459 }
00460 
00461 ?>

Generated on Sun Feb 26 13:23:04 2006 for Savane PHP Frontend Developer Reference by  doxygen 1.4.4