ILIAS  release_5-4 Revision v5.4.26-12-gabc799a52e6
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 {
39  private $log = null;
40  private static $instance = null;
41  private $servers = null;
42  private $mappings = array();
43  private $mapping_members = array();
44  private $query = array();
45  private $active_servers = false;
46 
50  private $users = [];
51 
58  private function __construct()
59  {
60  global $DIC;
61 
62  $this->log = $DIC->logger()->auth();
63 
64  $this->initServers();
65  }
66 
73  public static function _getInstance()
74  {
75  if (is_object(self::$instance)) {
76  return self::$instance;
77  }
78  return self::$instance = new ilLDAPRoleGroupMapping();
79  }
80 
90  public function getInfoStrings($a_obj_id, $a_check_type = false)
91  {
92  if (!$this->active_servers) {
93  return false;
94  }
95  if ($a_check_type) {
96  if (isset($this->mapping_info_strict[$a_obj_id]) and is_array($this->mapping_info_strict[$a_obj_id])) {
97  return $this->mapping_info_strict[$a_obj_id];
98  }
99  } else {
100  if (isset($this->mapping_info[$a_obj_id]) and is_array($this->mapping_info[$a_obj_id])) {
101  return $this->mapping_info[$a_obj_id];
102  }
103  }
104  return false;
105  }
106 
107 
117  public function assign($a_role_id, $a_usr_id)
118  {
119  // return if there nothing to do
120  if (!$this->active_servers) {
121  return false;
122  }
123 
124  if (!$this->isHandledRole($a_role_id)) {
125  return false;
126  }
127  if (!$this->isHandledUser($a_usr_id)) {
128  $this->log->info('LDAP assign: User ID: ' . $a_usr_id . ' has no LDAP account');
129  return false;
130  }
131  $this->log->info('LDAP assigned: User ID: ' . $a_usr_id . ' Role Id: ' . $a_role_id);
132  $this->assignToGroup($a_role_id, $a_usr_id);
133 
134  return true;
135  }
136 
146  public function deleteRole($a_role_id)
147  {
148  global $DIC;
149 
150  $rbacreview = $DIC['rbacreview'];
151 
152  // return if there nothing to do
153  if (!$this->active_servers) {
154  return false;
155  }
156 
157  if (!$this->isHandledRole($a_role_id)) {
158  return false;
159  }
160 
161  foreach ($rbacreview->assignedUsers($a_role_id) as $usr_id) {
162  $this->deassign($a_role_id, $usr_id);
163  }
164  return true;
165  }
166 
167 
177  public function deassign($a_role_id, $a_usr_id)
178  {
179  // return if there notzing to do
180  if (!$this->active_servers) {
181  return false;
182  }
183  if (!$this->isHandledRole($a_role_id)) {
184  return false;
185  }
186  if (!$this->isHandledUser($a_usr_id)) {
187  return false;
188  }
189  $this->log->info('LDAP deassigned: User ID: ' . $a_usr_id . ' Role Id: ' . $a_role_id);
190  $this->deassignFromGroup($a_role_id, $a_usr_id);
191 
192  return true;
193  }
194 
201  public function deleteUser($a_usr_id)
202  {
203  foreach ($this->mappings as $role_id => $data) {
204  $this->deassign($role_id, $a_usr_id);
205  }
206  return true;
207  }
208 
209 
217  private function initServers()
218  {
219  $server_ids = ilLDAPServer::_getRoleSyncServerIds();
220 
221  if (!count($server_ids)) {
222  return false;
223  }
224 
225  // Init servers
226  include_once('Services/LDAP/classes/class.ilLDAPRoleGroupMappingSettings.php');
227 
228  $this->active_servers = true;
229  $this->mappings = array();
230  $this->users = [];
231  foreach ($server_ids as $server_id) {
232  $this->servers[$server_id] = new ilLDAPServer($server_id);
234  $this->users[$server_id] = ilObjUser::_getExternalAccountsByAuthMode(
235  'ldap_' . $server_id,
236  true
237  );
238  }
239  $this->mapping_info = array();
240  $this->mapping_info_strict = array();
241  foreach ($this->mappings as $mapping) {
242  foreach ($mapping as $key => $data) {
243  if (strlen($data['info']) and $data['object_id']) {
244  $this->mapping_info[$data['object_id']][] = $data['info'];
245  }
246  if (strlen($data['info']) && ($data['info_type'] == ilLDAPRoleGroupMappingSettings::MAPPING_INFO_ALL)) {
247  $this->mapping_info_strict[$data['object_id']][] = $data['info'];
248  }
249  }
250  }
251  return true;
252  }
253 
262  private function isHandledRole($a_role_id)
263  {
264  return array_key_exists($a_role_id, $this->mappings);
265  }
266 
272  private function isHandledUser($a_usr_id)
273  {
274  foreach ($this->users as $server_id => $users) {
275  if (array_key_exists($a_usr_id, $users)) {
276  return true;
277  }
278  }
279  return false;
280  }
281 
282 
290  private function assignToGroup($a_role_id, $a_usr_id)
291  {
292  foreach ($this->mappings[$a_role_id] as $data) {
293  try {
294  if ($data['isdn']) {
295  $external_account = $this->readDN($a_usr_id, $data['server_id']);
296  } else {
297  $external_account = $this->users[$data['server_id']][$a_usr_id];
298  }
299  // Forcing modAdd since Active directory is too slow and i cannot check if a user is member or not.
300  $query_obj = $this->getLDAPQueryInstance($data['server_id'], $data['url']);
301  $query_obj->modAdd($data['dn'], array($data['member'] => $external_account));
302  $this->log->info('LDAP assign: Assigned ' . $external_account . ' to group ' . $data['dn']);
303  } catch (ilLDAPQueryException $exc) {
304  $this->log->warning($exc->getMessage());
305  // try next mapping
306  continue;
307  }
308  }
309  }
310 
319  private function deassignFromGroup($a_role_id, $a_usr_id)
320  {
321  foreach ($this->mappings[$a_role_id] as $data) {
322  try {
323  if ($data['isdn']) {
324  $external_account = $this->readDN($a_usr_id, $data['server_id']);
325  } else {
326  $external_account = $this->users[$data['server_id']][$a_usr_id];
327  }
328 
329  // Check for other role membership
330  if ($role_id = $this->checkOtherMembership($a_usr_id, $a_role_id, $data)) {
331  $this->log->info('LDAP deassign: User is still assigned to role "' . $role_id . '".');
332  continue;
333  }
334  // Deassign user
335  $query_obj = $this->getLDAPQueryInstance($data['server_id'], $data['url']);
336  $query_obj->modDelete($data['dn'], array($data['member'] => $external_account));
337  $this->log->info('LDAP deassign: Deassigned ' . $external_account . ' from group ' . $data['dn']);
338 
339  // Delete from cache
340  if (is_array($this->mapping_members[$data['mapping_id']])) {
341  $key = array_search($external_account, $this->mapping_members[$data['mapping_id']]);
342  if ($key or $key === 0) {
343  unset($this->mapping_members[$data['mapping_id']]);
344  }
345  }
346  } catch (ilLDAPQueryException $exc) {
347  $this->log->warning($exc->getMessage());
348  // try next mapping
349  continue;
350  }
351  }
352  }
353 
354 
362  private function checkOtherMembership($a_usr_id, $a_role_id, $a_data)
363  {
364  global $DIC;
365 
366  $rbacreview = $DIC['rbacreview'];
367  $ilObjDataCache = $DIC['ilObjDataCache'];
368 
369  foreach ($this->mappings as $role_id => $tmp_data) {
370  foreach ($tmp_data as $data) {
371  if ($role_id == $a_role_id) {
372  continue;
373  }
374  if ($data['server_id'] != $a_data['server_id']) {
375  continue;
376  }
377  if ($data['dn'] != $a_data['dn']) {
378  continue;
379  }
380  if ($rbacreview->isAssigned($a_usr_id, $role_id)) {
381  return $ilObjDataCache->lookupTitle($role_id);
382  }
383  }
384  }
385  return false;
386  }
387 
394  private function storeMembers($a_mapping_id, $a_data)
395  {
396  $this->mapping_members[$a_mapping_id] = array();
397  foreach ($a_data as $field => $value) {
398  if (strtolower($field) == 'dn') {
399  continue;
400  }
401 
402  if (!is_array($value)) {
403  $this->mapping_members[$a_mapping_id][] = $value;
404  continue;
405  }
406  foreach ($value as $external_account) {
407  $this->mapping_members[$a_mapping_id][] = $external_account;
408  }
409  }
410  return true;
411  }
412 
421  private function readDN($a_usr_id, $a_server_id)
422  {
423  if (isset($this->user_dns[$a_usr_id])) {
424  return $this->user_dns[$a_usr_id];
425  }
426 
427  $external_account = $this->users[$a_server_id][$a_usr_id];
428 
429  try {
430  $server = $this->servers[$a_server_id];
431  $query_obj = $this->getLDAPQueryInstance($a_server_id, $server->getUrl());
432 
433  if ($search_base = $server->getSearchBase()) {
434  $search_base .= ',';
435  }
436  $search_base .= $server->getBaseDN();
437 
438  // try optional group user filter first
439  if ($server->isMembershipOptional() and $server->getGroupUserFilter()) {
440  $userFilter = $server->getGroupUserFilter();
441  } else {
442  $userFilter = $server->getFilter();
443  }
444 
445  $filter = sprintf(
446  '(&(%s=%s)%s)',
447  $server->getUserAttribute(),
448  $external_account,
449  $userFilter
450  );
451 
452  $res = $query_obj->query($search_base, $filter, $server->getUserScope(), array('dn'));
453 
454  if (!$res->numRows()) {
455  include_once('Services/LDAP/classes/class.ilLDAPQueryException.php');
456  throw new ilLDAPQueryException(__METHOD__ . ' cannot find dn for user ' . $external_account);
457  }
458  if ($res->numRows() > 1) {
459  include_once('Services/LDAP/classes/class.ilLDAPQueryException.php');
460  throw new ilLDAPQueryException(__METHOD__ . ' found multiple distinguished name for: ' . $external_account);
461  }
462 
463  $data = $res->get();
464  return $this->user_dns[$a_usr_id] = $data['dn'];
465  } catch (ilLDAPQueryException $exc) {
466  throw $exc;
467  }
468  }
469 
477  private function getLDAPQueryInstance($a_server_id, $a_url)
478  {
479  include_once 'Services/LDAP/classes/class.ilLDAPQuery.php';
480 
481  if (array_key_exists($a_server_id, $this->query) and
482  array_key_exists($a_url, $this->query[$a_server_id]) and
483  is_object($this->query[$a_server_id][$a_url])) {
484  return $this->query[$a_server_id][$a_url];
485  }
486  try {
487  $tmp_query = new ilLDAPQuery($this->servers[$a_server_id], $a_url);
488  $tmp_query->bind(IL_LDAP_BIND_ADMIN);
489  } catch (ilLDAPQueryException $exc) {
490  throw $exc;
491  }
492  return $this->query[$a_server_id][$a_url] = $tmp_query;
493  }
494 }
getLDAPQueryInstance($a_server_id, $a_url)
Get LDAPQueryInstance.
deleteRole($a_role_id)
Delete role.
initServers()
Check if there is any active server with.
global $DIC
Definition: saml.php:7
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.
$server
Definition: sabredav.php:48
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
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
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.
$key
Definition: croninfo.php:18
static _getRoleSyncServerIds()
Check whether there if there is an active server with option role_sync_active.
$data
Definition: bench.php:6