ILIAS  eassessment Revision 61809
 All Data Structures Namespaces Files Functions Variables Groups Pages
class.ilLDAPRoleGroupMapping.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 include_once('Services/LDAP/classes/class.ilLDAPServer.php');
25 
35 {
36  private $log = null;
37  private static $instance = null;
38  private $servers = null;
39  private $mappings = array();
40  private $mapping_members = array();
41  private $query = array();
42  private $active_servers = false;
43 
50  private function __construct()
51  {
52  global $ilLog;
53 
54  $this->log = $ilLog;
55  $this->initServers();
56  }
57 
64  public static function _getInstance()
65  {
66  if(is_object(self::$instance))
67  {
68  return self::$instance;
69  }
70  return self::$instance = new ilLDAPRoleGroupMapping();
71  }
72 
82  public function getInfoStrings($a_obj_id,$a_check_type = false)
83  {
84  if(!$this->active_servers)
85  {
86  return false;
87  }
88  if($a_check_type)
89  {
90  if(isset($this->mapping_info_strict[$a_obj_id]) and is_array($this->mapping_info_strict[$a_obj_id]))
91  {
92  return $this->mapping_info_strict[$a_obj_id];
93  }
94  }
95  else
96  {
97  if(isset($this->mapping_info[$a_obj_id]) and is_array($this->mapping_info[$a_obj_id]))
98  {
99  return $this->mapping_info[$a_obj_id];
100  }
101 
102  }
103  return false;
104  }
105 
106 
116  public function assign($a_role_id,$a_usr_id)
117  {
118  // return if there nothing to do
119  if(!$this->active_servers)
120  {
121  return false;
122  }
123 
124  if(!$this->isHandledRole($a_role_id))
125  {
126  return false;
127  }
128  if(!$this->isHandledUser($a_usr_id))
129  {
130  $this->log->write('LDAP assign: User ID: '.$a_usr_id.' has no LDAP account');
131  return false;
132  }
133  $this->log->write('LDAP assign: User ID: '.$a_usr_id.' Role Id: '.$a_role_id);
134  $this->assignToGroup($a_role_id,$a_usr_id);
135 
136  return true;
137  }
138 
148  public function deleteRole($a_role_id)
149  {
150  global $rbacreview;
151 
152  // return if there nothing to do
153  if(!$this->active_servers)
154  {
155  return false;
156  }
157 
158  if(!$this->isHandledRole($a_role_id))
159  {
160  return false;
161  }
162 
163  foreach($rbacreview->assignedUsers($a_role_id) as $usr_id)
164  {
165  $this->deassign($a_role_id,$usr_id);
166  }
167  return true;
168  }
169 
170 
180  public function deassign($a_role_id,$a_usr_id)
181  {
182  // return if there notzing to do
183  if(!$this->active_servers)
184  {
185  return false;
186  }
187  if(!$this->isHandledRole($a_role_id))
188  {
189  return false;
190  }
191  if(!$this->isHandledUser($a_usr_id))
192  {
193  return false;
194  }
195  $this->log->write('LDAP deassign: User ID: '.$a_usr_id.' Role Id: '.$a_role_id);
196  $this->deassignFromGroup($a_role_id,$a_usr_id);
197 
198  return true;
199  }
200 
207  public function deleteUser($a_usr_id)
208  {
209  foreach($this->mappings as $role_id => $data)
210  {
211  $this->deassign($role_id,$a_usr_id);
212  }
213  return true;
214  }
215 
216 
224  private function initServers()
225  {
226  $server_ids = ilLDAPServer::_getRoleSyncServerIds();
227 
228  if(!count($server_ids))
229  {
230  return false;
231  }
232 
233  // Init servers
234  include_once('Services/LDAP/classes/class.ilLDAPRoleGroupMappingSettings.php');
235 
236  $this->active_servers = true;
237  $this->mappings = array();
238  foreach($server_ids as $server_id)
239  {
240  $this->servers[$server_id] = new ilLDAPServer($server_id);
242  }
243  $this->mapping_info = array();
244  $this->mapping_info_strict = array();
245  foreach($this->mappings as $mapping)
246  {
247  foreach($mapping as $key => $data)
248  {
249  if(strlen($data['info']) and $data['object_id'])
250  {
251  $this->mapping_info[$data['object_id']][] = $data['info'];
252  }
253  if(strlen($data['info']) && ($data['info_type'] == ilLDAPRoleGroupMappingSettings::MAPPING_INFO_ALL))
254  {
255  $this->mapping_info_strict[$data['object_id']][] = $data['info'];
256  }
257  }
258  }
259  $this->users = ilObjUser::_getExternalAccountsByAuthMode('ldap',true);
260 
261  return true;
262  }
263 
272  private function isHandledRole($a_role_id)
273  {
274  return array_key_exists($a_role_id,$this->mappings);
275  }
276 
282  private function isHandledUser($a_usr_id)
283  {
284  return array_key_exists($a_usr_id,$this->users);
285  }
286 
287 
295  private function assignToGroup($a_role_id,$a_usr_id)
296  {
297  foreach($this->mappings[$a_role_id] as $data)
298  {
299  try
300  {
301  if($data['isdn'])
302  {
303  $external_account = $this->readDN($a_usr_id,$data['server_id']);
304  }
305  else
306  {
307  $external_account = $this->users[$a_usr_id];
308  }
309 
310  // Forcing modAdd since Active directory is too slow and i cannot check if a user is member or not.
311  #if($this->isMember($external_account,$data))
312  #{
313  # $this->log->write("LDAP assign: User already assigned to group '".$data['dn']."'");
314  #}
315  #else
316  {
317  // Add user
318  $query_obj = $this->getLDAPQueryInstance($data['server_id'],$data['url']);
319  $query_obj->modAdd($data['dn'],array($data['member'] => $external_account));
320  $this->log->write('LDAP assign: Assigned '.$external_account.' to group '.$data['dn']);
321  }
322  }
323  catch(ilLDAPQueryException $exc)
324  {
325  $this->log->write($exc->getMessage());
326  // try next mapping
327  continue;
328  }
329  }
330  }
331 
340  private function deassignFromGroup($a_role_id,$a_usr_id)
341  {
342  foreach($this->mappings[$a_role_id] as $data)
343  {
344  try
345  {
346  if($data['isdn'])
347  {
348  $external_account = $this->readDN($a_usr_id,$data['server_id']);
349  }
350  else
351  {
352  $external_account = $this->users[$a_usr_id];
353  }
354 
355  // Check for other role membership
356  if($role_id = $this->checkOtherMembership($a_usr_id,$a_role_id,$data))
357  {
358  $this->log->write('LDAP deassign: User is still assigned to role "'.$role_id.'".');
359  continue;
360  }
361  /*
362  if(!$this->isMember($external_account,$data))
363  {
364  $this->log->write("LDAP deassign: User not assigned to group '".$data['dn']."'");
365  continue;
366  }
367  */
368  // Deassign user
369  $query_obj = $this->getLDAPQueryInstance($data['server_id'],$data['url']);
370  $query_obj->modDelete($data['dn'],array($data['member'] => $external_account));
371  $this->log->write('LDAP deassign: Deassigned '.$external_account.' from group '.$data['dn']);
372 
373  // Delete from cache
374  if(is_array($this->mapping_members[$data['mapping_id']]))
375  {
376  $key = array_search($external_account,$this->mapping_members[$data['mapping_id']]);
377  if($key or $key === 0)
378  {
379  unset($this->mapping_members[$data['mapping_id']]);
380  }
381  }
382 
383  }
384  catch(ilLDAPQueryException $exc)
385  {
386  $this->log->write($exc->getMessage());
387  // try next mapping
388  continue;
389  }
390  }
391  }
392 
399  private function isMember($a_uid,$data)
400  {
401  if(!isset($this->mapping_members["$data[mapping_id]"]))
402  {
403  // Read members
404  try
405  {
406  $server = $this->servers["$data[server_id]"];
407  $query_obj = $this->getLDAPQueryInstance($data['server_id'],$server->getUrl());
408 
409  // query for members
410  $res = $query_obj->query($data['dn'],
411  '(objectClass=*)',
413  array($data['member']));
414 
415  $this->storeMembers($data['mapping_id'],$res->get());
416  unset($res);
417  }
418  catch(ilLDAPQueryException $exc)
419  {
420  throw $exc;
421  }
422  }
423  #var_dump("<pre>",$a_uid,$this->mapping_members,"</pre>");
424 
425  // Now check for membership in stored result
426  if(in_array($a_uid,$this->mapping_members["$data[mapping_id]"]))
427  {
428  return true;
429  }
430  return false;
431  }
432 
440  private function checkOtherMembership($a_usr_id,$a_role_id,$a_data)
441  {
442  global $rbacreview,$ilObjDataCache;
443 
444  foreach($this->mappings as $role_id => $tmp_data)
445  {
446  foreach($tmp_data as $data)
447  {
448  if($role_id == $a_role_id)
449  {
450  continue;
451  }
452  if($data['server_id'] != $a_data['server_id'])
453  {
454  continue;
455  }
456  if($data['dn'] != $a_data['dn'])
457  {
458  continue;
459  }
460  if($rbacreview->isAssigned($a_usr_id,$role_id))
461  {
462  return $ilObjDataCache->lookupTitle($role_id);
463  }
464  }
465  }
466  return false;
467 
468  }
469 
476  private function storeMembers($a_mapping_id,$a_data)
477  {
478  $this->mapping_members[$a_mapping_id] = array();
479  foreach($a_data as $field => $value)
480  {
481  if(strtolower($field) == 'dn')
482  {
483  continue;
484  }
485 
486  if(!is_array($value))
487  {
488  $this->mapping_members[$a_mapping_id][] = $value;
489  continue;
490  }
491  foreach($value as $external_account)
492  {
493  $this->mapping_members[$a_mapping_id][] = $external_account;
494  }
495  }
496  return true;
497  }
498 
507  private function readDN($a_usr_id,$a_server_id)
508  {
509  if(isset($this->user_dns[$a_usr_id]))
510  {
511  return $this->user_dns[$a_usr_id];
512  }
513 
514  $external_account = $this->users[$a_usr_id];
515 
516  try
517  {
518  $server = $this->servers[$a_server_id];
519  $query_obj = $this->getLDAPQueryInstance($a_server_id,$server->getUrl());
520 
521  if($search_base = $server->getSearchBase())
522  {
523  $search_base .= ',';
524  }
525  $search_base .= $server->getBaseDN();
526 
527  // try optional group user filter first
528  if($server->isMembershipOptional() and $server->getGroupUserFilter())
529  {
530  $userFilter = $server->getGroupUserFilter();
531  }
532  else
533  {
534  $userFilter = $server->getFilter();
535  }
536 
537  $filter = sprintf('(&(%s=%s)%s)',
538  $server->getUserAttribute(),
539  $external_account,
540  $userFilter);
541 
542  $res = $query_obj->query($search_base,$filter,$server->getUserScope(),array('dn'));
543 
544  if(!$res->numRows())
545  {
546  include_once('Services/LDAP/classes/class.ilLDAPQueryException.php');
547  throw new ilLDAPQueryException(__METHOD__.' cannot find dn for user '.$external_account);
548  }
549  if($res->numRows() > 1)
550  {
551  include_once('Services/LDAP/classes/class.ilLDAPQueryException.php');
552  throw new ilLDAPQueryException(__METHOD__.' found multiple distinguished name for: '.$external_account);
553  }
554 
555  $data = $res->get();
556  return $this->user_dns[$a_usr_id] = $data['dn'];
557  }
558  catch(ilLDAPQueryException $exc)
559  {
560  throw $exc;
561  }
562  }
563 
571  private function getLDAPQueryInstance($a_server_id,$a_url)
572  {
573  include_once 'Services/LDAP/classes/class.ilLDAPQuery.php';
574 
575  if(array_key_exists($a_server_id,$this->query) and
576  array_key_exists($a_url,$this->query[$a_server_id]) and
577  is_object($this->query[$a_server_id][$a_url]))
578  {
579  return $this->query[$a_server_id][$a_url];
580  }
581  try
582  {
583  $tmp_query = new ilLDAPQuery($this->servers[$a_server_id],$a_url);
584  $tmp_query->bind(IL_LDAP_BIND_ADMIN);
585  }
586  catch(ilLDAPQueryException $exc)
587  {
588  throw $exc;
589  }
590  return $this->query[$a_server_id][$a_url] = $tmp_query;
591  }
592 
593 }
594 
595 
596 ?>