ILIAS  Release_4_1_x_branch Revision 61804
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilLDAPServer.php
Go to the documentation of this file.
1 <?php
2 
3 /* Copyright (c) 1998-2009 ILIAS open source, Extended GPL, see docs/LICENSE */
4 
5 define('IL_LDAP_BIND_ANONYMOUS',0);
6 define('IL_LDAP_BIND_USER',1);
7 
8 define('IL_LDAP_SCOPE_SUB',0);
9 define('IL_LDAP_SCOPE_ONE',1);
10 define('IL_LDAP_SCOPE_BASE',2);
11 
25 {
26  private static $instances = array();
27 
28  const DEBUG = false;
29  const DEFAULT_VERSION = 3;
30 
31  private $role_bind_dn = '';
32  private $role_bind_pass = '';
33  private $role_sync_active = 0;
34 
35  private $server_id = null;
36  private $fallback_urls = array();
37 
38  public function __construct($a_server_id = 0)
39  {
40  global $ilDB,$lng;
41 
42  $this->db = $ilDB;
43  $this->lng = $lng;
44  $this->server_id = $a_server_id;
45 
46  $this->read();
47  }
48 
49  public static function getInstanceByServerId($a_server_id)
50  {
51  if(isset(self::$instances[$a_server_id]))
52  {
53  return self::$instances[$a_server_id];
54  }
55  return self::$instances[$a_server_id] = new ilLDAPServer($a_server_id);
56  }
57 
62  public static function checkLDAPLib()
63  {
64  return function_exists('ldap_bind');
65  }
66 
72  public static function _getActiveServerList()
73  {
74  global $ilDB;
75 
76  $query = "SELECT server_id FROM ldap_server_settings ".
77  "WHERE active = 1 ".
78  "ORDER BY name ";
79  $res = $ilDB->query($query);
80  $server_ids = array();
81  while($row = $ilDB->fetchObject($res))
82  {
83  $server_ids[] = $row->server_id;
84  }
85  return $server_ids;
86  }
87 
93  public static function _getCronServerIds()
94  {
95  global $ilDB;
96 
97  $query = "SELECT server_id FROM ldap_server_settings ".
98  "WHERE active = 1 ".
99  "AND sync_per_cron = 1 ".
100  "ORDER BY name";
101 
102  $res = $ilDB->query($query);
103  while($row = $ilDB->fetchObject($res))
104  {
105  $server_ids[] = $row->server_id;
106  }
107  return $server_ids ? $server_ids : array();
108  }
109 
117  public static function _getRoleSyncServerIds()
118  {
119  global $ilDB;
120 
121  $query = "SELECT server_id FROM ldap_server_settings ".
122  "WHERE active = 1 ".
123  "AND role_sync_active = 1 ";
124 
125  $res = $ilDB->query($query);
126  $server_ids = array();
127  while($row = $ilDB->fetchObject($res))
128  {
129  $server_ids[] = $row->server_id;
130  }
131  return $server_ids;
132  }
133 
141  public static function _getPasswordServers()
142  {
144  }
145 
146 
152  public static function _getFirstActiveServer()
153  {
155  if(count($servers))
156  {
157  return $servers[0];
158  }
159  return 0;
160  }
161 
167  public static function _getServerList()
168  {
169  global $ilDB;
170 
171  $query = "SELECT server_id FROM ldap_server_settings ORDER BY name";
172 
173  $res = $ilDB->query($query);
174  while($row = $ilDB->fetchObject($res))
175  {
176  $server_ids[] = $row->server_id;
177  }
178  return $server_ids ? $server_ids : array();
179  }
180 
181  /*
182  * Get first server id
183  *
184  * @return integer server_id
185  */
186  public static function _getFirstServer()
187  {
188  $servers = ilLDAPServer::_getServerList();
189 
190  if(count($servers))
191  {
192  return $servers[0];
193  }
194  return 0;
195  }
196 
197  // Set/Get
198  public function getServerId()
199  {
200  return $this->server_id;
201  }
202 
203 
204  public function toggleActive($a_status)
205  {
206  $this->active = $a_status;
207  }
208  public function isActive()
209  {
210  return $this->active;
211  }
212  public function getUrl()
213  {
214  return $this->url;
215  }
216  public function setUrl($a_url)
217  {
218  $this->url_string = $a_url;
219 
220  // Maybe there are more than one url's (comma seperated).
221  $urls = explode(',',$a_url);
222 
223  $counter = 0;
224  foreach($urls as $url)
225  {
226  $url = trim($url);
227  if(!$counter++)
228  {
229  $this->url = $url;
230  }
231  else
232  {
233  $this->fallback_urls[] = $url;
234  }
235  }
236  }
237  public function getUrlString()
238  {
239  return $this->url_string;
240  }
241 
249  public function doConnectionCheck()
250  {
251  global $ilLog;
252 
253  include_once('Services/LDAP/classes/class.ilLDAPQuery.php');
254 
255  foreach(array_merge(array(0 => $this->url),$this->fallback_urls) as $url)
256  {
257  try
258  {
259  // Need to do a full bind, since openldap return valid connection links for invalid hosts
260  $query = new ilLDAPQuery($this,$url);
261  $query->bind();
262  $this->url = $url;
263  $ilLog->write(__METHOD__.': Using url: '.$url.'.');
264  return true;
265  }
266  catch(ilLDAPQueryException $exc)
267  {
268  $ilLog->write(__METHOD__.': Cannot connect to LDAP server: '.$url.'. Trying fallback...');
269  }
270  }
271  $ilLog->write(__METHOD__.': No valid LDAP server found.');
272  return false;
273  }
274 
275 
276  public function getName()
277  {
278  return $this->name;
279  }
280  public function setName($a_name)
281  {
282  $this->name = $a_name;
283  }
284  public function getVersion()
285  {
286  return $this->version ? $this->version : self::DEFAULT_VERSION;
287  }
288  public function setVersion($a_version)
289  {
290  $this->version = $a_version;
291  }
292  public function getBaseDN()
293  {
294  return $this->base_dn;
295  }
296  public function setBaseDN($a_base_dn)
297  {
298  $this->base_dn = $a_base_dn;
299  }
300  public function isActiveReferrer()
301  {
302  return $this->referrals ? true : false;
303  }
304  public function toggleReferrer($a_status)
305  {
306  $this->referrals = $a_status;
307  }
308  public function isActiveTLS()
309  {
310  return $this->tls ? true : false;
311  }
312  public function toggleTLS($a_status)
313  {
314  $this->tls = $a_status;
315  }
316  public function getBindingType()
317  {
318  return $this->binding_type;
319  }
320  public function setBindingType($a_type)
321  {
322  if($a_type == IL_LDAP_BIND_USER)
323  {
324  $this->binding_type = IL_LDAP_BIND_USER;
325  }
326  else
327  {
328  $this->binding_type = IL_LDAP_BIND_ANONYMOUS;
329  }
330  }
331  public function getBindUser()
332  {
333  return $this->bind_user;
334  }
335  public function setBindUser($a_user)
336  {
337  $this->bind_user = $a_user;
338  }
339  public function getBindPassword()
340  {
341  return $this->bind_password;
342  }
343  public function setBindPassword($a_password)
344  {
345  $this->bind_password = $a_password;
346  }
347  public function getSearchBase()
348  {
349  return $this->search_base;
350  }
351  public function setSearchBase($a_search_base)
352  {
353  $this->search_base = $a_search_base;
354  }
355  public function getUserAttribute()
356  {
357  return $this->user_attribute;
358  }
359  public function setUserAttribute($a_user_attr)
360  {
361  $this->user_attribute = $a_user_attr;
362  }
363  public function getFilter()
364  {
365  return $this->prepareFilter($this->filter);
366  }
367  public function setFilter($a_filter)
368  {
369  $this->filter = $a_filter;
370  }
371  public function getGroupDN()
372  {
373  return $this->group_dn;
374  }
375  public function setGroupDN($a_value)
376  {
377  $this->group_dn = $a_value;
378  }
379  public function getGroupFilter()
380  {
381  return $this->prepareFilter($this->group_filter);
382  }
383  public function setGroupFilter($a_value)
384  {
385  $this->group_filter = $a_value;
386  }
387  public function getGroupMember()
388  {
389  return $this->group_member;
390  }
391  public function setGroupMember($a_value)
392  {
393  $this->group_member = $a_value;
394  }
395  public function getGroupName()
396  {
397  return $this->group_name;
398  }
399  public function setGroupName($a_value)
400  {
401  $this->group_name = $a_value;
402  }
410  public function getGroupNames()
411  {
412  $names = explode(',',$this->getGroupName());
413 
414  if(!is_array($names))
415  {
416  return array();
417  }
418  foreach($names as $name)
419  {
420  $new_names[] = trim($name);
421  }
422  return $new_names;
423  }
424 
425 
426  public function getGroupAttribute()
427  {
428  return $this->group_attribute;
429  }
430  public function setGroupAttribute($a_value)
431  {
432  $this->group_attribute = $a_value;
433  }
434 
435  public function toggleMembershipOptional($a_status)
436  {
437  $this->group_optional = (bool) $a_status;
438  }
439  public function isMembershipOptional()
440  {
441  return (bool) $this->group_optional;
442  }
443  public function setGroupUserFilter($a_filter)
444  {
445  $this->group_user_filter = $a_filter;
446  }
447  public function getGroupUserFilter()
448  {
449  return $this->group_user_filter;
450  }
451 
452  public function enabledGroupMemberIsDN()
453  {
454  return (bool) $this->memberisdn;
455  }
456  public function enableGroupMemberIsDN($a_value)
457  {
458  $this->memberisdn = (bool) $a_value;
459  }
460  public function setGroupScope($a_value)
461  {
462  $this->group_scope = $a_value;
463  }
464  public function getGroupScope()
465  {
466  return $this->group_scope;
467  }
468  public function setUserScope($a_value)
469  {
470  $this->user_scope = $a_value;
471  }
472  public function getUserScope()
473  {
474  return $this->user_scope;
475  }
476  public function enabledSyncOnLogin()
477  {
478  return $this->sync_on_login;
479  }
480  public function enableSyncOnLogin($a_value)
481  {
482  $this->sync_on_login = (int) $a_value;
483  }
484  public function enabledSyncPerCron()
485  {
486  return $this->sync_per_cron;
487  }
488  public function enableSyncPerCron($a_value)
489  {
490  $this->sync_per_cron = (int) $a_value;
491  }
492  public function setGlobalRole($a_role)
493  {
494  $this->global_role = $a_role;
495  }
496  public function getRoleBindDN()
497  {
498  return $this->role_bind_dn;
499  }
500  public function setRoleBindDN($a_value)
501  {
502  $this->role_bind_dn = $a_value;
503  }
504  public function getRoleBindPassword()
505  {
506  return $this->role_bind_pass;
507  }
508  public function setRoleBindPassword($a_value)
509  {
510  $this->role_bind_pass = $a_value;
511  }
512  public function enabledRoleSynchronization()
513  {
515  }
516  public function enableRoleSynchronization($a_value)
517  {
518  $this->role_sync_active = $a_value;
519  }
520 
528  public function enableAccountMigration($a_status)
529  {
530  $this->account_migration = $a_status;
531  }
532 
539  public function isAccountMigrationEnabled()
540  {
541  return $this->account_migration ? true : false;
542  }
543 
544 
550  public function validate()
551  {
552  global $ilErr;
553 
554  $ilErr->setMessage('');
555  if(!strlen($this->getName()) ||
556  !strlen($this->getUrl()) ||
557  !strlen($this->getBaseDN()) ||
558  !strlen($this->getUserAttribute()))
559  {
560  $ilErr->setMessage($this->lng->txt('fill_out_all_required_fields'));
561  }
562 
563  if($this->getBindingType() == IL_LDAP_BIND_USER
564  && (!strlen($this->getBindUser()) || !strlen($this->getBindPassword())))
565  {
566  $ilErr->appendMessage($this->lng->txt('ldap_missing_bind_user'));
567  }
568 
569  if(($this->enabledSyncPerCron() or $this->enabledSyncOnLogin()) and !$this->global_role)
570  {
571  $ilErr->appendMessage($this->lng->txt('ldap_missing_role_assignment'));
572  }
573  if($this->getVersion() == 2 and $this->isActiveTLS())
574  {
575  $ilErr->appendMessage($this->lng->txt('ldap_tls_conflict'));
576  }
577 
578  return strlen($ilErr->getMessage()) ? false : true;
579  }
580 
581  public function create()
582  {
583  global $ilDB;
584 
585  $next_id = $ilDB->nextId('ldap_server_settings');
586 
587  $query = 'INSERT INTO ldap_server_settings (server_id,active,name,url,version,base_dn,referrals,tls,bind_type,bind_user,bind_pass,'.
588  'search_base,user_scope,user_attribute,filter,group_dn,group_scope,group_filter,group_member,group_memberisdn,group_name,'.
589  'group_attribute,group_optional,group_user_filter,sync_on_login,sync_per_cron,role_sync_active,role_bind_dn,role_bind_pass,migration) '.
590  'VALUES (%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s,%s)';
591  $res = $ilDB->queryF($query,
592  array(
593  'integer','integer','text','text','integer','text','integer','integer','integer','text','text','text','integer',
594  'text','text','text','integer','text','text','integer','text','text','integer','text','integer','integer','integer',
595  'text','text', 'integer'),
596  array(
597  $next_id,
598  $this->isActive(),
599  $this->getName(),
600  $this->getUrlString(),
601  $this->getVersion(),
602  $this->getBaseDN(),
603  $this->isActiveReferrer(),
604  $this->isActiveTLS(),
605  $this->getBindingType(),
606  $this->getBindUser(),
607  $this->getBindPassword(),
608  $this->getSearchBase(),
609  $this->getUserScope(),
610  $this->getUserAttribute(),
611  $this->getFilter(),
612  $this->getGroupDN(),
613  $this->getGroupScope(),
614  $this->getGroupFilter(),
615  $this->getGroupMember(),
616  $this->enabledGroupMemberIsDN(),
617  $this->getGroupName(),
618  $this->getGroupAttribute(),
619  $this->isMembershipOptional(),
620  $this->getGroupUserFilter(),
621  $this->enabledSyncOnLogin(),
622  $this->enabledSyncPerCron(),
624  $this->getRoleBindDN(),
625  $this->getRoleBindPassword(),
627  ));
628 
629  return $next_id;
630  }
631 
632  public function update()
633  {
634  global $ilDB;
635 
636  $query = "UPDATE ldap_server_settings SET ".
637  "active = ".$this->db->quote($this->isActive(),'integer').", ".
638  "name = ".$this->db->quote($this->getName(),'text').", ".
639  "url = ".$this->db->quote($this->getUrlString(),'text').", ".
640  "version = ".$this->db->quote($this->getVersion(),'integer').", ".
641  "base_dn = ".$this->db->quote($this->getBaseDN(),'text').", ".
642  "referrals = ".$this->db->quote($this->isActiveReferrer(),'integer').", ".
643  "tls = ".$this->db->quote($this->isActiveTLS(),'integer').", ".
644  "bind_type = ".$this->db->quote($this->getBindingType(),'integer').", ".
645  "bind_user = ".$this->db->quote($this->getBindUser(),'text').", ".
646  "bind_pass = ".$this->db->quote($this->getBindPassword(),'text').", ".
647  "search_base = ".$this->db->quote($this->getSearchBase(),'text').", ".
648  "user_scope = ".$this->db->quote($this->getUserScope(),'integer').", ".
649  "user_attribute = ".$this->db->quote($this->getUserAttribute(),'text').", ".
650  "filter = ".$this->db->quote($this->getFilter(),'text').", ".
651  "group_dn = ".$this->db->quote($this->getGroupDN(),'text').", ".
652  "group_scope = ".$this->db->quote($this->getGroupScope(),'integer').", ".
653  "group_filter = ".$this->db->quote($this->getGroupFilter(),'text').", ".
654  "group_member = ".$this->db->quote($this->getGroupMember(),'text').", ".
655  "group_memberisdn =".$this->db->quote((int) $this->enabledGroupMemberIsDN(),'integer').", ".
656  "group_name = ".$this->db->quote($this->getGroupName(),'text').", ".
657  "group_attribute = ".$this->db->quote($this->getGroupAttribute(),'text').", ".
658  "group_optional = ".$this->db->quote((int) $this->isMembershipOptional(),'integer').", ".
659  "group_user_filter = ".$this->db->quote($this->getGroupUserFilter(),'text').", ".
660  "sync_on_login = ".$this->db->quote(($this->enabledSyncOnLogin() ? 1 : 0),'integer').", ".
661  "sync_per_cron = ".$this->db->quote(($this->enabledSyncPerCron() ? 1 : 0),'integer').", ".
662  "role_sync_active = ".$this->db->quote($this->enabledRoleSynchronization(),'integer').", ".
663  "role_bind_dn = ".$this->db->quote($this->getRoleBindDN(),'text').", ".
664  "role_bind_pass = ".$this->db->quote($this->getRoleBindPassword(),'text').", ".
665  "migration = ".$this->db->quote((int)$this->isAccountMigrationEnabled(),'integer')." ".
666  "WHERE server_id = ".$this->db->quote($this->getServerId(),'integer');
667 
668  $res = $ilDB->manipulate($query);
669  return true;
670  }
671 
677  public function toPearAuthArray()
678  {
679  $options = array(
680  'url' => $this->getUrl(),
681  'version' => (int) $this->getVersion(),
682  'referrals' => (bool) $this->isActiveReferrer());
683 
684  if($this->getBindingType() == IL_LDAP_BIND_USER)
685  {
686  $options['binddn'] = $this->getBindUser();
687  $options['bindpw'] = $this->getBindPassword();
688  }
689  $options['basedn'] = $this->getBaseDN();
690  $options['start_tls'] = (bool) $this->isActiveTLS();
691  $options['userdn'] = $this->getSearchBase();
692  switch($this->getUserScope())
693  {
694  case IL_LDAP_SCOPE_ONE:
695  $options['userscope'] = 'one';
696  break;
697  default:
698  $options['userscope'] = 'sub';
699  break;
700  }
701 
702  $options['userattr'] = $this->getUserAttribute();
703  $options['userfilter'] = $this->getFilter();
704  $options['attributes'] = $this->getPearAtributeArray();
705  $options['debug'] = self::DEBUG;
706 
707  if(@include_once('Log.php'))
708  {
709  if(@include_once('Log/observer.php'))
710  {
711  $options['enableLogging'] = true;
712  }
713  }
714  switch($this->getGroupScope())
715  {
716  case IL_LDAP_SCOPE_BASE:
717  $options['groupscope'] = 'base';
718  break;
719  case IL_LDAP_SCOPE_ONE:
720  $options['groupscope'] = 'one';
721  break;
722  default:
723  $options['groupscope'] = 'sub';
724  break;
725  }
726  $options['groupdn'] = $this->getGroupDN();
727  $options['groupattr'] = $this->getGroupAttribute();
728  $options['groupfilter'] = $this->getGroupFilter();
729  $options['memberattr'] = $this->getGroupMember();
730  $options['memberisdn'] = $this->enabledGroupMemberIsDN();
731  $options['group'] = $this->getGroupName();
732 
733 
734  return $options;
735  }
736 
744  private function prepareFilter($a_filter)
745  {
746  $filter = trim($a_filter);
747 
748  if(!strlen($filter))
749  {
750  return $filter;
751  }
752 
753  if(strpos($filter,'(') !== 0)
754  {
755  $filter = ('('.$filter);
756  }
757  if(substr($filter,-1) != ')')
758  {
759  $filter = ($filter.')');
760  }
761  return $filter;
762  }
763 
771  private function getPearAtributeArray()
772  {
773  if($this->enabledSyncOnLogin())
774  {
775  include_once('Services/LDAP/classes/class.ilLDAPAttributeMapping.php');
776  include_once('Services/LDAP/classes/class.ilLDAPRoleAssignmentRules.php');
778  return array_merge(
779  array($this->getUserAttribute()),
780  $mapping->getFields(),
781  array('dn'),
783  );
784  }
785  else
786  {
787  return array($this->getUserAttribute());
788  }
789  }
790 
791 
792 
797  private function read()
798  {
799  if(!$this->server_id)
800  {
801  return true;
802  }
803  $query = "SELECT * FROM ldap_server_settings WHERE server_id = ".$this->db->quote($this->server_id)."";
804 # var_dump("<pre>",$query,"</pre>");
805 
806  $res = $this->db->query($query);
807  while($row = $res->fetchRow(DB_FETCHMODE_OBJECT))
808  {
809  $this->toggleActive($row->active);
810  $this->setName($row->name);
811  $this->setUrl($row->url);
812  $this->setVersion($row->version);
813  $this->setBaseDN($row->base_dn);
814  $this->toggleReferrer($row->referrals);
815  $this->toggleTLS($row->tls);
816  $this->setBindingType($row->bind_type);
817  $this->setBindUser($row->bind_user);
818  $this->setBindPassword($row->bind_pass);
819  $this->setSearchBase($row->search_base);
820  $this->setUserScope($row->user_scope);
821  $this->setUserAttribute($row->user_attribute);
822  $this->setFilter($row->filter);
823  $this->setGroupDN($row->group_dn);
824  $this->setGroupScope($row->group_scope);
825  $this->setGroupFilter($row->group_filter);
826  $this->setGroupMember($row->group_member);
827  $this->setGroupAttribute($row->group_attribute);
828  $this->toggleMembershipOptional($row->group_optional);
829  $this->setGroupUserFilter($row->group_user_filter);
830  $this->enableGroupMemberIsDN($row->group_memberisdn);
831  $this->setGroupName($row->group_name);
832  $this->enableSyncOnLogin($row->sync_on_login);
833  $this->enableSyncPerCron($row->sync_per_cron);
834  $this->enableRoleSynchronization($row->role_sync_active);
835  $this->setRoleBindDN($row->role_bind_dn);
836  $this->setRoleBindPassword($row->role_bind_pass);
837  $this->enableAccountMigration($row->migration);
838  }
839  }
840 }
841 ?>