summaryrefslogtreecommitdiff
path: root/plugins/kolab_auth
diff options
context:
space:
mode:
authorThomas Bruederli <bruederli@kolabsys.com>2014-10-11 01:14:45 (GMT)
committerThomas Bruederli <bruederli@kolabsys.com>2014-10-11 01:14:45 (GMT)
commit1e0b0cdf9d428de6d8c12e673b72cdcdb0aa79bd (patch)
treed2d362879ce8022a5d75e452d1fb9a2ade15d498 /plugins/kolab_auth
parent232b458be41440210dec1553965fddd2f6c40589 (diff)
downloadroundcubemail-plugins-kolab-1e0b0cdf9d428de6d8c12e673b72cdcdb0aa79bd.tar.gz
Check effective rights for the login-as feature to improve the delegation model
and allow controlling the administration privileges in LDAP (#1834). This deprecates the config options 'kolab_auth_group', 'kolab_auth_role_value' and 'kolab_auth_allowed_tasks'. Admin privileges (per Roundcube task) and the required effective rights are now defined in 'kolab_auth_admin_rights'.
Diffstat (limited to 'plugins/kolab_auth')
-rw-r--r--plugins/kolab_auth/config.inc.php.dist28
-rw-r--r--plugins/kolab_auth/kolab_auth.php103
-rw-r--r--plugins/kolab_auth/localization/en_US.inc1
3 files changed, 91 insertions, 41 deletions
diff --git a/plugins/kolab_auth/config.inc.php.dist b/plugins/kolab_auth/config.inc.php.dist
index 17c0915..b353d61 100644
--- a/plugins/kolab_auth/config.inc.php.dist
+++ b/plugins/kolab_auth/config.inc.php.dist
@@ -29,6 +29,9 @@ $config['kolab_auth_name'] = array('name', 'cn');
$config['kolab_auth_email'] = array('email');
$config['kolab_auth_organization'] = array('organization');
+// Role field (from fieldmap configuration)
+$config['kolab_auth_role'] = 'role';
+
// Template for user names displayed in the UI.
// You can use all attributes from the 'fieldmap' property of the 'kolab_auth_addressbook' configuration
$config['kolab_auth_user_displayname'] = '{name} ({ou})';
@@ -40,20 +43,17 @@ $config['kolab_auth_admin_password'] = '';
// Enable audit logging for abuse of administrative privileges.
$config['kolab_auth_auditlog'] = false;
-// Role field (from fieldmap configuration)
-$config['kolab_auth_role'] = 'role';
-// The required value for the role attribute to contain should the user be allowed
-// to login as another user.
-$config['kolab_auth_role_value'] = '';
-
-// Administrative group name to which user must be assigned to
-// which adds privilege to login as another user.
-$config['kolab_auth_group'] = '';
-
-// List of tasks to which admin has access when logged in as another user.
-// To limit usage to Settings only use: array('settings'). Default: array() - all tasks.
-// When defined all non-authorized requests will be redirected to first task on the list.
-$config['kolab_auth_allowed_tasks'] = array();
+// As set of rules to define the required rights on the target entry
+// which allow an admin user to login as another user (the target).
+// The effective rights value refers to either entry level attribute level rights:
+// * entry:[read|add|delete]
+// * attrib:<attribute-name>:[read|write|delete]
+$config['kolab_auth_admin_rights'] = array(
+ // Roundcube task => required effective right
+ 'settings' => 'entry:read',
+ 'mail' => 'entry:delete',
+ 'addressbook' => 'entry:delete',
+);
// Enable plugins on a role-by-role basis. In this example, the 'acl' plugin
// is enabled for people with a 'cn=professional-user,dc=mykolab,dc=ch' role.
diff --git a/plugins/kolab_auth/kolab_auth.php b/plugins/kolab_auth/kolab_auth.php
index 86f1649..31f50ad 100644
--- a/plugins/kolab_auth/kolab_auth.php
+++ b/plugins/kolab_auth/kolab_auth.php
@@ -91,12 +91,12 @@ class kolab_auth extends rcube_plugin
$rcmail = rcube::get_instance();
// Check access rights when logged in as another user
- if (!empty($_SESSION['kolab_auth_admin']) && $rcmail->task != 'login' && $rcmail->task != 'logout') {
- $tasks = $rcmail->config->get('kolab_auth_allowed_tasks');
+ if (!empty($_SESSION['kolab_auth_admin']) && $args['task'] != 'login' && $args['task'] != 'logout') {
// access to specified task is forbidden,
// redirect to the first task on the list
- if (!empty($tasks)) {
- if (!in_array($rcmail->task, (array) $tasks)) {
+ if (!empty($_SESSION['kolab_auth_allowed_tasks'])) {
+ $tasks = (array)$_SESSION['kolab_auth_allowed_tasks'];
+ if (!in_array($args['task'], $tasks)) {
header('Location: ?_task=' . array_shift($tasks));
die;
}
@@ -451,24 +451,69 @@ class kolab_auth extends rcube_plugin
return $args;
}
- // check if the original user has/belongs to administrative role/group
$isadmin = false;
- $group = $rcmail->config->get('kolab_auth_group');
- $role_dn = $rcmail->config->get('kolab_auth_role_value');
-
- // check role attribute
- if (!empty($role_attr) && !empty($role_dn) && !empty($record[$role_attr])) {
- $role_dn = $ldap->parse_vars($role_dn, $user, $host);
- if (in_array($role_dn, (array)$record[$role_attr])) {
- $isadmin = true;
+ $admin_rights = $rcmail->config->get('kolab_auth_admin_rights', array());
+
+ // @deprecated: fall-back to the old check if the original user has/belongs to administrative role/group
+ if (empty($admin_rights)) {
+ $group = $rcmail->config->get('kolab_auth_group');
+ $role_dn = $rcmail->config->get('kolab_auth_role_value');
+
+ // check role attribute
+ if (!empty($role_attr) && !empty($role_dn) && !empty($record[$role_attr])) {
+ $role_dn = $ldap->parse_vars($role_dn, $user, $host);
+ if (in_array($role_dn, (array)$record[$role_attr])) {
+ $isadmin = true;
+ }
+ }
+
+ // check group
+ if (!$isadmin && !empty($group)) {
+ $groups = $ldap->get_user_groups($record['dn'], $user, $host);
+ if (in_array($group, $groups)) {
+ $isadmin = true;
+ }
+ }
+
+ if ($isadmin) {
+ // user has admin privileges privilage, get "login as" user credentials
+ $target_entry = $ldap->get_user_record($loginas, $host);
+ $allowed_tasks = $rcmail->config->get('kolab_auth_allowed_tasks');
}
}
+ else {
+ // get "login as" user credentials
+ $target_entry = $ldap->get_user_record($loginas, $host);
+
+ if (!empty($target_entry)) {
+ // get effective rights to determine login-as permissions
+ $effective_rights = (array)$ldap->effective_rights($target_entry['dn']);
+
+ if (!empty($effective_rights)) {
+ $effective_rights['attrib'] = $effective_rights['attributeLevelRights'];
+ $effective_rights['entry'] = $effective_rights['entryLevelRights'];
+
+ // compare the rights with the permissions mapping
+ $allowed_tasks = array();
+ foreach ($admin_rights as $task => $perms) {
+ $perms_ = explode(':', $perms);
+ $type = array_shift($perms_);
+ $req = array_pop($perms_);
+ $attrib = array_pop($perms_);
+
+ if (array_key_exists($type, $effective_rights)) {
+ if ($type == 'entry' && in_array($req, $effective_rights[$type])) {
+ $allowed_tasks[] = $task;
+ }
+ else if ($type == 'attrib' && array_key_exists($attrib, $effective_rights[$type]) &&
+ in_array($req, $effective_rights[$type][$attrib])) {
+ $allowed_tasks[] = $task;
+ }
+ }
+ }
- // check group
- if (!$isadmin && !empty($group)) {
- $groups = $ldap->get_user_groups($record['dn'], $user, $host);
- if (in_array($group, $groups)) {
- $isadmin = true;
+ $isadmin = !empty($allowed_tasks);
+ }
}
}
@@ -480,22 +525,22 @@ class kolab_auth extends rcube_plugin
$origname = $user;
}
- $record = null;
+ if (!$isadmin || empty($target_entry)) {
+ $this->add_texts('localization/');
- // user has the privilage, get "login as" user credentials
- if ($isadmin) {
- $record = $ldap->get_user_record($loginas, $host);
- }
-
- if (empty($record)) {
$args['abort'] = true;
+ $args['error'] = $this->gettext(array(
+ 'name' => 'loginasnotallowed',
+ 'vars' => array('user' => Q($loginas)),
+ ));
+
$message = sprintf(
'Login failure for user %s (as user %s) from %s in session %s (error %s)',
$user,
$loginas,
rcube_utils::remote_ip(),
session_id(),
- "No user record found for '" . $loginas . "'"
+ "No privileges to login as '" . $loginas . "'"
);
rcube::write_log('userlogins', $message);
@@ -503,12 +548,16 @@ class kolab_auth extends rcube_plugin
return $args;
}
+ // replace $record with target entry
+ $record = $target_entry;
+
$args['user'] = $this->username = $loginas;
// Mark session to use SASL proxy for IMAP authentication
$_SESSION['kolab_auth_admin'] = strtolower($origname);
$_SESSION['kolab_auth_login'] = $rcmail->encrypt($admin_login);
$_SESSION['kolab_auth_password'] = $rcmail->encrypt($admin_pass);
+ $_SESSION['kolab_auth_allowed_tasks'] = $allowed_tasks;
}
// Store UID and DN of logged user in session for use by other plugins
@@ -662,7 +711,7 @@ class kolab_auth extends rcube_plugin
public function render_page($args)
{
$rcmail = rcube::get_instance();
- $tasks = $rcmail->config->get('kolab_auth_allowed_tasks');
+ $tasks = (array)$_SESSION['kolab_auth_allowed_tasks'];
$tasks[] = 'logout';
// disable buttons in taskbar
diff --git a/plugins/kolab_auth/localization/en_US.inc b/plugins/kolab_auth/localization/en_US.inc
index 2a7b246..4882bdc 100644
--- a/plugins/kolab_auth/localization/en_US.inc
+++ b/plugins/kolab_auth/localization/en_US.inc
@@ -9,5 +9,6 @@
*/
$labels['loginas'] = 'Login As';
+$labels['loginasnotallowed'] = 'No privileges to login as $user';
?>