ILIAS  release_5-3 Revision v5.3.23-19-g915713cf615
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  return self::$instance;
68  }
69  return self::$instance = new ilLDAPRoleGroupMapping();
70  }
71 
81  public function getInfoStrings($a_obj_id, $a_check_type = false)
82  {
83  if (!$this->active_servers) {
84  return false;
85  }
86  if ($a_check_type) {
87  if (isset($this->mapping_info_strict[$a_obj_id]) and is_array($this->mapping_info_strict[$a_obj_id])) {
88  return $this->mapping_info_strict[$a_obj_id];
89  }
90  } else {
91  if (isset($this->mapping_info[$a_obj_id]) and is_array($this->mapping_info[$a_obj_id])) {
92  return $this->mapping_info[$a_obj_id];
93  }
94  }
95  return false;
96  }
97 
98 
108  public function assign($a_role_id, $a_usr_id)
109  {
110  // return if there nothing to do
111  if (!$this->active_servers) {
112  return false;
113  }
114 
115  if (!$this->isHandledRole($a_role_id)) {
116  return false;
117  }
118  if (!$this->isHandledUser($a_usr_id)) {
119  $this->log->write('LDAP assign: User ID: ' . $a_usr_id . ' has no LDAP account');
120  return false;
121  }
122  $this->log->write('LDAP assign: User ID: ' . $a_usr_id . ' Role Id: ' . $a_role_id);
123  $this->assignToGroup($a_role_id, $a_usr_id);
124 
125  return true;
126  }
127 
137  public function deleteRole($a_role_id)
138  {
139  global $rbacreview;
140 
141  // return if there nothing to do
142  if (!$this->active_servers) {
143  return false;
144  }
145 
146  if (!$this->isHandledRole($a_role_id)) {
147  return false;
148  }
149 
150  foreach ($rbacreview->assignedUsers($a_role_id) as $usr_id) {
151  $this->deassign($a_role_id, $usr_id);
152  }
153  return true;
154  }
155 
156 
166  public function deassign($a_role_id, $a_usr_id)
167  {
168  // return if there notzing to do
169  if (!$this->active_servers) {
170  return false;
171  }
172  if (!$this->isHandledRole($a_role_id)) {
173  return false;
174  }
175  if (!$this->isHandledUser($a_usr_id)) {
176  return false;
177  }
178  $this->log->write('LDAP deassign: User ID: ' . $a_usr_id . ' Role Id: ' . $a_role_id);
179  $this->deassignFromGroup($a_role_id, $a_usr_id);
180 
181  return true;
182  }
183 
190  public function deleteUser($a_usr_id)
191  {
192  foreach ($this->mappings as $role_id => $data) {
193  $this->deassign($role_id, $a_usr_id);
194  }
195  return true;
196  }
197 
198 
206  private function initServers()
207  {
208  $server_ids = ilLDAPServer::_getRoleSyncServerIds();
209 
210  if (!count($server_ids)) {
211  return false;
212  }
213 
214  // Init servers
215  include_once('Services/LDAP/classes/class.ilLDAPRoleGroupMappingSettings.php');
216 
217  $this->active_servers = true;
218  $this->mappings = array();
219  foreach ($server_ids as $server_id) {
220  $this->servers[$server_id] = new ilLDAPServer($server_id);
222  }
223  $this->mapping_info = array();
224  $this->mapping_info_strict = array();
225  foreach ($this->mappings as $mapping) {
226  foreach ($mapping as $key => $data) {
227  if (strlen($data['info']) and $data['object_id']) {
228  $this->mapping_info[$data['object_id']][] = $data['info'];
229  }
230  if (strlen($data['info']) && ($data['info_type'] == ilLDAPRoleGroupMappingSettings::MAPPING_INFO_ALL)) {
231  $this->mapping_info_strict[$data['object_id']][] = $data['info'];
232  }
233  }
234  }
235  $this->users = ilObjUser::_getExternalAccountsByAuthMode('ldap', true);
236 
237  return true;
238  }
239 
248  private function isHandledRole($a_role_id)
249  {
250  return array_key_exists($a_role_id, $this->mappings);
251  }
252 
258  private function isHandledUser($a_usr_id)
259  {
260  return array_key_exists($a_usr_id, $this->users);
261  }
262 
263 
271  private function assignToGroup($a_role_id, $a_usr_id)
272  {
273  foreach ($this->mappings[$a_role_id] as $data) {
274  try {
275  if ($data['isdn']) {
276  $external_account = $this->readDN($a_usr_id, $data['server_id']);
277  } else {
278  $external_account = $this->users[$a_usr_id];
279  }
280 
281  // Forcing modAdd since Active directory is too slow and i cannot check if a user is member or not.
282  #if($this->isMember($external_account,$data))
283  #{
284  # $this->log->write("LDAP assign: User already assigned to group '".$data['dn']."'");
285  #}
286  #else
287  {
288  // Add user
289  $query_obj = $this->getLDAPQueryInstance($data['server_id'], $data['url']);
290  $query_obj->modAdd($data['dn'], array($data['member'] => $external_account));
291  $this->log->write('LDAP assign: Assigned ' . $external_account . ' to group ' . $data['dn']);
292  }
293  } catch (ilLDAPQueryException $exc) {
294  $this->log->write($exc->getMessage());
295  // try next mapping
296  continue;
297  }
298  }
299  }
300 
309  private function deassignFromGroup($a_role_id, $a_usr_id)
310  {
311  foreach ($this->mappings[$a_role_id] as $data) {
312  try {
313  if ($data['isdn']) {
314  $external_account = $this->readDN($a_usr_id, $data['server_id']);
315  } else {
316  $external_account = $this->users[$a_usr_id];
317  }
318 
319  // Check for other role membership
320  if ($role_id = $this->checkOtherMembership($a_usr_id, $a_role_id, $data)) {
321  $this->log->write('LDAP deassign: User is still assigned to role "' . $role_id . '".');
322  continue;
323  }
324  /*
325  if(!$this->isMember($external_account,$data))
326  {
327  $this->log->write("LDAP deassign: User not assigned to group '".$data['dn']."'");
328  continue;
329  }
330  */
331  // Deassign user
332  $query_obj = $this->getLDAPQueryInstance($data['server_id'], $data['url']);
333  $query_obj->modDelete($data['dn'], array($data['member'] => $external_account));
334  $this->log->write('LDAP deassign: Deassigned ' . $external_account . ' from group ' . $data['dn']);
335 
336  // Delete from cache
337  if (is_array($this->mapping_members[$data['mapping_id']])) {
338  $key = array_search($external_account, $this->mapping_members[$data['mapping_id']]);
339  if ($key or $key === 0) {
340  unset($this->mapping_members[$data['mapping_id']]);
341  }
342  }
343  } catch (ilLDAPQueryException $exc) {
344  $this->log->write($exc->getMessage());
345  // try next mapping
346  continue;
347  }
348  }
349  }
350 
357  private function isMember($a_uid, $data)
358  {
359  if (!isset($this->mapping_members["$data[mapping_id]"])) {
360  // Read members
361  try {
362  $server = $this->servers["$data[server_id]"];
363  $query_obj = $this->getLDAPQueryInstance($data['server_id'], $server->getUrl());
364 
365  // query for members
366  $res = $query_obj->query(
367  $data['dn'],
368  '(objectClass=*)',
370  array($data['member'])
371  );
372 
373  $this->storeMembers($data['mapping_id'], $res->get());
374  unset($res);
375  } catch (ilLDAPQueryException $exc) {
376  throw $exc;
377  }
378  }
379  #var_dump("<pre>",$a_uid,$this->mapping_members,"</pre>");
380 
381  // Now check for membership in stored result
382  if (in_array($a_uid, $this->mapping_members["$data[mapping_id]"])) {
383  return true;
384  }
385  return false;
386  }
387 
395  private function checkOtherMembership($a_usr_id, $a_role_id, $a_data)
396  {
397  global $rbacreview,$ilObjDataCache;
398 
399  foreach ($this->mappings as $role_id => $tmp_data) {
400  foreach ($tmp_data as $data) {
401  if ($role_id == $a_role_id) {
402  continue;
403  }
404  if ($data['server_id'] != $a_data['server_id']) {
405  continue;
406  }
407  if ($data['dn'] != $a_data['dn']) {
408  continue;
409  }
410  if ($rbacreview->isAssigned($a_usr_id, $role_id)) {
411  return $ilObjDataCache->lookupTitle($role_id);
412  }
413  }
414  }
415  return false;
416  }
417 
424  private function storeMembers($a_mapping_id, $a_data)
425  {
426  $this->mapping_members[$a_mapping_id] = array();
427  foreach ($a_data as $field => $value) {
428  if (strtolower($field) == 'dn') {
429  continue;
430  }
431 
432  if (!is_array($value)) {
433  $this->mapping_members[$a_mapping_id][] = $value;
434  continue;
435  }
436  foreach ($value as $external_account) {
437  $this->mapping_members[$a_mapping_id][] = $external_account;
438  }
439  }
440  return true;
441  }
442 
451  private function readDN($a_usr_id, $a_server_id)
452  {
453  if (isset($this->user_dns[$a_usr_id])) {
454  return $this->user_dns[$a_usr_id];
455  }
456 
457  $external_account = $this->users[$a_usr_id];
458 
459  try {
460  $server = $this->servers[$a_server_id];
461  $query_obj = $this->getLDAPQueryInstance($a_server_id, $server->getUrl());
462 
463  if ($search_base = $server->getSearchBase()) {
464  $search_base .= ',';
465  }
466  $search_base .= $server->getBaseDN();
467 
468  // try optional group user filter first
469  if ($server->isMembershipOptional() and $server->getGroupUserFilter()) {
470  $userFilter = $server->getGroupUserFilter();
471  } else {
472  $userFilter = $server->getFilter();
473  }
474 
475  $filter = sprintf(
476  '(&(%s=%s)%s)',
477  $server->getUserAttribute(),
478  $external_account,
479  $userFilter
480  );
481 
482  $res = $query_obj->query($search_base, $filter, $server->getUserScope(), array('dn'));
483 
484  if (!$res->numRows()) {
485  include_once('Services/LDAP/classes/class.ilLDAPQueryException.php');
486  throw new ilLDAPQueryException(__METHOD__ . ' cannot find dn for user ' . $external_account);
487  }
488  if ($res->numRows() > 1) {
489  include_once('Services/LDAP/classes/class.ilLDAPQueryException.php');
490  throw new ilLDAPQueryException(__METHOD__ . ' found multiple distinguished name for: ' . $external_account);
491  }
492 
493  $data = $res->get();
494  return $this->user_dns[$a_usr_id] = $data['dn'];
495  } catch (ilLDAPQueryException $exc) {
496  throw $exc;
497  }
498  }
499 
507  private function getLDAPQueryInstance($a_server_id, $a_url)
508  {
509  include_once 'Services/LDAP/classes/class.ilLDAPQuery.php';
510 
511  if (array_key_exists($a_server_id, $this->query) and
512  array_key_exists($a_url, $this->query[$a_server_id]) and
513  is_object($this->query[$a_server_id][$a_url])) {
514  return $this->query[$a_server_id][$a_url];
515  }
516  try {
517  $tmp_query = new ilLDAPQuery($this->servers[$a_server_id], $a_url);
518  $tmp_query->bind(IL_LDAP_BIND_ADMIN);
519  } catch (ilLDAPQueryException $exc) {
520  throw $exc;
521  }
522  return $this->query[$a_server_id][$a_url] = $tmp_query;
523  }
524 }
getLDAPQueryInstance($a_server_id, $a_url)
Get LDAPQueryInstance.
deleteRole($a_role_id)
Delete role.
initServers()
Check if there is any active server with.
checkOtherMembership($a_usr_id, $a_role_id, $a_data)
Check other membership.
static _getExternalAccountsByAuthMode($a_auth_mode, $a_read_auth_default=false)
Get list of external account by authentication method Note: If login == ext_account for two user with...
__construct()
Singleton contructor.
deassign($a_role_id, $a_usr_id)
This method is typically called from class RbacAdmin::deassignUser() It checks if there is a role map...
isHandledRole($a_role_id)
Check if a role is handled or not.
readDN($a_usr_id, $a_server_id)
Read DN of user.
static _getInstance()
Get singleton instance of this class.
assign($a_role_id, $a_usr_id)
This method is typically called from class RbacAdmin::assignUser() It checks if there is a role mappi...
foreach($_POST as $key=> $value) $res
isMember($a_uid, $data)
Check if user is member.
deleteUser($a_usr_id)
Delete user => deassign from all ldap groups.
assignToGroup($a_role_id, $a_usr_id)
Assign user to group.
storeMembers($a_mapping_id, $a_data)
Store Members.
isHandledUser($a_usr_id)
Check if user is ldap user.
const IL_LDAP_BIND_ADMIN
Create styles array
The data for the language used.
$server
Definition: getUserInfo.php:12
getInfoStrings($a_obj_id, $a_check_type=false)
Get info string for object If check info type is enabled this function will check if the info string ...
deassignFromGroup($a_role_id, $a_usr_id)
Deassign user from group.
const IL_LDAP_SCOPE_BASE
$key
Definition: croninfo.php:18
static _getRoleSyncServerIds()
Check whether there if there is an active server with option role_sync_active.