ILIAS  Release_4_0_x_branch Revision 61816
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilAuthUtils.php
Go to the documentation of this file.
1 <?php
2 /*
3  +-----------------------------------------------------------------------------+
4  | ILIAS open source |
5  +-----------------------------------------------------------------------------+
6  | Copyright (c) 1998-2006 ILIAS open source, University of Cologne |
7  | |
8  | This program is free software; you can redistribute it and/or |
9  | modify it under the terms of the GNU General Public License |
10  | as published by the Free Software Foundation; either version 2 |
11  | of the License, or (at your option) any later version. |
12  | |
13  | This program is distributed in the hope that it will be useful, |
14  | but WITHOUT ANY WARRANTY; without even the implied warranty of |
15  | MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
16  | GNU General Public License for more details. |
17  | |
18  | You should have received a copy of the GNU General Public License |
19  | along with this program; if not, write to the Free Software |
20  | Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. |
21  +-----------------------------------------------------------------------------+
22 */
23 
24 // define auth modes
25 define ("AUTH_LOCAL",1);
26 define ("AUTH_LDAP",2);
27 define ("AUTH_RADIUS",3);
28 define ("AUTH_SCRIPT",4);
29 define ("AUTH_SHIBBOLETH",5);
30 define ("AUTH_CAS",6);
31 define ("AUTH_SOAP",7);
32 // BEGIN WebDAV: Add support for HTTP authentication
33 define ("AUTH_HTTP",8);
34 // END WebDAV: Add support for HTTP authentication
35 define ("AUTH_ECS",9);
36 
37 
38 define ("AUTH_INACTIVE",18);
39 
40 define('AUTH_MULTIPLE',20);
41 
42 define('AUTH_SOAP_NO_ILIAS_USER', -100);
43 define('AUTH_LDAP_NO_ILIAS_USER',-200);
44 define('AUTH_RADIUS_NO_ILIAS_USER',-300);
45 
46 define('AUTH_MODE_INACTIVE',-1000);
47 
48 
49 // an external user cannot be found in ilias, but his email address
50 // matches one or more ILIAS users
51 define('AUTH_SOAP_NO_ILIAS_USER_BUT_EMAIL', -101);
52 define('AUTH_CAS_NO_ILIAS_USER', -90);
53 
54 include_once './Services/Authentication/classes/class.ilAuthFactory.php';
55 
56 
65 {
66 
70  function _initAuth()
71  {
72  global $ilAuth, $ilSetting, $ilDB, $ilClientIniFile,$ilBench;
73 //var_dump($_SESSION);
74  $ilBench->start('Auth','initAuth');
75 
76  // check whether settings object is available
77  if (!is_object($ilSetting))
78  {
79  die ("Fatal Error: ilAuthUtils::_initAuth called without ilSetting.");
80  }
81 
82  // check whether database object is available
83  if (!is_object($ilDB))
84  {
85  die ("Fatal Error: ilAuthUtils::_initAuth called without ilDB.");
86  }
87 
88  // check whether client ini file object is available
89  if (!is_object($ilClientIniFile))
90  {
91  die ("Fatal Error: ilAuthUtils::_initAuth called without ilClientIniFile.");
92  }
93 
94  // get default auth mode
95  //$default_auth_mode = $this->getSetting("auth_mode");
96  define ("AUTH_DEFAULT", $ilSetting->get("auth_mode") ? $ilSetting->get("auth_mode") : AUTH_LOCAL);
97 
98  // set local auth mode (1) in case database wasn't updated
99  /*if ($default_auth_mode === false)
100  {
101  $default_auth_mode = AUTH_LOCAL;
102  }*/
103 //var_dump($_SESSION);
104 
105  // determine authentication method if no session is found and username & password is posted
106  // does this if statement make any sense? we enter this block nearly everytime.
107  if (empty($_SESSION) ||
108  (!isset($_SESSION['_authsession']['registered']) ||
109  $_SESSION['_authsession']['registered'] !== true))
110  {
111  // no sesssion found
112  if ($_POST['username'] != '' and $_POST['password'] != '' or isset($_GET['ecs_hash']))
113  {
114  $user_auth_mode = ilAuthUtils::_getAuthModeOfUser($_POST['username'], $_POST['password'], $ilDB);
115 
116  if ($user_auth_mode == AUTH_CAS && $ilSetting->get("cas_allow_local"))
117  {
118  $user_auth_mode = AUTH_LOCAL;
119  }
120  if ($user_auth_mode == AUTH_SOAP && $ilSetting->get("soap_auth_allow_local"))
121  {
122  $user_auth_mode = AUTH_LOCAL;
123  }
124  if ($user_auth_mode == AUTH_SHIBBOLETH && $ilSetting->get("shib_auth_allow_local"))
125  {
126  $user_auth_mode = AUTH_LOCAL;
127  }
128  }
129  }
130 
131  // to do: other solution?
132  if (!$ilSetting->get("soap_auth_active") && $user_auth_mode == AUTH_SOAP)
133  {
134  $user_auth_mode = AUTH_LOCAL;
135  }
136 
137  if($ilSetting->get("cas_active") && $_GET['forceCASLogin'])
138  {
140  $user_auth_mode = AUTH_CAS;
141  }
142 
143  // BEGIN WebDAV: Share session between browser and WebDAV client.
144  // The realm is needed to support a common session between Auth_HTTP and Auth.
145  // It also helps us to distinguish between parallel sessions run on different clients.
146  // Common session only works if we use a common session name starting with "_authhttp".
147  // We must use the "_authttp" prefix, because it is hardcoded in the session name of
148  // class Auth_HTTP.
149  // Whenever we use Auth_HTTP, we need to explicitly switch off "sessionSharing", because
150  // it interfers with the session mechanism of the other Auth modules. If we would
151  // keep this switched on, then users could steal each others session, which would cause
152  // a major security breach.
153  // Note: The realm and sessionName used here, must be the same as in
154  // class ilBaseAuthentication. Otherwise, Soap clients won't be able to log
155  // in to ILIAS.
156  $realm = CLIENT_ID;
157  //$this->writelog('ilias.php realm='.$realm);
158  // END WebDAV: Share session between browser and WebDAV client.
159 
160 //var_dump($_SESSION);
161 //echo "1-".$ilSetting->get("soap_auth_active")."-";
162  // if soap authentication activated and soap credentials given
163  if (($ilSetting->get("soap_auth_active") && !empty($_GET["ext_uid"])
164  && !empty($_GET["soap_pw"])) || $user_auth_mode == AUTH_SOAP)
165  {
166 
167  define('AUTH_CURRENT',AUTH_SOAP);
168  }
169  // if Shibboleth is active and the user is authenticated
170  // we set auth_mode to Shibboleth
171  else if ( $ilSetting->get("shib_active")
172  && $_SERVER[$ilSetting->get("shib_login")])
173  {
174  define ("AUTH_CURRENT", AUTH_SHIBBOLETH);
175  }
176  // check CAS authentication
177  else
178  {
179  define ("AUTH_CURRENT", $user_auth_mode);
180  }
181 //var_dump($_SESSION);
182 
183  // Determine the authentication method to use
184  if (WebDAV_Authentication == 'HTTP') {
185  // Since WebDAV clients create the login form by
186  // themselves, we can not provide buttons on the form for
187  // choosing an authentication method.
188  // If the user is already logged in, we continue using
189  // the current authentication method. If the user is
190  // not logged in yet, we use the "multiple authentication"
191  // method using a predefined sequence of authentication methods.
192  $authmode = AUTH_CURRENT ? AUTH_CURRENT : AUTH_MULTIPLE;
193  }
194  else
195  {
196  $authmode = AUTH_CURRENT;
197  }
198  switch ($authmode)
199  {
200  case AUTH_LDAP:
201 
202  include_once './Services/LDAP/classes/class.ilAuthContainerLDAP.php';
204  break;
205 
206  case AUTH_RADIUS:
207 
208  include_once './Services/Radius/classes/class.ilAuthContainerRadius.php';
210  break;
211 
212  case AUTH_SHIBBOLETH:
213  // build option string for SHIB::Auth
214  $auth_params = array();
215  $auth_params['sessionName'] = "_authhttp".md5($realm);
216  $ilAuth = new ShibAuth($auth_params,true);
217  break;
218 
219  case AUTH_CAS:
220 
221  include_once './Services/CAS/classes/class.ilAuthContainerCAS.php';
223  break;
224 
225  case AUTH_SOAP:
226 
227  include_once './Services/SOAPAuth/classes/class.ilAuthContainerSOAP.php';
228  $ilAuth = ilAuthFactory::factory(new ilAuthContainerSOAP());
229  break;
230 
231  case AUTH_MULTIPLE:
232 
233  include_once './Services/Authentication/classes/class.ilAuthContainerMultiple.php';
235  break;
236 
237  case AUTH_ECS:
238  include_once './Services/WebServices/ECS/classes/class.ilAuthContainerECS.php';
240  break;
241 
242  case AUTH_INACTIVE:
243  require_once('./Services/Authentication/classes/class.ilAuthInactive.php');
244  $ilAuth = new ilAuthInactive(AUTH_MODE_INACTIVE);
245  break;
246 
247  case AUTH_LOCAL:
248  default:
249 
250  global $ilLog;
251 
252  include_once './Services/Database/classes/class.ilAuthContainerMDB2.php';
254  break;
255 
256  /*
257  // build option string for PEAR::Auth
258  $auth_params = array();
259  $auth_params['dsn'] = $ilDB->getDSN();
260  $auth_params['table'] = $ilClientIniFile->readVariable("auth", "table");
261  $auth_params['usernamecol'] = $ilClientIniFile->readVariable("auth", "usercol");
262  $auth_params['passwordcol'] = $ilClientIniFile->readVariable("auth", "passcol");
263  $auth_params['sessionName'] = "_authhttp".md5($realm);
264 
265  // We use MySQL as storage container
266  // this starts already the session, AccountId is '' _authsession is null
267  //
268  if (WebDAV_Authentication == 'HTTP')
269  {
270  // Use HTTP authentication as the frontend for WebDAV clients:
271  require_once("Auth/HTTP.php");
272  require_once 'class.ilAuthContainerMDB2.php';
273  $auth_params['sessionSharing'] = false;
274  $authContainer = new ilAuthContainerMDB2($auth_params);
275  $authContainer->setObserversEnabled(true);
276  $ilAuth = new Auth_HTTP($authContainer, $auth_params,"",false);
277  $ilAuth->setRealm($realm);
278  }
279  else
280  {
281  // Use a login form as the frontend for web browsers:
282  require_once 'class.ilAuthContainerMDB2.php';
283  $authContainer = new ilAuthContainerMDB2($auth_params);
284  $authContainer->setObserversEnabled(true);
285  $ilAuth = new Auth($authContainer, $auth_params,"",false);
286  }
287  break;
288  */
289 
290  }
291 
292  // Due to a bug in Pear Auth_HTTP, we can't use idle time
293  // with WebDAV clients. If we used it, users could never log
294  // back into ILIAS once their session idled out. :(
295  if (WebDAV_Authentication != 'HTTP') {
296  $ilAuth->setIdle($ilClientIniFile->readVariable("session","expire"), false);
297  }
298  $ilAuth->setExpire(0);
299 
300  ini_set("session.cookie_lifetime", "0");
301 //echo "-".get_class($ilAuth)."-";
302  $GLOBALS['ilAuth'] =& $ilAuth;
303 
304  $ilBench->stop('Auth','initAuth');
305  }
306 
307  function _getAuthModeOfUser($a_username,$a_password,$a_db_handler = '')
308  {
309  global $ilDB;
310 
311  if(isset($_GET['ecs_hash']))
312  {
314  return AUTH_ECS;
315  }
316  if(isset($_POST['auth_mode']))
317  {
318  return (int) $_POST['auth_mode'];
319  }
320 
321  include_once('./Services/Authentication/classes/class.ilAuthModeDetermination.php');
323 
324  if(!$det->isManualSelection() and $det->getCountActiveAuthModes() > 1)
325  {
326  return AUTH_MULTIPLE;
327  }
328 
329 
330  $db =& $ilDB;
331 
332  if ($a_db_handler != '')
333  {
334  $db =& $a_db_handler;
335  }
336 
337  // Is it really necessary to check the auth mode with password ?
338  // Changed: smeyer
339  $q = "SELECT auth_mode FROM usr_data WHERE ".
340  "login = ".$ilDB->quote($a_username);
341  //"passwd = ".$ilDB->quote(md5($a_password))."";
342 
343 
344  $r = $db->query($q);
345  $row = $r->fetchRow(DB_FETCHMODE_OBJECT);
346 //echo "+".$row->auth_mode."+";
347 
348  $auth_mode = self::_getAuthMode($row->auth_mode,$db);
349 
350  return in_array($auth_mode,self::_getActiveAuthModes()) ? $auth_mode : AUTH_INACTIVE;
351  }
352 
353  function _getAuthMode($a_auth_mode,$a_db_handler = '')
354  {
355  global $ilDB, $ilSetting;
356 
357  $db =& $ilDB;
358 
359  if ($a_db_handler != '')
360  {
361  $db =& $a_db_handler;
362  }
363 
364  switch ($a_auth_mode)
365  {
366  case "local":
367  return AUTH_LOCAL;
368  break;
369 
370  case "ldap":
371  return AUTH_LDAP;
372  break;
373 
374  case "radius":
375  return AUTH_RADIUS;
376  break;
377 
378  case "script":
379  return AUTH_SCRIPT;
380  break;
381 
382  case "shibboleth":
383  return AUTH_SHIBBOLETH;
384  break;
385 
386  case "cas":
387  return AUTH_CAS;
388  break;
389 
390  case "soap":
391  return AUTH_SOAP;
392  break;
393 
394  case 'ecs':
395  return AUTH_ECS;
396 
397  default:
398  return $ilSetting->get("auth_mode");
399  break;
400  }
401  }
402 
403  function _getAuthModeName($a_auth_key)
404  {
405  global $ilias;
406 
407  switch ($a_auth_key)
408  {
409  case AUTH_LOCAL:
410  return "local";
411  break;
412 
413  case AUTH_LDAP:
414  return "ldap";
415  break;
416 
417  case AUTH_RADIUS:
418  return "radius";
419  break;
420 
421  case AUTH_CAS:
422  return "cas";
423  break;
424 
425  case AUTH_SCRIPT:
426  return "script";
427  break;
428 
429  case AUTH_SHIBBOLETH:
430  return "shibboleth";
431  break;
432 
433  case AUTH_SOAP:
434  return "soap";
435  break;
436 
437  case AUTH_ECS:
438  return 'ecs';
439 
440  default:
441  return "default";
442  break;
443  }
444  }
445 
447  {
448  global $ilias,$ilSetting;
449 
450  $modes = array(
451  'default' => $ilSetting->get("auth_mode"),
452  'local' => AUTH_LOCAL
453  );
454  include_once('Services/LDAP/classes/class.ilLDAPServer.php');
456  {
457  $modes['ldap'] = AUTH_LDAP;
458  }
459  if ($ilSetting->get("radius_active")) $modes['radius'] = AUTH_RADIUS;
460  if ($ilSetting->get("shib_active")) $modes['shibboleth'] = AUTH_SHIBBOLETH;
461  if ($ilSetting->get("script_active")) $modes['script'] = AUTH_SCRIPT;
462  if ($ilSetting->get("cas_active")) $modes['cas'] = AUTH_CAS;
463  if ($ilSetting->get("soap_auth_active")) $modes['soap'] = AUTH_SOAP;
464 
465  include_once('./Services/WebServices/ECS/classes/class.ilECSSettings.php');
466 
467  if(ilECSSettings::_getInstance()->isEnabled())
468  {
469  $modes['ecs'] = AUTH_ECS;
470  }
471  return $modes;
472  }
473 
474  function _getAllAuthModes()
475  {
476  return array(
484  }
485 
490  function _generateLogin($a_login)
491  {
492  global $ilDB;
493 
494  // Check if username already exists
495  $found = false;
496  $postfix = 0;
497  $c_login = $a_login;
498  while(!$found)
499  {
500  $r = $ilDB->query("SELECT login FROM usr_data WHERE login = ".
501  $ilDB->quote($c_login));
502  if ($r->numRows() > 0)
503  {
504  $postfix++;
505  $c_login = $a_login.$postfix;
506  }
507  else
508  {
509  $found = true;
510  }
511  }
512 
513  return $c_login;
514  }
515 
516  public static function _hasMultipleAuthenticationMethods()
517  {
518  include_once('Services/Radius/classes/class.ilRadiusSettings.php');
519 
520  $rad_settings = ilRadiusSettings::_getInstance();
521  if($rad_settings->isActive())
522  {
523  return true;
524  }
525  include_once('Services/LDAP/classes/class.ilLDAPServer.php');
526  return count(ilLDAPServer::_getActiveServerList()) ? true : false;
527  }
528 
529  public static function _getMultipleAuthModeOptions($lng)
530  {
531  global $ilSetting;
532 
533  // in the moment only ldap is activated as additional authentication method
534  include_once('Services/LDAP/classes/class.ilLDAPServer.php');
535 
536  $options[AUTH_LOCAL]['txt'] = $lng->txt('authenticate_ilias');
537 
538  // LDAP
539  if($ldap_id = ilLDAPServer::_getFirstActiveServer())
540  {
541  $ldap_server = new ilLDAPServer($ldap_id);
542  $options[AUTH_LDAP]['txt'] = $ldap_server->getName();
543  }
544  include_once('Services/Radius/classes/class.ilRadiusSettings.php');
545  $rad_settings = ilRadiusSettings::_getInstance();
546  if($rad_settings->isActive())
547  {
548  $options[AUTH_RADIUS]['txt'] = $rad_settings->getName();
549  }
550 
551  if($ilSetting->get('auth_mode',AUTH_LOCAL) == AUTH_LDAP)
552  {
553  $default = AUTH_LDAP;
554  }
555  elseif($ilSetting->get('auth_mode',AUTH_LOCAL) == AUTH_RADIUS)
556  {
557  $default = AUTH_RADIUS;
558  }
559  else
560  {
561  $default = AUTH_LOCAL;
562  }
563 
564  $default = $ilSetting->get('default_auth_mode',$default);
565  $default = (int) $_REQUEST['auth_mode'] ? (int) $_REQUEST['auth_mode'] : $default;
566 
567  $options[$default]['checked'] = true;
568  return $options ? $options : array();
569  }
570 
580  public static function _isExternalAccountEnabled()
581  {
582  global $ilSetting;
583 
584  if($ilSetting->get("cas_active"))
585  {
586  return true;
587  }
588  if($ilSetting->get("soap_auth_active"))
589  {
590  return true;
591  }
592  if($ilSetting->get("shib_active"))
593  {
594  return true;
595  }
596  if($ilSetting->get('radius_active'))
597  {
598  return true;
599  }
600  include_once('Services/LDAP/classes/class.ilLDAPServer.php');
602  {
603  return true;
604  }
605  return false;
606  }
607 
616  public static function _allowPasswordModificationByAuthMode($a_auth_mode)
617  {
618  switch($a_auth_mode)
619  {
620  case AUTH_LDAP:
621  case AUTH_RADIUS:
622  case AUTH_ECS:
623  return false;
624  default:
625  return true;
626  }
627  }
628 
637  public static function _needsExternalAccountByAuthMode($a_auth_mode)
638  {
639  switch($a_auth_mode)
640  {
641  case AUTH_LOCAL:
642  return false;
643  default:
644  return true;
645  }
646  }
647 }
648 ?>